aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Chalko <nchalko@google.com>2016-02-26 13:38:57 -0800
committerNick Chalko <nchalko@google.com>2016-02-26 13:39:22 -0800
commitba5845f23b8fbc985890f892961abc8b39886611 (patch)
treeda373b9fe1955a2c7008c2e65df5ec3f5b087454
parent1abddd9f6225298066094e20a6c29061b6af4590 (diff)
downloadTV-ba5845f23b8fbc985890f892961abc8b39886611.tar.gz
Sync to ub-tv-interns at cc7c29d2a24a1343498f6d95ca5a79e003e6aefe
Change-Id: I580da190231e47c65b69f425b30ec4685eb50ce4
-rw-r--r--Android.mk13
-rw-r--r--AndroidManifest.xml12
-rw-r--r--common/Android.mk11
-rw-r--r--common/buildconfig.mk (renamed from buildconfig.mk)0
-rw-r--r--common/res/drawable/setup_selector_background.xml17
-rw-r--r--common/res/layout/activity_setup.xml (renamed from common/res/layout/activity_stepped_setup.xml)0
-rw-r--r--common/res/layout/fragment_setup_multi_pane.xml11
-rw-r--r--common/res/values-af/strings.xml21
-rw-r--r--common/res/values-am/strings.xml21
-rw-r--r--common/res/values-ar/strings.xml21
-rw-r--r--common/res/values-az-rAZ/strings.xml21
-rw-r--r--common/res/values-bg/strings.xml21
-rw-r--r--common/res/values-bn-rBD/strings.xml21
-rw-r--r--common/res/values-ca/strings.xml21
-rw-r--r--common/res/values-cs/strings.xml21
-rw-r--r--common/res/values-da/strings.xml21
-rw-r--r--common/res/values-de/strings.xml21
-rw-r--r--common/res/values-el/strings.xml21
-rw-r--r--common/res/values-en-rAU/strings.xml21
-rw-r--r--common/res/values-en-rGB/strings.xml21
-rw-r--r--common/res/values-en-rIN/strings.xml21
-rw-r--r--common/res/values-es-rUS/strings.xml21
-rw-r--r--common/res/values-es/strings.xml21
-rw-r--r--common/res/values-et-rEE/strings.xml21
-rw-r--r--common/res/values-eu-rES/strings.xml21
-rw-r--r--common/res/values-fa/strings.xml21
-rw-r--r--common/res/values-fi/strings.xml21
-rw-r--r--common/res/values-fr-rCA/strings.xml21
-rw-r--r--common/res/values-fr/strings.xml21
-rw-r--r--common/res/values-gl-rES/strings.xml21
-rw-r--r--common/res/values-hi/strings.xml21
-rw-r--r--common/res/values-hr/strings.xml21
-rw-r--r--common/res/values-hu/strings.xml21
-rw-r--r--common/res/values-hy-rAM/strings.xml21
-rw-r--r--common/res/values-in/strings.xml21
-rw-r--r--common/res/values-is-rIS/strings.xml21
-rw-r--r--common/res/values-it/strings.xml21
-rw-r--r--common/res/values-iw/strings.xml21
-rw-r--r--common/res/values-ja/strings.xml21
-rw-r--r--common/res/values-ka-rGE/strings.xml21
-rw-r--r--common/res/values-kk-rKZ/strings.xml21
-rw-r--r--common/res/values-km-rKH/strings.xml21
-rw-r--r--common/res/values-kn-rIN/strings.xml21
-rw-r--r--common/res/values-ko/strings.xml21
-rw-r--r--common/res/values-ky-rKG/strings.xml21
-rw-r--r--common/res/values-lo-rLA/strings.xml21
-rw-r--r--common/res/values-lt/strings.xml21
-rw-r--r--common/res/values-lv/strings.xml21
-rw-r--r--common/res/values-mk-rMK/strings.xml21
-rw-r--r--common/res/values-ml-rIN/strings.xml21
-rw-r--r--common/res/values-mn-rMN/strings.xml21
-rw-r--r--common/res/values-mr-rIN/strings.xml21
-rw-r--r--common/res/values-ms-rMY/strings.xml21
-rw-r--r--common/res/values-my-rMM/strings.xml21
-rw-r--r--common/res/values-nb/strings.xml21
-rw-r--r--common/res/values-ne-rNP/strings.xml21
-rw-r--r--common/res/values-nl/strings.xml21
-rw-r--r--common/res/values-pl/strings.xml21
-rw-r--r--common/res/values-pt-rPT/strings.xml21
-rw-r--r--common/res/values-pt/strings.xml21
-rw-r--r--common/res/values-ro/strings.xml21
-rw-r--r--common/res/values-ru/strings.xml21
-rw-r--r--common/res/values-si-rLK/strings.xml21
-rw-r--r--common/res/values-sk/strings.xml21
-rw-r--r--common/res/values-sl/strings.xml21
-rw-r--r--common/res/values-sr/strings.xml21
-rw-r--r--common/res/values-sv/strings.xml21
-rw-r--r--common/res/values-sw/strings.xml21
-rw-r--r--common/res/values-ta-rIN/strings.xml21
-rw-r--r--common/res/values-te-rIN/strings.xml21
-rw-r--r--common/res/values-th/strings.xml21
-rw-r--r--common/res/values-tl/strings.xml21
-rw-r--r--common/res/values-tr/strings.xml21
-rw-r--r--common/res/values-uk/strings.xml21
-rw-r--r--common/res/values-ur-rPK/strings.xml21
-rw-r--r--common/res/values-uz-rUZ/strings.xml21
-rw-r--r--common/res/values-vi/strings.xml21
-rw-r--r--common/res/values-zh-rCN/strings.xml21
-rw-r--r--common/res/values-zh-rHK/strings.xml21
-rw-r--r--common/res/values-zh-rTW/strings.xml21
-rw-r--r--common/res/values-zu/strings.xml21
-rw-r--r--common/res/values/attrs.xml25
-rw-r--r--common/res/values/colors.xml1
-rw-r--r--common/res/values/dimens.xml7
-rw-r--r--common/res/values/strings.xml3
-rw-r--r--common/res/values/styles.xml37
-rw-r--r--common/res/values/themes.xml16
-rw-r--r--common/res_leanback/animator/lb_onboarding_description_enter.xml (renamed from res/animator/onboarding_welcome_description_enter.xml)0
-rw-r--r--common/res_leanback/animator/lb_onboarding_logo_enter.xml (renamed from res/animator/onboarding_welcome_logo_enter.xml)0
-rw-r--r--common/res_leanback/animator/lb_onboarding_logo_exit.xml (renamed from res/animator/onboarding_welcome_logo_exit.xml)2
-rw-r--r--common/res_leanback/animator/lb_onboarding_page_indicator_enter.xml (renamed from res/animator/onboarding_welcome_page_indicator_enter.xml)0
-rw-r--r--common/res_leanback/animator/lb_onboarding_page_indicator_fade_in.xml25
-rw-r--r--common/res_leanback/animator/lb_onboarding_page_indicator_fade_out.xml25
-rw-r--r--common/res_leanback/animator/lb_onboarding_start_button_fade_in.xml31
-rw-r--r--common/res_leanback/animator/lb_onboarding_start_button_fade_out.xml31
-rw-r--r--common/res_leanback/animator/lb_onboarding_title_enter.xml (renamed from res/animator/onboarding_welcome_title_enter.xml)0
-rw-r--r--common/res_leanback/animator/lb_page_indicator_dot_hide.xml37
-rw-r--r--common/res_leanback/animator/lb_page_indicator_dot_show.xml37
-rw-r--r--common/res_leanback/drawable-xhdpi/lb_ic_nav_arrow.png (renamed from res/drawable-xhdpi/ic_nav_arrow.png)bin354 -> 354 bytes
-rw-r--r--common/res_leanback/drawable/lb_onboarding_start_button_background.xml (renamed from res/values-ldrtl/integers.xml)13
-rw-r--r--common/res_leanback/layout/lb_onboarding_fragment.xml120
-rw-r--r--common/res_leanback/values-af/strings.xml22
-rw-r--r--common/res_leanback/values-am/strings.xml22
-rw-r--r--common/res_leanback/values-ar/strings.xml22
-rw-r--r--common/res_leanback/values-az-rAZ/strings.xml22
-rw-r--r--common/res_leanback/values-bg/strings.xml22
-rw-r--r--common/res_leanback/values-bn-rBD/strings.xml22
-rw-r--r--common/res_leanback/values-ca/strings.xml22
-rw-r--r--common/res_leanback/values-cs/strings.xml22
-rw-r--r--common/res_leanback/values-da/strings.xml22
-rw-r--r--common/res_leanback/values-de/strings.xml22
-rw-r--r--common/res_leanback/values-el/strings.xml22
-rw-r--r--common/res_leanback/values-en-rAU/strings.xml22
-rw-r--r--common/res_leanback/values-en-rGB/strings.xml22
-rw-r--r--common/res_leanback/values-en-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-es-rUS/strings.xml22
-rw-r--r--common/res_leanback/values-es/strings.xml22
-rw-r--r--common/res_leanback/values-et-rEE/strings.xml22
-rw-r--r--common/res_leanback/values-eu-rES/strings.xml22
-rw-r--r--common/res_leanback/values-fa/strings.xml22
-rw-r--r--common/res_leanback/values-fi/strings.xml22
-rw-r--r--common/res_leanback/values-fr-rCA/strings.xml22
-rw-r--r--common/res_leanback/values-fr/strings.xml22
-rw-r--r--common/res_leanback/values-gl-rES/strings.xml22
-rw-r--r--common/res_leanback/values-hi/strings.xml22
-rw-r--r--common/res_leanback/values-hr/strings.xml22
-rw-r--r--common/res_leanback/values-hu/strings.xml22
-rw-r--r--common/res_leanback/values-hy-rAM/strings.xml22
-rw-r--r--common/res_leanback/values-in/strings.xml22
-rw-r--r--common/res_leanback/values-is-rIS/strings.xml22
-rw-r--r--common/res_leanback/values-it/strings.xml22
-rw-r--r--common/res_leanback/values-iw/strings.xml22
-rw-r--r--common/res_leanback/values-ja/strings.xml22
-rw-r--r--common/res_leanback/values-ka-rGE/strings.xml22
-rw-r--r--common/res_leanback/values-kk-rKZ/strings.xml22
-rw-r--r--common/res_leanback/values-km-rKH/strings.xml22
-rw-r--r--common/res_leanback/values-kn-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-ko/strings.xml22
-rw-r--r--common/res_leanback/values-ky-rKG/strings.xml22
-rw-r--r--common/res_leanback/values-lo-rLA/strings.xml22
-rw-r--r--common/res_leanback/values-lt/strings.xml22
-rw-r--r--common/res_leanback/values-lv/strings.xml22
-rw-r--r--common/res_leanback/values-mk-rMK/strings.xml22
-rw-r--r--common/res_leanback/values-ml-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-mn-rMN/strings.xml22
-rw-r--r--common/res_leanback/values-mr-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-ms-rMY/strings.xml22
-rw-r--r--common/res_leanback/values-my-rMM/strings.xml22
-rw-r--r--common/res_leanback/values-nb/strings.xml22
-rw-r--r--common/res_leanback/values-ne-rNP/strings.xml22
-rw-r--r--common/res_leanback/values-nl/strings.xml22
-rw-r--r--common/res_leanback/values-pl/strings.xml22
-rw-r--r--common/res_leanback/values-pt-rPT/strings.xml22
-rw-r--r--common/res_leanback/values-pt/strings.xml22
-rw-r--r--common/res_leanback/values-ro/strings.xml22
-rw-r--r--common/res_leanback/values-ru/strings.xml22
-rw-r--r--common/res_leanback/values-si-rLK/strings.xml22
-rw-r--r--common/res_leanback/values-sk/strings.xml22
-rw-r--r--common/res_leanback/values-sl/strings.xml22
-rw-r--r--common/res_leanback/values-sr/strings.xml22
-rw-r--r--common/res_leanback/values-sv/strings.xml22
-rw-r--r--common/res_leanback/values-sw/strings.xml22
-rw-r--r--common/res_leanback/values-ta-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-te-rIN/strings.xml22
-rw-r--r--common/res_leanback/values-th/strings.xml22
-rw-r--r--common/res_leanback/values-tl/strings.xml22
-rw-r--r--common/res_leanback/values-tr/strings.xml22
-rw-r--r--common/res_leanback/values-uk/strings.xml22
-rw-r--r--common/res_leanback/values-ur-rPK/strings.xml22
-rw-r--r--common/res_leanback/values-uz-rUZ/strings.xml22
-rw-r--r--common/res_leanback/values-vi/strings.xml22
-rw-r--r--common/res_leanback/values-zh-rCN/strings.xml22
-rw-r--r--common/res_leanback/values-zh-rHK/strings.xml22
-rw-r--r--common/res_leanback/values-zh-rTW/strings.xml22
-rw-r--r--common/res_leanback/values-zu/strings.xml22
-rw-r--r--common/res_leanback/values/colors.xml23
-rw-r--r--common/res_leanback/values/dimens.xml39
-rw-r--r--common/res_leanback/values/strings.xml25
-rw-r--r--common/src/com/android/tv/common/AutoCloseableUtils.java36
-rw-r--r--common/src/com/android/tv/common/CollectionUtils.java78
-rw-r--r--common/src/com/android/tv/common/MemoryManageable.java (renamed from src/com/android/tv/util/MemoryManageable.java)2
-rw-r--r--common/src/com/android/tv/common/SharedPreferencesUtils.java64
-rw-r--r--common/src/com/android/tv/common/TvCommonConstants.java5
-rw-r--r--common/src/com/android/tv/common/TvContentRatingCache.java145
-rw-r--r--common/src/com/android/tv/common/annotation/UsedByReflection.java29
-rw-r--r--common/src/com/android/tv/common/dvr/DvrSessionClient.java149
-rw-r--r--common/src/com/android/tv/common/dvr/DvrTvView.java67
-rw-r--r--common/src/com/android/tv/common/feature/CommonFeatures.java40
-rw-r--r--common/src/com/android/tv/common/feature/EngOnlyFeature.java (renamed from src/com/android/tv/util/EngOnlyFeature.java)7
-rw-r--r--common/src/com/android/tv/common/feature/PackageVersionFeature.java55
-rw-r--r--common/src/com/android/tv/common/feature/Sdk.java42
-rw-r--r--common/src/com/android/tv/common/feature/SharedPreferencesFeature.java9
-rw-r--r--common/src/com/android/tv/common/feature/TestableFeature.java21
-rw-r--r--common/src/com/android/tv/common/recording/PlaybackTvView.java191
-rw-r--r--common/src/com/android/tv/common/recording/RecordingCapability.java181
-rw-r--r--common/src/com/android/tv/common/recording/RecordingTvInputService.java (renamed from common/src/com/android/tv/common/dvr/DvrTvInputService.java)149
-rw-r--r--common/src/com/android/tv/common/recording/RecordingUtils.java (renamed from common/src/com/android/tv/common/dvr/DvrUtils.java)27
-rw-r--r--common/src/com/android/tv/common/recording/TvRecording.java384
-rw-r--r--common/src/com/android/tv/common/ui/setup/OnActionClickListener.java3
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupActionHelper.java45
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupActivity.java168
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupFragment.java150
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java49
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java17
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupStep.java75
-rw-r--r--common/src/com/android/tv/common/ui/setup/SteppedSetupActivity.java148
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/CustomTransition.java54
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/CustomTransitionProvider.java43
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java126
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java71
-rw-r--r--common/src/com/android/tv/common/ui/setup/leanback/OnboardingFragment.java531
-rw-r--r--common/src/com/android/tv/common/ui/setup/leanback/PagingIndicator.java377
-rw-r--r--proguard.flags8
-rw-r--r--res/drawable-xhdpi/ic_playstore.pngbin0 -> 2431 bytes
-rw-r--r--res/drawable-xhdpi/ic_settings.pngbin0 -> 763 bytes
-rw-r--r--res/drawable-xhdpi/ic_store.pngbin0 -> 16294 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvoption_about.pngbin932 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvoption_parental.pngbin751 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_100.pngbin16514 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_101.pngbin16945 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_102.pngbin17341 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_103.pngbin17492 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_104.pngbin17686 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_105.pngbin18036 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_106.pngbin19931 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_107.pngbin19860 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_108.pngbin19748 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_109.pngbin19118 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_110.pngbin15014 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_111.pngbin15038 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_112.pngbin15166 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_113.pngbin15668 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_114.pngbin16269 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_115.pngbin16562 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_116.pngbin16812 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_117.pngbin16806 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_118.pngbin16860 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_119.pngbin16947 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_120.pngbin15632 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_121.pngbin15895 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_122.pngbin16091 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_123.pngbin16181 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_124.pngbin16429 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_125.pngbin16564 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_126.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_127.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_128.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_129.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_130.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_131.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_132.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_133.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_134.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_135.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_136.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_137.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_138.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_139.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_140.pngbin14773 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_141.pngbin18295 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_142.pngbin19167 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_143.pngbin19507 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_144.pngbin19908 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_145.pngbin20101 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_146.pngbin20251 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_147.pngbin20336 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_148.pngbin20385 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_149.pngbin20227 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_15.pngbin943 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_150.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_151.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_152.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_153.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_154.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_155.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_156.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_157.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_158.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_159.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_16.pngbin1158 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_160.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_161.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_162.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_163.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_164.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_165.pngbin18670 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_166.pngbin20626 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_167.pngbin20626 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_168.pngbin20378 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_169.pngbin19841 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_17.pngbin1595 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_170.pngbin15443 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_171.pngbin15566 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_172.pngbin15750 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_173.pngbin15999 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_174.pngbin16304 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_175.pngbin16574 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_176.pngbin16808 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_177.pngbin17016 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_178.pngbin17382 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_179.pngbin17891 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_18.pngbin1821 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_180.pngbin16232 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_181.pngbin16574 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_182.pngbin17015 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_183.pngbin17036 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_184.pngbin17160 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_185.pngbin17191 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_186.pngbin15661 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_187.pngbin15841 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_188.pngbin15742 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_189.pngbin15759 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_19.pngbin2047 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_190.pngbin15476 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_191.pngbin15166 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_192.pngbin15118 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_193.pngbin15179 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_194.pngbin15142 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_195.pngbin14748 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_196.pngbin14036 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_197.pngbin13750 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_198.pngbin13370 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_199.pngbin13160 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_20.pngbin2231 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_200.pngbin13075 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_201.pngbin14032 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_202.pngbin14277 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_203.pngbin14497 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_204.pngbin14502 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_205.pngbin14190 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_206.pngbin13917 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_207.pngbin13541 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_208.pngbin13138 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_209.pngbin12282 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_21.pngbin2365 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_210.pngbin9796 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_211.pngbin9249 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_212.pngbin8387 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_213.pngbin7710 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_214.pngbin7098 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_215.pngbin6469 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_216.pngbin6302 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_217.pngbin5841 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_218.pngbin5451 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_219.pngbin5129 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_22.pngbin2471 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_220.pngbin4823 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_221.pngbin4623 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_222.pngbin4427 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_223.pngbin4094 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_224.pngbin3632 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_225.pngbin3502 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_226.pngbin3406 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_227.pngbin3236 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_228.pngbin2893 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_229.pngbin2471 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_23.pngbin2672 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_230.pngbin2231 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_231.pngbin1821 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_232.pngbin1158 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_233.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_234.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_235.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_236.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_237.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_238.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_239.pngbin910 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_24.pngbin2893 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_25.pngbin3014 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_26.pngbin3236 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_27.pngbin3383 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_28.pngbin3406 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_29.pngbin3448 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_30.pngbin3502 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_31.pngbin3433 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_32.pngbin3632 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_33.pngbin3809 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_34.pngbin4094 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_35.pngbin4249 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_36.pngbin4427 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_37.pngbin4514 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_38.pngbin4623 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_39.pngbin4694 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_40.pngbin4823 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_41.pngbin5044 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_42.pngbin5129 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_43.pngbin5309 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_44.pngbin5451 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_45.pngbin5642 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_46.pngbin5841 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_47.pngbin6071 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_48.pngbin6302 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_49.pngbin6493 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_50.pngbin6469 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_51.pngbin6860 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_52.pngbin7098 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_53.pngbin7322 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_54.pngbin7710 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_55.pngbin8091 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_56.pngbin8387 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_57.pngbin8704 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_58.pngbin9249 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_59.pngbin9514 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_60.pngbin9796 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_61.pngbin9949 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_62.pngbin10068 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_63.pngbin10273 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_64.pngbin10414 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_65.pngbin10537 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_66.pngbin10658 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_67.pngbin10848 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_68.pngbin10959 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_69.pngbin11101 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_70.pngbin11255 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_71.pngbin11410 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_72.pngbin11471 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_73.pngbin11561 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_74.pngbin11515 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_75.pngbin11628 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_76.pngbin11536 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_77.pngbin11551 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_78.pngbin11548 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_79.pngbin11689 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_80.pngbin11977 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_81.pngbin12203 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_82.pngbin12375 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_83.pngbin12430 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_84.pngbin12837 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_85.pngbin13102 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_86.pngbin13459 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_87.pngbin13614 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_88.pngbin13881 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_89.pngbin14318 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_90.pngbin14621 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_91.pngbin14463 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_92.pngbin15031 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_93.pngbin15162 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_94.pngbin15095 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_95.pngbin15115 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_96.pngbin15186 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_97.pngbin15059 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_98.pngbin15598 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_4a_99.pngbin16152 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_0.pngbin0 -> 106 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_1.pngbin0 -> 116 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_10.pngbin0 -> 1331 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_100.pngbin0 -> 5624 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_101.pngbin0 -> 5797 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_102.pngbin0 -> 5881 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_103.pngbin0 -> 6012 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_104.pngbin0 -> 5827 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_105.pngbin0 -> 5946 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_106.pngbin0 -> 6027 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_107.pngbin0 -> 6201 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_108.pngbin0 -> 6252 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_109.pngbin0 -> 6509 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_11.pngbin0 -> 1359 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_110.pngbin0 -> 6202 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_111.pngbin0 -> 6187 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_112.pngbin0 -> 6057 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_113.pngbin0 -> 6021 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_114.pngbin0 -> 5966 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_115.pngbin0 -> 5861 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_116.pngbin0 -> 5777 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_117.pngbin0 -> 5557 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_118.pngbin0 -> 5434 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_119.pngbin0 -> 5262 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_12.pngbin0 -> 1389 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_120.pngbin0 -> 5176 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_121.pngbin0 -> 5216 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_122.pngbin0 -> 5089 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_123.pngbin0 -> 4941 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_124.pngbin0 -> 4818 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_125.pngbin0 -> 4886 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_126.pngbin0 -> 4800 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_127.pngbin0 -> 4761 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_128.pngbin0 -> 4813 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_129.pngbin0 -> 4839 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_13.pngbin0 -> 1471 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_130.pngbin0 -> 4526 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_131.pngbin0 -> 4573 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_132.pngbin0 -> 4674 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_133.pngbin0 -> 4631 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_134.pngbin0 -> 4574 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_135.pngbin0 -> 5077 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_136.pngbin0 -> 4905 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_137.pngbin0 -> 4692 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_138.pngbin0 -> 4451 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_139.pngbin0 -> 4381 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_14.pngbin0 -> 1615 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_140.pngbin0 -> 4287 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_141.pngbin0 -> 4224 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_142.pngbin0 -> 4093 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_143.pngbin0 -> 4076 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_144.pngbin0 -> 4062 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_145.pngbin0 -> 4161 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_146.pngbin0 -> 4185 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_147.pngbin0 -> 3792 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_148.pngbin0 -> 3650 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_149.pngbin0 -> 3586 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_15.pngbin0 -> 1680 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_150.pngbin0 -> 3785 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_151.pngbin0 -> 3619 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_152.pngbin0 -> 3735 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_153.pngbin0 -> 3606 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_154.pngbin0 -> 3638 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_155.pngbin0 -> 3568 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_156.pngbin0 -> 3533 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_157.pngbin0 -> 3259 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_158.pngbin0 -> 3304 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_159.pngbin0 -> 3147 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_16.pngbin0 -> 1890 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_160.pngbin0 -> 3344 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_161.pngbin0 -> 3304 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_162.pngbin0 -> 3132 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_163.pngbin0 -> 3279 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_164.pngbin0 -> 3304 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_165.pngbin0 -> 3221 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_166.pngbin0 -> 3139 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_167.pngbin0 -> 2903 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_168.pngbin0 -> 2856 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_169.pngbin0 -> 2854 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_17.pngbin0 -> 2027 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_170.pngbin0 -> 2667 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_171.pngbin0 -> 2714 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_172.pngbin0 -> 2597 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_173.pngbin0 -> 2571 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_174.pngbin0 -> 2668 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_175.pngbin0 -> 2715 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_176.pngbin0 -> 2580 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_177.pngbin0 -> 2465 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_178.pngbin0 -> 2398 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_179.pngbin0 -> 2422 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_18.pngbin0 -> 2049 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_180.pngbin0 -> 2503 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_181.pngbin0 -> 2518 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_182.pngbin0 -> 2560 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_183.pngbin0 -> 2534 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_184.pngbin0 -> 2515 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_185.pngbin0 -> 2508 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_186.pngbin0 -> 2457 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_187.pngbin0 -> 2517 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_188.pngbin0 -> 2568 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_189.pngbin0 -> 2622 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_19.pngbin0 -> 2090 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_190.pngbin0 -> 2577 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_191.pngbin0 -> 2504 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_192.pngbin0 -> 2493 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_193.pngbin0 -> 2542 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_194.pngbin0 -> 2512 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_195.pngbin0 -> 2392 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_196.pngbin0 -> 2356 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_197.pngbin0 -> 2289 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_198.pngbin0 -> 2208 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_199.pngbin0 -> 2065 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_2.pngbin0 -> 423 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_20.pngbin0 -> 2315 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_200.pngbin0 -> 1987 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_201.pngbin0 -> 1913 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_202.pngbin0 -> 1954 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_203.pngbin0 -> 1942 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_204.pngbin0 -> 2044 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_205.pngbin0 -> 2051 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_206.pngbin0 -> 2047 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_207.pngbin0 -> 2063 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_208.pngbin0 -> 2057 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_209.pngbin0 -> 2082 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_21.pngbin0 -> 2533 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_210.pngbin0 -> 1998 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_211.pngbin0 -> 1986 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_212.pngbin0 -> 1968 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_213.pngbin0 -> 1750 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_214.pngbin0 -> 1750 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_215.pngbin0 -> 1767 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_216.pngbin0 -> 1889 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_217.pngbin0 -> 1807 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_218.pngbin0 -> 1802 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_219.pngbin0 -> 1789 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_22.pngbin0 -> 2611 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_220.pngbin0 -> 1838 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_221.pngbin0 -> 1761 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_222.pngbin0 -> 1603 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_223.pngbin0 -> 1513 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_224.pngbin0 -> 1518 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_23.pngbin0 -> 2663 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_24.pngbin0 -> 2785 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_25.pngbin0 -> 2924 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_26.pngbin0 -> 2996 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_27.pngbin0 -> 3174 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_28.pngbin0 -> 3258 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_29.pngbin0 -> 3399 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_3.pngbin0 -> 536 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_30.pngbin0 -> 3554 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_31.pngbin0 -> 3657 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_32.pngbin0 -> 3674 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_33.pngbin0 -> 3663 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_34.pngbin0 -> 3739 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_35.pngbin0 -> 4212 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_36.pngbin0 -> 4681 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_37.pngbin0 -> 4595 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_38.pngbin0 -> 4779 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_39.pngbin0 -> 4896 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_4.pngbin0 -> 675 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_40.pngbin0 -> 5001 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_41.pngbin0 -> 5157 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_42.pngbin0 -> 5029 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_43.pngbin0 -> 4997 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_44.pngbin0 -> 4917 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_45.pngbin0 -> 4788 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_46.pngbin0 -> 5094 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_47.pngbin0 -> 4979 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_48.pngbin0 -> 4784 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_49.pngbin0 -> 4695 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_5.pngbin0 -> 813 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_50.pngbin0 -> 4682 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_51.pngbin0 -> 4927 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_52.pngbin0 -> 5036 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_53.pngbin0 -> 5143 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_54.pngbin0 -> 5171 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_55.pngbin0 -> 5217 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_56.pngbin0 -> 5077 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_57.pngbin0 -> 5031 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_58.pngbin0 -> 4951 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_59.pngbin0 -> 4955 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_6.pngbin0 -> 915 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_60.pngbin0 -> 5055 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_61.pngbin0 -> 5082 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_62.pngbin0 -> 5141 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_63.pngbin0 -> 5192 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_64.pngbin0 -> 4737 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_65.pngbin0 -> 4659 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_66.pngbin0 -> 4757 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_67.pngbin0 -> 4894 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_68.pngbin0 -> 4968 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_69.pngbin0 -> 4792 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_7.pngbin0 -> 993 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_70.pngbin0 -> 5197 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_71.pngbin0 -> 5462 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_72.pngbin0 -> 5438 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_73.pngbin0 -> 5450 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_74.pngbin0 -> 5568 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_75.pngbin0 -> 5466 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_76.pngbin0 -> 5385 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_77.pngbin0 -> 5307 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_78.pngbin0 -> 5251 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_79.pngbin0 -> 5443 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_8.pngbin0 -> 1122 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_80.pngbin0 -> 5450 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_81.pngbin0 -> 5548 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_82.pngbin0 -> 5651 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_83.pngbin0 -> 5498 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_84.pngbin0 -> 5461 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_85.pngbin0 -> 5500 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_86.pngbin0 -> 5541 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_87.pngbin0 -> 5402 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_88.pngbin0 -> 5584 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_89.pngbin0 -> 5584 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_9.pngbin0 -> 1257 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_90.pngbin0 -> 5977 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_91.pngbin0 -> 5800 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_92.pngbin0 -> 5630 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_93.pngbin0 -> 5672 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_94.pngbin0 -> 5541 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_95.pngbin0 -> 5232 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_96.pngbin0 -> 5236 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_97.pngbin0 -> 5291 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_98.pngbin0 -> 5116 bytes
-rw-r--r--res/drawable-xhdpi/tv_5a_99.pngbin0 -> 5338 bytes
-rw-r--r--res/layout/dvr_main.xml21
-rw-r--r--res/layout/dvr_play.xml28
-rw-r--r--res/layout/fragment_new_sources.xml83
-rw-r--r--res/layout/fragment_welcome.xml114
-rw-r--r--res/layout/fragment_welcome_page.xml48
-rw-r--r--res/layout/menu_card_dvr.xml52
-rw-r--r--res/layout/menu_card_guide.xml4
-rw-r--r--res/layout/onboarding_welcome_background.xml39
-rw-r--r--res/layout/onboarding_welcome_content.xml54
-rw-r--r--res/layout/onboarding_welcome_foreground.xml (renamed from res/layout/setup_item_divider.xml)17
-rw-r--r--res/layout/option_item_simple.xml33
-rw-r--r--res/layout/overlay_root_view.xml4
-rw-r--r--res/layout/setup_dialog.xml71
-rw-r--r--res/layout/setup_item_action.xml42
-rw-r--r--res/layout/setup_item_input.xml51
-rw-r--r--res/values-af/arrays.xml12
-rw-r--r--res/values-af/strings.xml60
-rw-r--r--res/values-am/arrays.xml12
-rw-r--r--res/values-am/strings.xml60
-rw-r--r--res/values-ar/arrays.xml12
-rw-r--r--res/values-ar/strings.xml72
-rw-r--r--res/values-az-rAZ/arrays.xml57
-rw-r--r--res/values-az-rAZ/strings.xml202
-rw-r--r--res/values-bg/arrays.xml12
-rw-r--r--res/values-bg/strings.xml60
-rw-r--r--res/values-bn-rBD/arrays.xml12
-rw-r--r--res/values-bn-rBD/strings.xml62
-rw-r--r--res/values-ca/arrays.xml12
-rw-r--r--res/values-ca/strings.xml62
-rw-r--r--res/values-cs/arrays.xml12
-rw-r--r--res/values-cs/strings.xml66
-rw-r--r--res/values-da/arrays.xml12
-rw-r--r--res/values-da/strings.xml60
-rw-r--r--res/values-de/arrays.xml12
-rw-r--r--res/values-de/strings.xml60
-rw-r--r--res/values-el/arrays.xml12
-rw-r--r--res/values-el/strings.xml58
-rw-r--r--res/values-en-rAU/arrays.xml12
-rw-r--r--res/values-en-rAU/strings.xml60
-rw-r--r--res/values-en-rGB/arrays.xml12
-rw-r--r--res/values-en-rGB/strings.xml60
-rw-r--r--res/values-en-rIN/arrays.xml12
-rw-r--r--res/values-en-rIN/strings.xml60
-rw-r--r--res/values-es-rUS/arrays.xml12
-rw-r--r--res/values-es-rUS/strings.xml60
-rw-r--r--res/values-es/arrays.xml12
-rw-r--r--res/values-es/strings.xml60
-rw-r--r--res/values-et-rEE/arrays.xml12
-rw-r--r--res/values-et-rEE/strings.xml60
-rw-r--r--res/values-eu-rES/arrays.xml12
-rw-r--r--res/values-eu-rES/strings.xml60
-rw-r--r--res/values-fa/arrays.xml12
-rw-r--r--res/values-fa/strings.xml62
-rw-r--r--res/values-fi/arrays.xml12
-rw-r--r--res/values-fi/strings.xml60
-rw-r--r--res/values-fr-rCA/arrays.xml12
-rw-r--r--res/values-fr-rCA/strings.xml60
-rw-r--r--res/values-fr/arrays.xml12
-rw-r--r--res/values-fr/strings.xml60
-rw-r--r--res/values-gl-rES/arrays.xml12
-rw-r--r--res/values-gl-rES/strings.xml62
-rw-r--r--res/values-hi/arrays.xml12
-rw-r--r--res/values-hi/strings.xml60
-rw-r--r--res/values-hr/arrays.xml12
-rw-r--r--res/values-hr/strings.xml63
-rw-r--r--res/values-hu/arrays.xml12
-rw-r--r--res/values-hu/strings.xml60
-rw-r--r--res/values-hy-rAM/arrays.xml12
-rw-r--r--res/values-hy-rAM/strings.xml62
-rw-r--r--res/values-in/arrays.xml12
-rw-r--r--res/values-in/strings.xml60
-rw-r--r--res/values-is-rIS/arrays.xml12
-rw-r--r--res/values-is-rIS/strings.xml60
-rw-r--r--res/values-it/arrays.xml12
-rw-r--r--res/values-it/strings.xml62
-rw-r--r--res/values-iw/arrays.xml12
-rw-r--r--res/values-iw/strings.xml68
-rw-r--r--res/values-ja/arrays.xml12
-rw-r--r--res/values-ja/strings.xml60
-rw-r--r--res/values-ka-rGE/arrays.xml12
-rw-r--r--res/values-ka-rGE/strings.xml60
-rw-r--r--res/values-kk-rKZ/arrays.xml12
-rw-r--r--res/values-kk-rKZ/strings.xml60
-rw-r--r--res/values-km-rKH/arrays.xml12
-rw-r--r--res/values-km-rKH/strings.xml60
-rw-r--r--res/values-kn-rIN/arrays.xml12
-rw-r--r--res/values-kn-rIN/strings.xml60
-rw-r--r--res/values-ko/arrays.xml12
-rw-r--r--res/values-ko/strings.xml60
-rw-r--r--res/values-ky-rKG/arrays.xml12
-rw-r--r--res/values-ky-rKG/strings.xml60
-rw-r--r--res/values-lo-rLA/arrays.xml12
-rw-r--r--res/values-lo-rLA/strings.xml60
-rw-r--r--res/values-lt/arrays.xml12
-rw-r--r--res/values-lt/strings.xml66
-rw-r--r--res/values-lv/arrays.xml12
-rw-r--r--res/values-lv/strings.xml63
-rw-r--r--res/values-mk-rMK/arrays.xml12
-rw-r--r--res/values-mk-rMK/strings.xml60
-rw-r--r--res/values-ml-rIN/arrays.xml12
-rw-r--r--res/values-ml-rIN/strings.xml58
-rw-r--r--res/values-mn-rMN/arrays.xml12
-rw-r--r--res/values-mn-rMN/strings.xml60
-rw-r--r--res/values-mr-rIN/arrays.xml12
-rw-r--r--res/values-mr-rIN/strings.xml60
-rw-r--r--res/values-ms-rMY/arrays.xml12
-rw-r--r--res/values-ms-rMY/strings.xml60
-rw-r--r--res/values-my-rMM/arrays.xml12
-rw-r--r--res/values-my-rMM/strings.xml60
-rw-r--r--res/values-nb/arrays.xml12
-rw-r--r--res/values-nb/strings.xml60
-rw-r--r--res/values-ne-rNP/arrays.xml12
-rw-r--r--res/values-ne-rNP/strings.xml64
-rw-r--r--res/values-nl/arrays.xml12
-rw-r--r--res/values-nl/strings.xml60
-rw-r--r--res/values-pl/arrays.xml12
-rw-r--r--res/values-pl/strings.xml66
-rw-r--r--res/values-pt-rPT/arrays.xml12
-rw-r--r--res/values-pt-rPT/strings.xml60
-rw-r--r--res/values-pt/arrays.xml12
-rw-r--r--res/values-pt/strings.xml60
-rw-r--r--res/values-ro/arrays.xml12
-rw-r--r--res/values-ro/strings.xml67
-rw-r--r--res/values-ru/arrays.xml12
-rw-r--r--res/values-ru/strings.xml68
-rw-r--r--res/values-si-rLK/arrays.xml12
-rw-r--r--res/values-si-rLK/strings.xml60
-rw-r--r--res/values-sk/arrays.xml12
-rw-r--r--res/values-sk/strings.xml66
-rw-r--r--res/values-sl/arrays.xml12
-rw-r--r--res/values-sl/strings.xml66
-rw-r--r--res/values-sr/arrays.xml12
-rw-r--r--res/values-sr/strings.xml63
-rw-r--r--res/values-sv/arrays.xml12
-rw-r--r--res/values-sv/strings.xml60
-rw-r--r--res/values-sw/arrays.xml12
-rw-r--r--res/values-sw/strings.xml60
-rw-r--r--res/values-ta-rIN/arrays.xml12
-rw-r--r--res/values-ta-rIN/strings.xml60
-rw-r--r--res/values-te-rIN/arrays.xml12
-rw-r--r--res/values-te-rIN/strings.xml60
-rw-r--r--res/values-th/arrays.xml12
-rw-r--r--res/values-th/strings.xml60
-rw-r--r--res/values-tl/arrays.xml12
-rw-r--r--res/values-tl/strings.xml60
-rw-r--r--res/values-tr/arrays.xml12
-rw-r--r--res/values-tr/strings.xml60
-rw-r--r--res/values-uk/arrays.xml12
-rw-r--r--res/values-uk/strings.xml66
-rw-r--r--res/values-ur-rPK/arrays.xml12
-rw-r--r--res/values-ur-rPK/strings.xml60
-rw-r--r--res/values-uz-rUZ/arrays.xml12
-rw-r--r--res/values-uz-rUZ/strings.xml62
-rw-r--r--res/values-vi/arrays.xml12
-rw-r--r--res/values-vi/strings.xml60
-rw-r--r--res/values-zh-rCN/arrays.xml12
-rw-r--r--res/values-zh-rCN/strings.xml60
-rw-r--r--res/values-zh-rHK/arrays.xml12
-rw-r--r--res/values-zh-rHK/strings.xml60
-rw-r--r--res/values-zh-rTW/arrays.xml12
-rw-r--r--res/values-zh-rTW/strings.xml60
-rw-r--r--res/values-zu/arrays.xml12
-rw-r--r--res/values-zu/strings.xml60
-rw-r--r--res/values/arrays.xml27
-rw-r--r--res/values/colors.xml13
-rw-r--r--res/values/dimens.xml21
-rw-r--r--res/values/integers.xml4
-rw-r--r--res/values/strings.xml167
-rw-r--r--res/values/styles.xml4
-rw-r--r--res/values/themes.xml6
-rw-r--r--src/com/android/tv/ApplicationSingletons.java5
-rw-r--r--src/com/android/tv/ChannelTuner.java4
-rw-r--r--src/com/android/tv/Features.java57
-rw-r--r--src/com/android/tv/MainActivity.java361
-rw-r--r--src/com/android/tv/MainActivityWrapper.java129
-rw-r--r--src/com/android/tv/SetupPassthroughActivity.java4
-rw-r--r--src/com/android/tv/TimeShiftManager.java74
-rw-r--r--src/com/android/tv/TvApplication.java131
-rw-r--r--src/com/android/tv/TvOptionsManager.java15
-rw-r--r--src/com/android/tv/analytics/OptOutPreferenceHelper.java112
-rw-r--r--src/com/android/tv/analytics/SendChannelStatusRunnable.java116
-rw-r--r--src/com/android/tv/analytics/StubAnalytics.java2
-rw-r--r--src/com/android/tv/data/Channel.java33
-rw-r--r--src/com/android/tv/data/ChannelDataManager.java92
-rw-r--r--src/com/android/tv/data/GenreItems.java35
-rw-r--r--src/com/android/tv/data/Program.java44
-rw-r--r--src/com/android/tv/data/ProgramDataManager.java25
-rw-r--r--src/com/android/tv/data/TvInputNewComparator.java10
-rw-r--r--src/com/android/tv/data/WatchedHistoryManager.java5
-rw-r--r--src/com/android/tv/dialog/FullscreenDialogFragment.java25
-rw-r--r--src/com/android/tv/dvr/BaseDvrDataManager.java8
-rw-r--r--src/com/android/tv/dvr/DvrDataManager.java9
-rw-r--r--src/com/android/tv/dvr/DvrDataManagerImpl.java95
-rw-r--r--src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java38
-rw-r--r--src/com/android/tv/dvr/DvrManager.java72
-rw-r--r--src/com/android/tv/dvr/DvrPlayActivity.java47
-rw-r--r--src/com/android/tv/dvr/DvrRecordingService.java20
-rw-r--r--src/com/android/tv/dvr/DvrSessionManager.java56
-rw-r--r--src/com/android/tv/dvr/Recording.java76
-rw-r--r--src/com/android/tv/dvr/RecordingTask.java242
-rw-r--r--src/com/android/tv/dvr/Scheduler.java73
-rw-r--r--src/com/android/tv/dvr/WritableDvrDataManager.java3
-rw-r--r--src/com/android/tv/dvr/provider/AsyncDvrDbTask.java72
-rw-r--r--src/com/android/tv/dvr/provider/DvrContract.java10
-rw-r--r--src/com/android/tv/dvr/provider/DvrDatabaseHelper.java93
-rw-r--r--src/com/android/tv/dvr/ui/DvrActivity.java (renamed from src/com/android/tv/util/CollectionUtils.java)28
-rw-r--r--src/com/android/tv/dvr/ui/DvrBrowseFragment.java119
-rw-r--r--src/com/android/tv/dvr/ui/GridItemPresenter.java165
-rw-r--r--src/com/android/tv/guide/ProgramGuide.java81
-rw-r--r--src/com/android/tv/guide/ProgramItemView.java103
-rw-r--r--src/com/android/tv/guide/ProgramManager.java4
-rw-r--r--src/com/android/tv/guide/ProgramTableAdapter.java74
-rw-r--r--src/com/android/tv/menu/ActionCardView.java1
-rw-r--r--src/com/android/tv/menu/AppLinkCardView.java35
-rw-r--r--src/com/android/tv/menu/ChannelCardView.java31
-rw-r--r--src/com/android/tv/menu/ChannelsPosterPrefetcher.java26
-rw-r--r--src/com/android/tv/menu/ChannelsRowAdapter.java74
-rw-r--r--src/com/android/tv/menu/MenuAction.java19
-rw-r--r--src/com/android/tv/menu/MenuRowView.java1
-rw-r--r--src/com/android/tv/menu/PlayControlsRowView.java20
-rw-r--r--src/com/android/tv/menu/SimpleCardView.java (renamed from src/com/android/tv/menu/GuideCardView.java)8
-rw-r--r--src/com/android/tv/menu/TvOptionsRowAdapter.java36
-rw-r--r--src/com/android/tv/onboarding/AppOverviewFragment.java110
-rw-r--r--src/com/android/tv/onboarding/NewSourcesFragment.java82
-rw-r--r--src/com/android/tv/onboarding/OnboardingActivity.java260
-rw-r--r--src/com/android/tv/onboarding/PagingIndicator.java235
-rw-r--r--src/com/android/tv/onboarding/SetupSourcesFragment.java428
-rw-r--r--src/com/android/tv/onboarding/WelcomeFragment.java828
-rw-r--r--src/com/android/tv/onboarding/WelcomePageFragment.java58
-rw-r--r--src/com/android/tv/receiver/AudioCapabilitiesReceiver.java5
-rw-r--r--src/com/android/tv/receiver/BootCompletedReceiver.java7
-rw-r--r--src/com/android/tv/receiver/PackageIntentsReceiver.java2
-rw-r--r--src/com/android/tv/recommendation/NotificationService.java162
-rw-r--r--src/com/android/tv/search/DataManagerSearch.java4
-rw-r--r--src/com/android/tv/search/LocalSearchProvider.java9
-rw-r--r--src/com/android/tv/search/ProgramGuideSearchFragment.java24
-rw-r--r--src/com/android/tv/search/TvProviderSearch.java14
-rw-r--r--src/com/android/tv/ui/AppLayerTvView.java4
-rw-r--r--src/com/android/tv/ui/ChannelBannerView.java55
-rw-r--r--src/com/android/tv/ui/InputBannerView.java3
-rw-r--r--src/com/android/tv/ui/KeypadChannelSwitchView.java4
-rw-r--r--src/com/android/tv/ui/SetupView.java419
-rw-r--r--src/com/android/tv/ui/TunableTvView.java92
-rw-r--r--src/com/android/tv/ui/TvOverlayManager.java381
-rw-r--r--src/com/android/tv/ui/sidepanel/AboutFragment.java187
-rw-r--r--src/com/android/tv/ui/sidepanel/ChannelSourcesFragment.java104
-rw-r--r--src/com/android/tv/ui/sidepanel/DeveloperFragment.java40
-rw-r--r--src/com/android/tv/ui/sidepanel/Item.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/SettingsFragment.java185
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragmentManager.java12
-rw-r--r--src/com/android/tv/ui/sidepanel/SimpleItem.java34
-rw-r--r--src/com/android/tv/util/BitmapUtils.java9
-rw-r--r--src/com/android/tv/util/ImageCache.java1
-rw-r--r--src/com/android/tv/util/ImageLoader.java134
-rw-r--r--src/com/android/tv/util/MultiLongSparseArray.java2
-rw-r--r--src/com/android/tv/util/OnboardingUtils.java45
-rw-r--r--src/com/android/tv/util/PipInputManager.java1
-rw-r--r--src/com/android/tv/util/RecurringRunner.java12
-rw-r--r--src/com/android/tv/util/SearchManagerHelper.java2
-rw-r--r--src/com/android/tv/util/SetupUtils.java114
-rw-r--r--src/com/android/tv/util/SoftPreconditions.java6
-rw-r--r--src/com/android/tv/util/SystemProperties.java7
-rw-r--r--src/com/android/tv/util/TvSettings.java3
-rw-r--r--src/com/android/tv/util/Utils.java33
-rw-r--r--src/com/android/usbtuner/UsbInputController.java3
-rw-r--r--tests/common/src/com/android/tv/MockTvApplication.java12
-rw-r--r--tests/common/src/com/android/tv/testing/ChannelUtils.java2
-rw-r--r--tests/common/src/com/android/tv/testing/ProgramUtils.java4
-rw-r--r--tests/common/src/com/android/tv/testing/TvContentRatingConstants.java7
-rw-r--r--tests/common/src/com/android/tv/testing/Utils.java25
-rw-r--r--tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java32
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java14
-rw-r--r--tests/func/src/com/android/tv/tests/ui/AboutFragmentTest.java57
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java32
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java17
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java3
-rw-r--r--tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java15
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputService.java8
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java103
-rw-r--r--tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java172
-rw-r--r--tests/unit/src/com/android/tv/common/ui/setup/leanback/PagingIndicatorTest.java94
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java3
-rw-r--r--tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java26
-rw-r--r--tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java2
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java12
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java4
-rw-r--r--tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java168
-rw-r--r--tests/unit/src/com/android/tv/dvr/RecordingTest.java50
-rw-r--r--tests/unit/src/com/android/tv/dvr/SchedulerTest.java11
-rw-r--r--tests/unit/src/com/android/tv/util/TestUtils.java2
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java183
-rw-r--r--usbtuner/Android.mk24
-rw-r--r--usbtuner/AndroidManifest.xml7
-rw-r--r--usbtuner/jni/Android.mk4
-rw-r--r--usbtuner/jni/DvbManager.cpp4
-rw-r--r--usbtuner/jni/DvbManager.h12
-rwxr-xr-xusbtuner/jni/gen_jni.sh2
-rw-r--r--usbtuner/jni/tunertvinput_jni.cpp (renamed from usbtuner/jni/usbtuner_jni.cpp)34
-rw-r--r--usbtuner/jni/tunertvinput_jni.h90
-rw-r--r--usbtuner/jni/usbtuner_jni.h79
-rw-r--r--usbtuner/res/layout/ut_channel_scan.xml18
-rw-r--r--usbtuner/res/values-af/strings.xml24
-rw-r--r--usbtuner/res/values-am/strings.xml24
-rw-r--r--usbtuner/res/values-ar/strings.xml36
-rw-r--r--usbtuner/res/values-az-rAZ/strings.xml78
-rw-r--r--usbtuner/res/values-bg/strings.xml24
-rw-r--r--usbtuner/res/values-bn-rBD/strings.xml24
-rw-r--r--usbtuner/res/values-ca/strings.xml24
-rw-r--r--usbtuner/res/values-cs/strings.xml30
-rw-r--r--usbtuner/res/values-da/strings.xml24
-rw-r--r--usbtuner/res/values-de/strings.xml24
-rw-r--r--usbtuner/res/values-el/strings.xml24
-rw-r--r--usbtuner/res/values-en-rAU/strings.xml24
-rw-r--r--usbtuner/res/values-en-rGB/strings.xml24
-rw-r--r--usbtuner/res/values-en-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-es-rUS/strings.xml24
-rw-r--r--usbtuner/res/values-es/strings.xml24
-rw-r--r--usbtuner/res/values-et-rEE/strings.xml24
-rw-r--r--usbtuner/res/values-eu-rES/strings.xml24
-rw-r--r--usbtuner/res/values-fa/strings.xml24
-rw-r--r--usbtuner/res/values-fi/strings.xml24
-rw-r--r--usbtuner/res/values-fr-rCA/strings.xml24
-rw-r--r--usbtuner/res/values-fr/strings.xml24
-rw-r--r--usbtuner/res/values-gl-rES/strings.xml24
-rw-r--r--usbtuner/res/values-hi/strings.xml24
-rw-r--r--usbtuner/res/values-hr/strings.xml27
-rw-r--r--usbtuner/res/values-hu/strings.xml24
-rw-r--r--usbtuner/res/values-hy-rAM/strings.xml24
-rw-r--r--usbtuner/res/values-in/strings.xml24
-rw-r--r--usbtuner/res/values-is-rIS/strings.xml24
-rw-r--r--usbtuner/res/values-it/strings.xml24
-rw-r--r--usbtuner/res/values-iw/strings.xml30
-rw-r--r--usbtuner/res/values-ja/strings.xml24
-rw-r--r--usbtuner/res/values-ka-rGE/strings.xml24
-rw-r--r--usbtuner/res/values-kk-rKZ/strings.xml24
-rw-r--r--usbtuner/res/values-km-rKH/strings.xml24
-rw-r--r--usbtuner/res/values-kn-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-ko/strings.xml24
-rw-r--r--usbtuner/res/values-ky-rKG/strings.xml24
-rw-r--r--usbtuner/res/values-lo-rLA/strings.xml24
-rw-r--r--usbtuner/res/values-lt/strings.xml30
-rw-r--r--usbtuner/res/values-lv/strings.xml27
-rw-r--r--usbtuner/res/values-mk-rMK/strings.xml24
-rw-r--r--usbtuner/res/values-ml-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-mn-rMN/strings.xml24
-rw-r--r--usbtuner/res/values-mr-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-ms-rMY/strings.xml24
-rw-r--r--usbtuner/res/values-my-rMM/strings.xml24
-rw-r--r--usbtuner/res/values-nb/strings.xml24
-rw-r--r--usbtuner/res/values-ne-rNP/strings.xml24
-rw-r--r--usbtuner/res/values-nl/strings.xml24
-rw-r--r--usbtuner/res/values-pl/strings.xml30
-rw-r--r--usbtuner/res/values-pt-rPT/strings.xml24
-rw-r--r--usbtuner/res/values-pt/strings.xml24
-rw-r--r--usbtuner/res/values-ro/strings.xml27
-rw-r--r--usbtuner/res/values-ru/strings.xml30
-rw-r--r--usbtuner/res/values-si-rLK/strings.xml24
-rw-r--r--usbtuner/res/values-sk/strings.xml30
-rw-r--r--usbtuner/res/values-sl/strings.xml30
-rw-r--r--usbtuner/res/values-sr/strings.xml27
-rw-r--r--usbtuner/res/values-sv/strings.xml24
-rw-r--r--usbtuner/res/values-sw/strings.xml24
-rw-r--r--usbtuner/res/values-ta-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-te-rIN/strings.xml24
-rw-r--r--usbtuner/res/values-th/strings.xml24
-rw-r--r--usbtuner/res/values-tl/strings.xml24
-rw-r--r--usbtuner/res/values-tr/strings.xml24
-rw-r--r--usbtuner/res/values-uk/strings.xml30
-rw-r--r--usbtuner/res/values-ur-rPK/strings.xml24
-rw-r--r--usbtuner/res/values-uz-rUZ/strings.xml24
-rw-r--r--usbtuner/res/values-vi/strings.xml24
-rw-r--r--usbtuner/res/values-zh-rCN/strings.xml24
-rw-r--r--usbtuner/res/values-zh-rHK/strings.xml24
-rw-r--r--usbtuner/res/values-zh-rTW/strings.xml24
-rw-r--r--usbtuner/res/values-zu/strings.xml24
-rw-r--r--usbtuner/res/values/dimens.xml1
-rw-r--r--usbtuner/res/xml/ut_tvinputservice.xml2
-rw-r--r--usbtuner/src/com/android/usbtuner/ChannelScanFileParser.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/DvbDeviceAccessor.java33
-rw-r--r--usbtuner/src/com/android/usbtuner/FileDataSource.java3
-rw-r--r--usbtuner/src/com/android/usbtuner/InputStreamSource.java7
-rw-r--r--usbtuner/src/com/android/usbtuner/InternalTunerHal.java57
-rw-r--r--usbtuner/src/com/android/usbtuner/SetupGuidedStepFragment.java543
-rw-r--r--usbtuner/src/com/android/usbtuner/TunerHal.java231
-rw-r--r--usbtuner/src/com/android/usbtuner/TunerSetupActivity.java400
-rw-r--r--usbtuner/src/com/android/usbtuner/UsbTunerDataSource.java34
-rw-r--r--usbtuner/src/com/android/usbtuner/UsbTunerHal.java168
-rw-r--r--usbtuner/src/com/android/usbtuner/UsbTunerInterface.java312
-rw-r--r--usbtuner/src/com/android/usbtuner/UsbTunerPreferences.java75
-rw-r--r--usbtuner/src/com/android/usbtuner/UsbTunerTsScannerSource.java20
-rw-r--r--usbtuner/src/com/android/usbtuner/data/TunerChannel.java9
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/BaseSampleSourceExtractor.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/CacheManager.java1
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/CachedSampleSourceExtractor.java9
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/DvrStorageManager.java10
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/MediaCodecVideoTrackRenderer.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPassthroughAc3RendererBuilder.java6
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPlayer.java15
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/MpegTsSampleSourceExtractor.java33
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/RecordSampleSourceExtractor.java7
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/ReplaySampleSourceExtractor.java311
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/SampleCache.java36
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/SampleQueue.java10
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/TrickplayStorageManager.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/ac3/Ac3TrackRenderer.java41
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackMonitor.java14
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackWrapper.java1
-rw-r--r--usbtuner/src/com/android/usbtuner/exoplayer/ac3/MediaClock.java80
-rw-r--r--usbtuner/src/com/android/usbtuner/setup/ConnectionTypeFragment.java82
-rw-r--r--usbtuner/src/com/android/usbtuner/setup/ScanFragment.java (renamed from usbtuner/src/com/android/usbtuner/ScanActivity.java)257
-rw-r--r--usbtuner/src/com/android/usbtuner/setup/ScanResultFragment.java123
-rw-r--r--usbtuner/src/com/android/usbtuner/setup/TunerSetupActivity.java242
-rw-r--r--usbtuner/src/com/android/usbtuner/setup/WelcomeFragment.java100
-rw-r--r--usbtuner/src/com/android/usbtuner/ts/TsParser.java27
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/BaseTunerTvInputService.java113
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/ChannelDataManager.java11
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImplInternal.java62
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/EventDetector.java13
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/InternalTunerTvInputService.java107
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/RecordingSessionImpl.java (renamed from usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImpl.java)17
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImpl.java20
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImplInternal.java227
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/UsbTunerDebug.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/tvinput/UsbTunerTvInputService.java88
-rw-r--r--usbtuner/src/com/android/usbtuner/util/Ints.java2
-rw-r--r--usbtuner/src/com/android/usbtuner/util/TisConfiguration.java22
-rw-r--r--usbtuner/src/com/google/android/exoplayer/audio/AudioTrack.java21
-rw-r--r--version.mk6
1096 files changed, 18715 insertions, 9479 deletions
diff --git a/Android.mk b/Android.mk
index 5628c03c..e05a21f4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -21,15 +21,7 @@ LOCAL_MODULE_TAGS := optional
include $(LOCAL_PATH)/version.mk
-LOCAL_BUILDCONFIG_CLASS := src/com/android/tv/BuildConfig.java
-BC_OUT_DIR := $(LOCAL_PATH)
-BC_APPLICATION_ID := "com.android.tv"
-BC_VERSION_CODE := $(version_code_package)
-BC_VERSION_NAME := "$(version_name_package)"
-include $(LOCAL_PATH)/buildconfig.mk
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(LOCAL_BUILDCONFIG_CLASS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := LiveTv
@@ -40,6 +32,7 @@ LOCAL_SDK_VERSION := system_current
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/res \
$(LOCAL_PATH)/common/res \
+ $(LOCAL_PATH)/common/res_leanback \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res \
@@ -71,7 +64,7 @@ ifeq ($(TARGET_BUILD_APPS),)
endif
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/usbtuner/res
LOCAL_STATIC_JAVA_LIBRARIES += usbtuner-tvinput
-LOCAL_JNI_SHARED_LIBRARIES := libusbtuner_jni
+LOCAL_JNI_SHARED_LIBRARIES := libtunertvinput_jni
LOCAL_AAPT_FLAGS += --extra-packages com.android.usbtuner
include $(BUILD_PACKAGE)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9f8a67ad..9790798c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -100,6 +100,10 @@
android:launchMode="singleTop"
android:theme="@style/Theme.Setup.GuidedStep" />
+ <activity android:name=".dvr.ui.DvrActivity"
+ android:launchMode="singleTask"
+ android:theme="@style/Theme.Leanback.Browse" />
+
<provider android:name="com.android.tv.search.LocalSearchProvider"
android:authorities="com.android.tv.search"
android:exported="true"
@@ -142,18 +146,16 @@
</receiver>
<!-- USB tuner components definition -->
- <activity android:name="com.android.usbtuner.TunerSetupActivity"
+ <activity android:name="com.android.usbtuner.setup.TunerSetupActivity"
android:label="@string/ut_app_name"
android:launchMode="singleInstance"
android:process="com.android.usbtuner"
- android:theme="@style/Theme.UsbTunerSetup.Leanback.GuidedStep" >
+ android:theme="@style/Theme.Setup.GuidedStep" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
- <activity android:name="com.android.usbtuner.ScanActivity"
- android:process="com.android.usbtuner"
- android:theme="@style/Theme.Leanback" />
+ <activity android:name=".dvr.DvrPlayActivity"/>
<service android:name="com.android.usbtuner.tvinput.UsbTunerTvInputService"
android:enabled="false"
android:process="com.android.usbtuner"
diff --git a/common/Android.mk b/common/Android.mk
index 2f9c32e2..878cbb8b 100644
--- a/common/Android.mk
+++ b/common/Android.mk
@@ -1,8 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_BUILDCONFIG_CLASS := src/com/android/tv/common/BuildConfig.java
+BC_OUT_DIR := $(LOCAL_PATH)
+BC_APPLICATION_ID := "com.android.tv.common"
+include $(LOCAL_PATH)/buildconfig.mk
+
# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(LOCAL_BUILDCONFIG_CLASS)
LOCAL_MODULE := tv-common
LOCAL_MODULE_TAGS := optional
@@ -11,7 +17,8 @@ LOCAL_SDK_VERSION := system_current
LOCAL_RESOURCE_DIR := \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res \
- $(LOCAL_PATH)/res
+ $(LOCAL_PATH)/res \
+ $(LOCAL_PATH)/res_leanback \
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-annotations \
diff --git a/buildconfig.mk b/common/buildconfig.mk
index 93fcbcb0..93fcbcb0 100644
--- a/buildconfig.mk
+++ b/common/buildconfig.mk
diff --git a/common/res/drawable/setup_selector_background.xml b/common/res/drawable/setup_selector_background.xml
index 4f3ebfde..7351270b 100644
--- a/common/res/drawable/setup_selector_background.xml
+++ b/common/res/drawable/setup_selector_background.xml
@@ -14,11 +14,14 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape>
- <solid android:color="#26FFFFFF"/>
- <corners android:radius="2dp" />
- </shape>
+
+<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">
+ <shape>
+ <solid android:color="@android:color/white"/>
+ <corners android:radius="2dp" />
+ </shape>
</item>
-</selector>
+</ripple>
diff --git a/common/res/layout/activity_stepped_setup.xml b/common/res/layout/activity_setup.xml
index f742c539..f742c539 100644
--- a/common/res/layout/activity_stepped_setup.xml
+++ b/common/res/layout/activity_setup.xml
diff --git a/common/res/layout/fragment_setup_multi_pane.xml b/common/res/layout/fragment_setup_multi_pane.xml
index 32bf3188..84798c02 100644
--- a/common/res/layout/fragment_setup_multi_pane.xml
+++ b/common/res/layout/fragment_setup_multi_pane.xml
@@ -23,6 +23,12 @@
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="horizontal">
+ <View
+ android:id="@+id/setup_common_guidance_background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginStart="@dimen/setup_common_guidance_background_margin_start"
+ android:background="?attr/setupCommonGuidanceBackground" />
<!-- Guided step fragment container must be at the left of the done button at least by 1 pixel
for the focus navigation. If they overlap, the focus doesn't move from the button to the
fragment container.-->
@@ -33,13 +39,14 @@
android:layout_marginEnd="1dp"
android:clipChildren="false"
android:clipToPadding="false" />
+ // TODO: Use button action list in GuidedStepFragment
<FrameLayout
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:background="@color/common_setup_done_container_background"
- android:transitionGroup="false"
+ style="?attr/doneButtonContainerStyle"
+ android:transitionGroup="true"
android:transitionName="buttonDoneTransition">
<TextView
android:id="@+id/button_done"
diff --git a/common/res/values-af/strings.xml b/common/res/values-af/strings.xml
new file mode 100644
index 00000000..11b3990a
--- /dev/null
+++ b/common/res/values-af/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Klaar"</string>
+</resources>
diff --git a/common/res/values-am/strings.xml b/common/res/values-am/strings.xml
new file mode 100644
index 00000000..b72ab7d0
--- /dev/null
+++ b/common/res/values-am/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-ar/strings.xml b/common/res/values-ar/strings.xml
new file mode 100644
index 00000000..d234a33b
--- /dev/null
+++ b/common/res/values-ar/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..4770dd1e
--- /dev/null
+++ b/common/res/values-az-rAZ/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-bg/strings.xml b/common/res/values-bg/strings.xml
new file mode 100644
index 00000000..a8d42c3a
--- /dev/null
+++ b/common/res/values-bg/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..ef20cd3f
--- /dev/null
+++ b/common/res/values-bn-rBD/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-ca/strings.xml b/common/res/values-ca/strings.xml
new file mode 100644
index 00000000..790c58aa
--- /dev/null
+++ b/common/res/values-ca/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Fet"</string>
+</resources>
diff --git a/common/res/values-cs/strings.xml b/common/res/values-cs/strings.xml
new file mode 100644
index 00000000..6bc7a34d
--- /dev/null
+++ b/common/res/values-cs/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Hotovo"</string>
+</resources>
diff --git a/common/res/values-da/strings.xml b/common/res/values-da/strings.xml
new file mode 100644
index 00000000..a3ff65d6
--- /dev/null
+++ b/common/res/values-da/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Udført"</string>
+</resources>
diff --git a/common/res/values-de/strings.xml b/common/res/values-de/strings.xml
new file mode 100644
index 00000000..08cecfa4
--- /dev/null
+++ b/common/res/values-de/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Fertig"</string>
+</resources>
diff --git a/common/res/values-el/strings.xml b/common/res/values-el/strings.xml
new file mode 100644
index 00000000..8d178e29
--- /dev/null
+++ b/common/res/values-el/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-en-rAU/strings.xml b/common/res/values-en-rAU/strings.xml
new file mode 100644
index 00000000..5b24567c
--- /dev/null
+++ b/common/res/values-en-rAU/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Finished"</string>
+</resources>
diff --git a/common/res/values-en-rGB/strings.xml b/common/res/values-en-rGB/strings.xml
new file mode 100644
index 00000000..5b24567c
--- /dev/null
+++ b/common/res/values-en-rGB/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Finished"</string>
+</resources>
diff --git a/common/res/values-en-rIN/strings.xml b/common/res/values-en-rIN/strings.xml
new file mode 100644
index 00000000..5b24567c
--- /dev/null
+++ b/common/res/values-en-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Finished"</string>
+</resources>
diff --git a/common/res/values-es-rUS/strings.xml b/common/res/values-es-rUS/strings.xml
new file mode 100644
index 00000000..76f39ab4
--- /dev/null
+++ b/common/res/values-es-rUS/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Listo"</string>
+</resources>
diff --git a/common/res/values-es/strings.xml b/common/res/values-es/strings.xml
new file mode 100644
index 00000000..76f39ab4
--- /dev/null
+++ b/common/res/values-es/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Listo"</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..58a71664
--- /dev/null
+++ b/common/res/values-et-rEE/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..bdc86896
--- /dev/null
+++ b/common/res/values-eu-rES/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-fa/strings.xml b/common/res/values-fa/strings.xml
new file mode 100644
index 00000000..919c37fe
--- /dev/null
+++ b/common/res/values-fa/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-fi/strings.xml b/common/res/values-fi/strings.xml
new file mode 100644
index 00000000..58a71664
--- /dev/null
+++ b/common/res/values-fi/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-fr-rCA/strings.xml b/common/res/values-fr-rCA/strings.xml
new file mode 100644
index 00000000..a5334fed
--- /dev/null
+++ b/common/res/values-fr-rCA/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Terminé"</string>
+</resources>
diff --git a/common/res/values-fr/strings.xml b/common/res/values-fr/strings.xml
new file mode 100644
index 00000000..a018b053
--- /dev/null
+++ b/common/res/values-fr/strings.xml
@@ -0,0 +1,21 @@
+<?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">"OK"</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..04167ec0
--- /dev/null
+++ b/common/res/values-gl-rES/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-hi/strings.xml b/common/res/values-hi/strings.xml
new file mode 100644
index 00000000..93ddf14d
--- /dev/null
+++ b/common/res/values-hi/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-hr/strings.xml b/common/res/values-hr/strings.xml
new file mode 100644
index 00000000..e359fa47
--- /dev/null
+++ b/common/res/values-hr/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Gotovo"</string>
+</resources>
diff --git a/common/res/values-hu/strings.xml b/common/res/values-hu/strings.xml
new file mode 100644
index 00000000..c7edacc5
--- /dev/null
+++ b/common/res/values-hu/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Kész"</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..2832c576
--- /dev/null
+++ b/common/res/values-hy-rAM/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-in/strings.xml b/common/res/values-in/strings.xml
new file mode 100644
index 00000000..315e2eac
--- /dev/null
+++ b/common/res/values-in/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..a2d8da79
--- /dev/null
+++ b/common/res/values-is-rIS/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-it/strings.xml b/common/res/values-it/strings.xml
new file mode 100644
index 00000000..ba1ecc42
--- /dev/null
+++ b/common/res/values-it/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Fine"</string>
+</resources>
diff --git a/common/res/values-iw/strings.xml b/common/res/values-iw/strings.xml
new file mode 100644
index 00000000..106e5453
--- /dev/null
+++ b/common/res/values-iw/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-ja/strings.xml b/common/res/values-ja/strings.xml
new file mode 100644
index 00000000..9cf0ba31
--- /dev/null
+++ b/common/res/values-ja/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..d7297b9d
--- /dev/null
+++ b/common/res/values-ka-rGE/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..9994dc20
--- /dev/null
+++ b/common/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..f12663fb
--- /dev/null
+++ b/common/res/values-km-rKH/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..589ff1be
--- /dev/null
+++ b/common/res/values-kn-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-ko/strings.xml b/common/res/values-ko/strings.xml
new file mode 100644
index 00000000..e2e47fa4
--- /dev/null
+++ b/common/res/values-ko/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..3397fc32
--- /dev/null
+++ b/common/res/values-ky-rKG/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..88653b54
--- /dev/null
+++ b/common/res/values-lo-rLA/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-lt/strings.xml b/common/res/values-lt/strings.xml
new file mode 100644
index 00000000..6f51b3fc
--- /dev/null
+++ b/common/res/values-lt/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Atlikta"</string>
+</resources>
diff --git a/common/res/values-lv/strings.xml b/common/res/values-lv/strings.xml
new file mode 100644
index 00000000..8660efbd
--- /dev/null
+++ b/common/res/values-lv/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Gatavs"</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..a8d42c3a
--- /dev/null
+++ b/common/res/values-mk-rMK/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..81e9a8c6
--- /dev/null
+++ b/common/res/values-ml-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..ac4435f3
--- /dev/null
+++ b/common/res/values-mn-rMN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..82edcb03
--- /dev/null
+++ b/common/res/values-mr-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..315e2eac
--- /dev/null
+++ b/common/res/values-ms-rMY/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..a7faa7d9
--- /dev/null
+++ b/common/res/values-my-rMM/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-nb/strings.xml b/common/res/values-nb/strings.xml
new file mode 100644
index 00000000..3ff3ede1
--- /dev/null
+++ b/common/res/values-nb/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Ferdig"</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..4a08d5ef
--- /dev/null
+++ b/common/res/values-ne-rNP/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-nl/strings.xml b/common/res/values-nl/strings.xml
new file mode 100644
index 00000000..8756e624
--- /dev/null
+++ b/common/res/values-nl/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Gereed"</string>
+</resources>
diff --git a/common/res/values-pl/strings.xml b/common/res/values-pl/strings.xml
new file mode 100644
index 00000000..97beca37
--- /dev/null
+++ b/common/res/values-pl/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Gotowe"</string>
+</resources>
diff --git a/common/res/values-pt-rPT/strings.xml b/common/res/values-pt-rPT/strings.xml
new file mode 100644
index 00000000..a967a341
--- /dev/null
+++ b/common/res/values-pt-rPT/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Concluído"</string>
+</resources>
diff --git a/common/res/values-pt/strings.xml b/common/res/values-pt/strings.xml
new file mode 100644
index 00000000..a967a341
--- /dev/null
+++ b/common/res/values-pt/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Concluído"</string>
+</resources>
diff --git a/common/res/values-ro/strings.xml b/common/res/values-ro/strings.xml
new file mode 100644
index 00000000..2cbda306
--- /dev/null
+++ b/common/res/values-ro/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Terminat"</string>
+</resources>
diff --git a/common/res/values-ru/strings.xml b/common/res/values-ru/strings.xml
new file mode 100644
index 00000000..a8d42c3a
--- /dev/null
+++ b/common/res/values-ru/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..6293bbec
--- /dev/null
+++ b/common/res/values-si-rLK/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-sk/strings.xml b/common/res/values-sk/strings.xml
new file mode 100644
index 00000000..6bc7a34d
--- /dev/null
+++ b/common/res/values-sk/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Hotovo"</string>
+</resources>
diff --git a/common/res/values-sl/strings.xml b/common/res/values-sl/strings.xml
new file mode 100644
index 00000000..29c414ac
--- /dev/null
+++ b/common/res/values-sl/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Končano"</string>
+</resources>
diff --git a/common/res/values-sr/strings.xml b/common/res/values-sr/strings.xml
new file mode 100644
index 00000000..a8d42c3a
--- /dev/null
+++ b/common/res/values-sr/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-sv/strings.xml b/common/res/values-sv/strings.xml
new file mode 100644
index 00000000..ded93590
--- /dev/null
+++ b/common/res/values-sv/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Klar"</string>
+</resources>
diff --git a/common/res/values-sw/strings.xml b/common/res/values-sw/strings.xml
new file mode 100644
index 00000000..1cce7469
--- /dev/null
+++ b/common/res/values-sw/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Nimemaliza"</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..df4ce9ab
--- /dev/null
+++ b/common/res/values-ta-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..527f9e02
--- /dev/null
+++ b/common/res/values-te-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-th/strings.xml b/common/res/values-th/strings.xml
new file mode 100644
index 00000000..ca4158ef
--- /dev/null
+++ b/common/res/values-th/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-tl/strings.xml b/common/res/values-tl/strings.xml
new file mode 100644
index 00000000..4b53b66e
--- /dev/null
+++ b/common/res/values-tl/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Tapos Na"</string>
+</resources>
diff --git a/common/res/values-tr/strings.xml b/common/res/values-tr/strings.xml
new file mode 100644
index 00000000..34e0cb58
--- /dev/null
+++ b/common/res/values-tr/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Bitti"</string>
+</resources>
diff --git a/common/res/values-uk/strings.xml b/common/res/values-uk/strings.xml
new file mode 100644
index 00000000..a8d42c3a
--- /dev/null
+++ b/common/res/values-uk/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..87b1cec4
--- /dev/null
+++ b/common/res/values-ur-rPK/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</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..67468cec
--- /dev/null
+++ b/common/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-vi/strings.xml b/common/res/values-vi/strings.xml
new file mode 100644
index 00000000..756fb991
--- /dev/null
+++ b/common/res/values-vi/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Xong"</string>
+</resources>
diff --git a/common/res/values-zh-rCN/strings.xml b/common/res/values-zh-rCN/strings.xml
new file mode 100644
index 00000000..b8bd7736
--- /dev/null
+++ b/common/res/values-zh-rCN/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-zh-rHK/strings.xml b/common/res/values-zh-rHK/strings.xml
new file mode 100644
index 00000000..b8bd7736
--- /dev/null
+++ b/common/res/values-zh-rHK/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-zh-rTW/strings.xml b/common/res/values-zh-rTW/strings.xml
new file mode 100644
index 00000000..b8bd7736
--- /dev/null
+++ b/common/res/values-zh-rTW/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+</resources>
diff --git a/common/res/values-zu/strings.xml b/common/res/values-zu/strings.xml
new file mode 100644
index 00000000..91b5042c
--- /dev/null
+++ b/common/res/values-zu/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Kwenziwe"</string>
+</resources>
diff --git a/common/res/values/attrs.xml b/common/res/values/attrs.xml
new file mode 100644
index 00000000..fb23f358
--- /dev/null
+++ b/common/res/values/attrs.xml
@@ -0,0 +1,25 @@
+<?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="SetupGuidedStep">
+ <!-- Defines the background color of setup guidance background. -->
+ <attr name="setupCommonGuidanceBackground" format="reference" />
+ <!-- Defines the style of done button container. -->
+ <attr name="doneButtonContainerStyle" format="reference" />
+ </declare-styleable>
+</resources> \ No newline at end of file
diff --git a/common/res/values/colors.xml b/common/res/values/colors.xml
index 6e44b188..b6efb8ca 100644
--- a/common/res/values/colors.xml
+++ b/common/res/values/colors.xml
@@ -21,4 +21,5 @@
<color name="common_setup_action_background">#0374BF</color>
<color name="common_setup_done_container_background">#04549D</color>
<color name="common_setup_button_done_selected">#26FFFFFF</color>
+ <color name="common_setup_input_description">#EEEEEE</color>
</resources>
diff --git a/common/res/values/dimens.xml b/common/res/values/dimens.xml
index aded2876..4d8286cd 100644
--- a/common/res/values/dimens.xml
+++ b/common/res/values/dimens.xml
@@ -31,7 +31,12 @@
<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>
<!-- Transition -->
- <dimen name="setup_fragment_transition_distance">80dp</dimen>
+ <dimen name="setup_fragment_transition_long_distance">80dp</dimen>
+ <dimen name="setup_fragment_transition_short_distance">48dp</dimen>
+ <!-- This values should be less then or equal to -1 * setup_fragment_transition_long_distance. -->
+ <dimen name="setup_common_guidance_background_margin_start">-100dp</dimen>
</resources>
diff --git a/common/res/values/strings.xml b/common/res/values/strings.xml
index 25782443..f337af42 100644
--- a/common/res/values/strings.xml
+++ b/common/res/values/strings.xml
@@ -16,6 +16,5 @@
-->
<resources>
- <!-- TODO: Change translatable to true once implemented. -->
- <string name="action_text_done" translatable="false">Done</string>
+ <string name="action_text_done">Done</string>
</resources>
diff --git a/common/res/values/styles.xml b/common/res/values/styles.xml
index 7d9575f0..3c3c71c9 100644
--- a/common/res/values/styles.xml
+++ b/common/res/values/styles.xml
@@ -23,49 +23,40 @@
<style name="Widget.Setup.GuidanceTitleStyle" parent="Widget.Leanback.GuidanceTitleStyle">
<item name="android:layout_alignParentStart">true</item>
+ <item name="android:layout_below">@id/guidance_breadcrumb</item>
<item name="android:layout_centerVertical">false</item>
- <item name="android:layout_marginTop">181dp</item>
+ <item name="android:layout_marginTop">4dp</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:gravity">start</item>
<item name="android:lineSpacingExtra">0sp</item>
<item name="android:lineSpacingMultiplier">1.13778</item>
+ <item name="android:textAlignment">viewStart</item>
<item name="android:textColor">#EEEEEE</item>
<item name="android:textSize">34sp</item>
</style>
<style name="Widget.Setup.GuidanceDescriptionStyle" parent="Widget.Leanback.GuidanceDescriptionStyle">
+ <item name="android:layout_alignParentStart">true</item>
<item name="android:layout_marginTop">4dp</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:gravity">start</item>
<item name="android:lineSpacingExtra">0sp</item>
<item name="android:lineSpacingMultiplier">1.465</item>
<item name="android:maxLines">10</item>
+ <item name="android:textAlignment">viewStart</item>
<item name="android:textColor">#CCEEEEEE</item>
</style>
<style name="Widget.Setup.GuidanceBreadcrumbStyle" parent="Widget.Leanback.GuidanceBreadcrumbStyle">
- <item name="android:layout_marginBottom">4dp</item>
+ <item name="android:layout_alignParentStart">true</item>
+ <item name="android:layout_above">@null</item>
+ <item name="android:layout_marginTop">156dp</item>
<item name="android:fontFamily">sans-serif-condensed</item>
+ <item name="android:textAlignment">viewStart</item>
<item name="android:textColor">#B3EEEEEE</item>
<item name="android:textSize">16sp</item>
</style>
- <style name="Widget.Setup.GuidedActionsContainerStyle" parent="Widget.Leanback.GuidedActionsContainerStyle">
- <item name="android:layout_width">match_parent</item>
- <item name="android:background">@color/common_setup_action_background</item>
- <item name="android:elevation">0dp</item>
- <item name="android:transitionName">guidedActionsBackgroundTransition</item>
- </style>
-
- <style name="Widget.Setup.GuidedActionsSelectorStyle" parent="Widget.Leanback.GuidedActionsSelectorStyle">
- <item name="android:layout_centerVertical">false</item>
- <item name="android:layout_marginStart">@dimen/setup_guidedactions_selector_margin_start</item>
- <item name="android:layout_marginEnd">@dimen/setup_guidedactions_selector_margin_end</item>
- <item name="android:layout_marginTop">@dimen/setup_guidedactions_selector_margin_top</item>
- <item name="android:background">@drawable/setup_selector_background</item>
- <item name="android:elevation">0dp</item>
- </style>
-
<style name="Widget.Setup.GuidedActionsListStyle" parent="Widget.Leanback.GuidedActionsListStyle">
<item name="android:elevation">0dp</item>
</style>
@@ -83,6 +74,10 @@
<item name="android:visibility">gone</item>
</style>
+ <style name="Widget.Setup.GuidedActionItemIconStyle" parent="Widget.Leanback.GuidedActionItemIconStyle">
+ <item name="android:layout_marginEnd">@dimen/setup_guidedactions_item_delimiter_padding</item>
+ </style>
+
<style name="Widget.Setup.GuidedActionItemTitleStyle" parent="Widget.Leanback.GuidedActionItemTitleStyle">
<item name="android:layout_height">18dp</item>
<item name="android:fontFamily">sans-serif</item>
@@ -94,7 +89,11 @@
<item name="android:layout_height">17dp</item>
<item name="android:alpha">0.5</item>
<item name="android:fontFamily">sans-serif</item>
- <item name="android:textColor">#EEEEEE</item>
+ <item name="android:textColor">@color/common_setup_input_description</item>
<item name="android:textSize">12sp</item>
</style>
+
+ <style name="DoneButtonContainerStyle">
+ <item name="android:background">@color/common_setup_done_container_background</item>
+ </style>
</resources>
diff --git a/common/res/values/themes.xml b/common/res/values/themes.xml
index 6d7ac0a5..598ae9a5 100644
--- a/common/res/values/themes.xml
+++ b/common/res/values/themes.xml
@@ -19,16 +19,22 @@
<style name="Theme.Setup.GuidedStep" parent="Theme.Leanback.GuidedStep">
<item name="android:windowBackground">@color/common_tv_background</item>
<item name="android:windowEnterTransition">@null</item>
+ <item name="guidanceBreadcrumbStyle">@style/Widget.Setup.GuidanceBreadcrumbStyle</item>
<item name="guidanceContainerStyle">@style/Widget.Setup.GuidanceContainerStyle</item>
- <item name="guidanceTitleStyle">@style/Widget.Setup.GuidanceTitleStyle</item>
<item name="guidanceDescriptionStyle">@style/Widget.Setup.GuidanceDescriptionStyle</item>
- <item name="guidanceBreadcrumbStyle">@style/Widget.Setup.GuidanceBreadcrumbStyle</item>
- <item name="guidedActionsContainerStyle">@style/Widget.Setup.GuidedActionsContainerStyle</item>
- <item name="guidedActionsSelectorStyle">@style/Widget.Setup.GuidedActionsSelectorStyle</item>
- <item name="guidedActionsListStyle">@style/Widget.Setup.GuidedActionsListStyle</item>
+ <item name="guidanceTitleStyle">@style/Widget.Setup.GuidanceTitleStyle</item>
+ <item name="guidedActionContentWidthWeight">@string/setup_guidedactions_width_weight</item>
<item name="guidedActionItemContainerStyle">@style/Widget.Setup.GuidedActionItemContainerStyle</item>
<item name="guidedActionItemCheckmarkStyle">@style/Widget.Setup.GuidedActionItemCheckmarkStyle</item>
+ <item name="guidedActionItemIconStyle">@style/Widget.Setup.GuidedActionItemIconStyle</item>
<item name="guidedActionItemTitleStyle">@style/Widget.Setup.GuidedActionItemTitleStyle</item>
<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>
+ <item name="doneButtonContainerStyle">@style/DoneButtonContainerStyle</item>
</style>
</resources>
diff --git a/res/animator/onboarding_welcome_description_enter.xml b/common/res_leanback/animator/lb_onboarding_description_enter.xml
index 5f26cdd1..5f26cdd1 100644
--- a/res/animator/onboarding_welcome_description_enter.xml
+++ b/common/res_leanback/animator/lb_onboarding_description_enter.xml
diff --git a/res/animator/onboarding_welcome_logo_enter.xml b/common/res_leanback/animator/lb_onboarding_logo_enter.xml
index 76a4609a..76a4609a 100644
--- a/res/animator/onboarding_welcome_logo_enter.xml
+++ b/common/res_leanback/animator/lb_onboarding_logo_enter.xml
diff --git a/res/animator/onboarding_welcome_logo_exit.xml b/common/res_leanback/animator/lb_onboarding_logo_exit.xml
index c22b763e..40b618e6 100644
--- a/res/animator/onboarding_welcome_logo_exit.xml
+++ b/common/res_leanback/animator/lb_onboarding_logo_exit.xml
@@ -20,6 +20,6 @@
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0"
- android:duration="333"
+ android:duration="666"
android:interpolator="@android:interpolator/fast_out_slow_in" />
</set>
diff --git a/res/animator/onboarding_welcome_page_indicator_enter.xml b/common/res_leanback/animator/lb_onboarding_page_indicator_enter.xml
index e9fc46ef..e9fc46ef 100644
--- a/res/animator/onboarding_welcome_page_indicator_enter.xml
+++ b/common/res_leanback/animator/lb_onboarding_page_indicator_enter.xml
diff --git a/common/res_leanback/animator/lb_onboarding_page_indicator_fade_in.xml b/common/res_leanback/animator/lb_onboarding_page_indicator_fade_in.xml
new file mode 100644
index 00000000..f21fc23b
--- /dev/null
+++ b/common/res_leanback/animator/lb_onboarding_page_indicator_fade_in.xml
@@ -0,0 +1,25 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/common/res_leanback/animator/lb_onboarding_page_indicator_fade_out.xml b/common/res_leanback/animator/lb_onboarding_page_indicator_fade_out.xml
new file mode 100644
index 00000000..4c69c5d0
--- /dev/null
+++ b/common/res_leanback/animator/lb_onboarding_page_indicator_fade_out.xml
@@ -0,0 +1,25 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/common/res_leanback/animator/lb_onboarding_start_button_fade_in.xml b/common/res_leanback/animator/lb_onboarding_start_button_fade_in.xml
new file mode 100644
index 00000000..4125622b
--- /dev/null
+++ b/common/res_leanback/animator/lb_onboarding_start_button_fade_in.xml
@@ -0,0 +1,31 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="16dp"
+ android:valueTo="0dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/common/res_leanback/animator/lb_onboarding_start_button_fade_out.xml b/common/res_leanback/animator/lb_onboarding_start_button_fade_out.xml
new file mode 100644
index 00000000..26590ecd
--- /dev/null
+++ b/common/res_leanback/animator/lb_onboarding_start_button_fade_out.xml
@@ -0,0 +1,31 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="0dp"
+ android:valueTo="16dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/res/animator/onboarding_welcome_title_enter.xml b/common/res_leanback/animator/lb_onboarding_title_enter.xml
index 5f26cdd1..5f26cdd1 100644
--- a/res/animator/onboarding_welcome_title_enter.xml
+++ b/common/res_leanback/animator/lb_onboarding_title_enter.xml
diff --git a/common/res_leanback/animator/lb_page_indicator_dot_hide.xml b/common/res_leanback/animator/lb_page_indicator_dot_hide.xml
new file mode 100644
index 00000000..fdd60342
--- /dev/null
+++ b/common/res_leanback/animator/lb_page_indicator_dot_hide.xml
@@ -0,0 +1,37 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:duration="167"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="diameter"
+ android:valueFrom="36dp"
+ android:valueTo="10dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="-16dp"
+ android:valueTo="0dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/common/res_leanback/animator/lb_page_indicator_dot_show.xml b/common/res_leanback/animator/lb_page_indicator_dot_show.xml
new file mode 100644
index 00000000..392fb2c6
--- /dev/null
+++ b/common/res_leanback/animator/lb_page_indicator_dot_show.xml
@@ -0,0 +1,37 @@
+<?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">
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:duration="167"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="diameter"
+ android:valueFrom="10dp"
+ android:valueTo="36dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="-16dp"
+ android:valueTo="0dp"
+ android:duration="417"
+ android:interpolator="@android:anim/decelerate_interpolator" />
+</set>
diff --git a/res/drawable-xhdpi/ic_nav_arrow.png b/common/res_leanback/drawable-xhdpi/lb_ic_nav_arrow.png
index 04578a75..04578a75 100644
--- a/res/drawable-xhdpi/ic_nav_arrow.png
+++ b/common/res_leanback/drawable-xhdpi/lb_ic_nav_arrow.png
Binary files differ
diff --git a/res/values-ldrtl/integers.xml b/common/res_leanback/drawable/lb_onboarding_start_button_background.xml
index edac42a6..57c31387 100644
--- a/res/values-ldrtl/integers.xml
+++ b/common/res_leanback/drawable/lb_onboarding_start_button_background.xml
@@ -14,8 +14,11 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-
-<resources>
- <integer name="fullscreen_dialog_enter_translation_x">-200</integer>
- <integer name="fullscreen_dialog_exit_translation_x">200</integer>
-</resources> \ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#EEEEEE"/>
+ <corners android:radius="2dp" />
+ </shape>
+ </item>
+</selector>
diff --git a/common/res_leanback/layout/lb_onboarding_fragment.xml b/common/res_leanback/layout/lb_onboarding_fragment.xml
new file mode 100644
index 00000000..61cb93bd
--- /dev/null
+++ b/common/res_leanback/layout/lb_onboarding_fragment.xml
@@ -0,0 +1,120 @@
+<?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.
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/onboarding_fragment_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <FrameLayout
+ android:id="@+id/background_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <LinearLayout
+ android:id="@+id/page_container"
+ android:layout_width="@dimen/lb_onboarding_content_width"
+ android:layout_height="@dimen/lb_onboarding_header_height"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="@dimen/lb_onboarding_header_margin_top"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.5"
+ android:layout_marginBottom="3dp"
+ android:fontFamily="sans-serif-light"
+ android:gravity="center"
+ android:textColor="#EEEEEE"
+ android:textSize="34sp"
+ android:lineSpacingExtra="14sp"/>
+ <TextView
+ android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.5"
+ android:layout_marginTop="3dp"
+ android:fontFamily="sans-serif-light"
+ android:gravity="center"
+ android:textColor="#B3EEEEEE"
+ android:textSize="14sp"
+ android:lineSpacingExtra="10sp" />
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/content_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/page_indicator"
+ android:layout_below="@id/page_container"
+ android:layout_centerHorizontal="true"
+ android:visibility="gone" />
+
+ <com.google.android.tv.common.ui.setup.leanback.PagingIndicator
+ android:id="@id/page_indicator"
+ android:layout_width="@dimen/lb_onboarding_content_width"
+ android:layout_height="@dimen/lb_onboarding_navigation_height"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="58dp"
+ android:focusable="true"
+ android:contentDescription="@string/lb_onboarding_accessibility_next"
+ android:visibility="gone" />
+
+ <Button
+ android:id="@+id/button_start"
+ android:layout_width="wrap_content"
+ android:layout_height="36dp"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="62dp"
+ android:alpha="0.0"
+ android:background="@drawable/lb_onboarding_start_button_background"
+ android:elevation="1.5dp"
+ android:fontFamily="sans-serif"
+ android:gravity="center_vertical"
+ android:paddingEnd="24dp"
+ android:paddingStart="24dp"
+ android:stateListAnimator="@null"
+ android:text="@string/lb_onboarding_get_started"
+ android:textAllCaps="true"
+ android:textColor="#014269"
+ android:textSize="16sp"
+ android:visibility="gone"/>
+
+ <FrameLayout
+ android:id="@+id/foreground_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <ImageView
+ android:id="@+id/logo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:contentDescription="@null" />
+
+</RelativeLayout>
diff --git a/common/res_leanback/values-af/strings.xml b/common/res_leanback/values-af/strings.xml
new file mode 100644
index 00000000..d683758b
--- /dev/null
+++ b/common/res_leanback/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"BEGIN HIER"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Volgende"</string>
+</resources>
diff --git a/common/res_leanback/values-am/strings.xml b/common/res_leanback/values-am/strings.xml
new file mode 100644
index 00000000..e70214dc
--- /dev/null
+++ b/common/res_leanback/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ይጀምሩ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ቀጣይ"</string>
+</resources>
diff --git a/common/res_leanback/values-ar/strings.xml b/common/res_leanback/values-ar/strings.xml
new file mode 100644
index 00000000..f7ba5716
--- /dev/null
+++ b/common/res_leanback/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"البدء"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"التالية"</string>
+</resources>
diff --git a/common/res_leanback/values-az-rAZ/strings.xml b/common/res_leanback/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..2293accf
--- /dev/null
+++ b/common/res_leanback/values-az-rAZ/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"BAŞLAYIN"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Növbəti"</string>
+</resources>
diff --git a/common/res_leanback/values-bg/strings.xml b/common/res_leanback/values-bg/strings.xml
new file mode 100644
index 00000000..a6c3cc03
--- /dev/null
+++ b/common/res_leanback/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ПЪРВИ СТЪПКИ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Напред"</string>
+</resources>
diff --git a/common/res_leanback/values-bn-rBD/strings.xml b/common/res_leanback/values-bn-rBD/strings.xml
new file mode 100644
index 00000000..31b7a515
--- /dev/null
+++ b/common/res_leanback/values-bn-rBD/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"শুরু করা যাক"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"পরবর্তী"</string>
+</resources>
diff --git a/common/res_leanback/values-ca/strings.xml b/common/res_leanback/values-ca/strings.xml
new file mode 100644
index 00000000..8de1bb62
--- /dev/null
+++ b/common/res_leanback/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"COMENÇA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Següent"</string>
+</resources>
diff --git a/common/res_leanback/values-cs/strings.xml b/common/res_leanback/values-cs/strings.xml
new file mode 100644
index 00000000..231f92e7
--- /dev/null
+++ b/common/res_leanback/values-cs/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ZAČÍNÁME"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Další"</string>
+</resources>
diff --git a/common/res_leanback/values-da/strings.xml b/common/res_leanback/values-da/strings.xml
new file mode 100644
index 00000000..25375bc2
--- /dev/null
+++ b/common/res_leanback/values-da/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"KOM GODT I GANG"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Næste"</string>
+</resources>
diff --git a/common/res_leanback/values-de/strings.xml b/common/res_leanback/values-de/strings.xml
new file mode 100644
index 00000000..0f492e2f
--- /dev/null
+++ b/common/res_leanback/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"JETZT STARTEN"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Weiter"</string>
+</resources>
diff --git a/common/res_leanback/values-el/strings.xml b/common/res_leanback/values-el/strings.xml
new file mode 100644
index 00000000..1df4b216
--- /dev/null
+++ b/common/res_leanback/values-el/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ΕΝΑΡΞΗ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Επόμενο"</string>
+</resources>
diff --git a/common/res_leanback/values-en-rAU/strings.xml b/common/res_leanback/values-en-rAU/strings.xml
new file mode 100644
index 00000000..d6995936
--- /dev/null
+++ b/common/res_leanback/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"GET STARTED"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Next"</string>
+</resources>
diff --git a/common/res_leanback/values-en-rGB/strings.xml b/common/res_leanback/values-en-rGB/strings.xml
new file mode 100644
index 00000000..d6995936
--- /dev/null
+++ b/common/res_leanback/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"GET STARTED"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Next"</string>
+</resources>
diff --git a/common/res_leanback/values-en-rIN/strings.xml b/common/res_leanback/values-en-rIN/strings.xml
new file mode 100644
index 00000000..d6995936
--- /dev/null
+++ b/common/res_leanback/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"GET STARTED"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Next"</string>
+</resources>
diff --git a/common/res_leanback/values-es-rUS/strings.xml b/common/res_leanback/values-es-rUS/strings.xml
new file mode 100644
index 00000000..0a1bb255
--- /dev/null
+++ b/common/res_leanback/values-es-rUS/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"COMENZAR"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Siguiente"</string>
+</resources>
diff --git a/common/res_leanback/values-es/strings.xml b/common/res_leanback/values-es/strings.xml
new file mode 100644
index 00000000..0a17e9f2
--- /dev/null
+++ b/common/res_leanback/values-es/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"EMPEZAR"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Siguiente"</string>
+</resources>
diff --git a/common/res_leanback/values-et-rEE/strings.xml b/common/res_leanback/values-et-rEE/strings.xml
new file mode 100644
index 00000000..f74e1773
--- /dev/null
+++ b/common/res_leanback/values-et-rEE/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ALUSTAGE"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Järgmine"</string>
+</resources>
diff --git a/common/res_leanback/values-eu-rES/strings.xml b/common/res_leanback/values-eu-rES/strings.xml
new file mode 100644
index 00000000..25dadb75
--- /dev/null
+++ b/common/res_leanback/values-eu-rES/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"LEHEN URRATSAK"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Hurrengoa"</string>
+</resources>
diff --git a/common/res_leanback/values-fa/strings.xml b/common/res_leanback/values-fa/strings.xml
new file mode 100644
index 00000000..21b1f969
--- /dev/null
+++ b/common/res_leanback/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"شروع به‌ کار"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"بعدی"</string>
+</resources>
diff --git a/common/res_leanback/values-fi/strings.xml b/common/res_leanback/values-fi/strings.xml
new file mode 100644
index 00000000..c8474c4a
--- /dev/null
+++ b/common/res_leanback/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ALOITA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Seuraava"</string>
+</resources>
diff --git a/common/res_leanback/values-fr-rCA/strings.xml b/common/res_leanback/values-fr-rCA/strings.xml
new file mode 100644
index 00000000..9f7933bc
--- /dev/null
+++ b/common/res_leanback/values-fr-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"COMMENCER"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Suivant"</string>
+</resources>
diff --git a/common/res_leanback/values-fr/strings.xml b/common/res_leanback/values-fr/strings.xml
new file mode 100644
index 00000000..9f7933bc
--- /dev/null
+++ b/common/res_leanback/values-fr/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"COMMENCER"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Suivant"</string>
+</resources>
diff --git a/common/res_leanback/values-gl-rES/strings.xml b/common/res_leanback/values-gl-rES/strings.xml
new file mode 100644
index 00000000..8fa1ed80
--- /dev/null
+++ b/common/res_leanback/values-gl-rES/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"COMEZAR"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Seguinte"</string>
+</resources>
diff --git a/common/res_leanback/values-hi/strings.xml b/common/res_leanback/values-hi/strings.xml
new file mode 100644
index 00000000..c966d80d
--- /dev/null
+++ b/common/res_leanback/values-hi/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"प्रारंभ करें"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"अगला"</string>
+</resources>
diff --git a/common/res_leanback/values-hr/strings.xml b/common/res_leanback/values-hr/strings.xml
new file mode 100644
index 00000000..31676fcf
--- /dev/null
+++ b/common/res_leanback/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"POČETAK"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Dalje"</string>
+</resources>
diff --git a/common/res_leanback/values-hu/strings.xml b/common/res_leanback/values-hu/strings.xml
new file mode 100644
index 00000000..cfd19a8d
--- /dev/null
+++ b/common/res_leanback/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"KEZDŐ LÉPÉSEK"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Következő"</string>
+</resources>
diff --git a/common/res_leanback/values-hy-rAM/strings.xml b/common/res_leanback/values-hy-rAM/strings.xml
new file mode 100644
index 00000000..7b99acad
--- /dev/null
+++ b/common/res_leanback/values-hy-rAM/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ՍԿՍԵԼ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Հաջորդը"</string>
+</resources>
diff --git a/common/res_leanback/values-in/strings.xml b/common/res_leanback/values-in/strings.xml
new file mode 100644
index 00000000..940a5060
--- /dev/null
+++ b/common/res_leanback/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"MULAI"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Berikutnya"</string>
+</resources>
diff --git a/common/res_leanback/values-is-rIS/strings.xml b/common/res_leanback/values-is-rIS/strings.xml
new file mode 100644
index 00000000..0cbf8935
--- /dev/null
+++ b/common/res_leanback/values-is-rIS/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"HEFJAST HANDA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Áfram"</string>
+</resources>
diff --git a/common/res_leanback/values-it/strings.xml b/common/res_leanback/values-it/strings.xml
new file mode 100644
index 00000000..68681952
--- /dev/null
+++ b/common/res_leanback/values-it/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"INIZIA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Avanti"</string>
+</resources>
diff --git a/common/res_leanback/values-iw/strings.xml b/common/res_leanback/values-iw/strings.xml
new file mode 100644
index 00000000..1df4245e
--- /dev/null
+++ b/common/res_leanback/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"התחל"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"הבא"</string>
+</resources>
diff --git a/common/res_leanback/values-ja/strings.xml b/common/res_leanback/values-ja/strings.xml
new file mode 100644
index 00000000..67183065
--- /dev/null
+++ b/common/res_leanback/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"使ってみる"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"次へ"</string>
+</resources>
diff --git a/common/res_leanback/values-ka-rGE/strings.xml b/common/res_leanback/values-ka-rGE/strings.xml
new file mode 100644
index 00000000..d5238fc7
--- /dev/null
+++ b/common/res_leanback/values-ka-rGE/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"დაწყება"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"შემდეგი"</string>
+</resources>
diff --git a/common/res_leanback/values-kk-rKZ/strings.xml b/common/res_leanback/values-kk-rKZ/strings.xml
new file mode 100644
index 00000000..bf67ae09
--- /dev/null
+++ b/common/res_leanback/values-kk-rKZ/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ІСКЕ КІРІСУ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Келесі"</string>
+</resources>
diff --git a/common/res_leanback/values-km-rKH/strings.xml b/common/res_leanback/values-km-rKH/strings.xml
new file mode 100644
index 00000000..39b3a3c4
--- /dev/null
+++ b/common/res_leanback/values-km-rKH/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ចាប់ផ្ដើម"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"បន្ទាប់"</string>
+</resources>
diff --git a/common/res_leanback/values-kn-rIN/strings.xml b/common/res_leanback/values-kn-rIN/strings.xml
new file mode 100644
index 00000000..8113d1ac
--- /dev/null
+++ b/common/res_leanback/values-kn-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ಪ್ರಾರಂಭಿಸು"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ಮುಂದೆ"</string>
+</resources>
diff --git a/common/res_leanback/values-ko/strings.xml b/common/res_leanback/values-ko/strings.xml
new file mode 100644
index 00000000..b64e2d96
--- /dev/null
+++ b/common/res_leanback/values-ko/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"시작하기"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"다음"</string>
+</resources>
diff --git a/common/res_leanback/values-ky-rKG/strings.xml b/common/res_leanback/values-ky-rKG/strings.xml
new file mode 100644
index 00000000..d789e873
--- /dev/null
+++ b/common/res_leanback/values-ky-rKG/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"БАШТАДЫК"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Кийинки"</string>
+</resources>
diff --git a/common/res_leanback/values-lo-rLA/strings.xml b/common/res_leanback/values-lo-rLA/strings.xml
new file mode 100644
index 00000000..de4d7ead
--- /dev/null
+++ b/common/res_leanback/values-lo-rLA/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ເລີ່ມຕົ້ນນຳໃຊ້"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ຕໍ່​ໄປ"</string>
+</resources>
diff --git a/common/res_leanback/values-lt/strings.xml b/common/res_leanback/values-lt/strings.xml
new file mode 100644
index 00000000..2938c289
--- /dev/null
+++ b/common/res_leanback/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"PRADĖTI"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Kitas"</string>
+</resources>
diff --git a/common/res_leanback/values-lv/strings.xml b/common/res_leanback/values-lv/strings.xml
new file mode 100644
index 00000000..a65b8919
--- /dev/null
+++ b/common/res_leanback/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"SĀKT DARBU"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Tālāk"</string>
+</resources>
diff --git a/common/res_leanback/values-mk-rMK/strings.xml b/common/res_leanback/values-mk-rMK/strings.xml
new file mode 100644
index 00000000..a7df3e64
--- /dev/null
+++ b/common/res_leanback/values-mk-rMK/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ЗАПОЧНИ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Следно"</string>
+</resources>
diff --git a/common/res_leanback/values-ml-rIN/strings.xml b/common/res_leanback/values-ml-rIN/strings.xml
new file mode 100644
index 00000000..dc051da9
--- /dev/null
+++ b/common/res_leanback/values-ml-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ആരംഭിക്കുക"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"അടുത്തത്"</string>
+</resources>
diff --git a/common/res_leanback/values-mn-rMN/strings.xml b/common/res_leanback/values-mn-rMN/strings.xml
new file mode 100644
index 00000000..eb4b74bd
--- /dev/null
+++ b/common/res_leanback/values-mn-rMN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ЭХЭЛЦГЭЭЕ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Дараах"</string>
+</resources>
diff --git a/common/res_leanback/values-mr-rIN/strings.xml b/common/res_leanback/values-mr-rIN/strings.xml
new file mode 100644
index 00000000..293aa75b
--- /dev/null
+++ b/common/res_leanback/values-mr-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"प्रारंभ करा"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"पुढील"</string>
+</resources>
diff --git a/common/res_leanback/values-ms-rMY/strings.xml b/common/res_leanback/values-ms-rMY/strings.xml
new file mode 100644
index 00000000..08e6a0a6
--- /dev/null
+++ b/common/res_leanback/values-ms-rMY/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"MULAKAN"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Seterusnya"</string>
+</resources>
diff --git a/common/res_leanback/values-my-rMM/strings.xml b/common/res_leanback/values-my-rMM/strings.xml
new file mode 100644
index 00000000..37ca64e0
--- /dev/null
+++ b/common/res_leanback/values-my-rMM/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"စတင်ပါ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ရှေ့သို့"</string>
+</resources>
diff --git a/common/res_leanback/values-nb/strings.xml b/common/res_leanback/values-nb/strings.xml
new file mode 100644
index 00000000..f79a3fb5
--- /dev/null
+++ b/common/res_leanback/values-nb/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"KOM I GANG"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Neste"</string>
+</resources>
diff --git a/common/res_leanback/values-ne-rNP/strings.xml b/common/res_leanback/values-ne-rNP/strings.xml
new file mode 100644
index 00000000..0b479416
--- /dev/null
+++ b/common/res_leanback/values-ne-rNP/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"सुरू गरौँ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"अर्को"</string>
+</resources>
diff --git a/common/res_leanback/values-nl/strings.xml b/common/res_leanback/values-nl/strings.xml
new file mode 100644
index 00000000..98580f53
--- /dev/null
+++ b/common/res_leanback/values-nl/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"AAN DE SLAG"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Volgende"</string>
+</resources>
diff --git a/common/res_leanback/values-pl/strings.xml b/common/res_leanback/values-pl/strings.xml
new file mode 100644
index 00000000..59482365
--- /dev/null
+++ b/common/res_leanback/values-pl/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"WYPRÓBUJ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Dalej"</string>
+</resources>
diff --git a/common/res_leanback/values-pt-rPT/strings.xml b/common/res_leanback/values-pt-rPT/strings.xml
new file mode 100644
index 00000000..1529e3aa
--- /dev/null
+++ b/common/res_leanback/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"INICIAR"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Seguinte"</string>
+</resources>
diff --git a/common/res_leanback/values-pt/strings.xml b/common/res_leanback/values-pt/strings.xml
new file mode 100644
index 00000000..596351c5
--- /dev/null
+++ b/common/res_leanback/values-pt/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"PRIMEIROS PASSOS"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Próxima"</string>
+</resources>
diff --git a/common/res_leanback/values-ro/strings.xml b/common/res_leanback/values-ro/strings.xml
new file mode 100644
index 00000000..0a993f46
--- /dev/null
+++ b/common/res_leanback/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ÎNCEPEȚI"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Înainte"</string>
+</resources>
diff --git a/common/res_leanback/values-ru/strings.xml b/common/res_leanback/values-ru/strings.xml
new file mode 100644
index 00000000..1c07da67
--- /dev/null
+++ b/common/res_leanback/values-ru/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"НАЧАТЬ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Далее"</string>
+</resources>
diff --git a/common/res_leanback/values-si-rLK/strings.xml b/common/res_leanback/values-si-rLK/strings.xml
new file mode 100644
index 00000000..78dee7c6
--- /dev/null
+++ b/common/res_leanback/values-si-rLK/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ආරම්භ කරන්න"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ඊළඟ"</string>
+</resources>
diff --git a/common/res_leanback/values-sk/strings.xml b/common/res_leanback/values-sk/strings.xml
new file mode 100644
index 00000000..998585dc
--- /dev/null
+++ b/common/res_leanback/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ZAČÍNAME"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Ďalej"</string>
+</resources>
diff --git a/common/res_leanback/values-sl/strings.xml b/common/res_leanback/values-sl/strings.xml
new file mode 100644
index 00000000..ec5e4719
--- /dev/null
+++ b/common/res_leanback/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ZAČNITE"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Naprej"</string>
+</resources>
diff --git a/common/res_leanback/values-sr/strings.xml b/common/res_leanback/values-sr/strings.xml
new file mode 100644
index 00000000..e65e0e56
--- /dev/null
+++ b/common/res_leanback/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ЗАПОЧНИТЕ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Следећа"</string>
+</resources>
diff --git a/common/res_leanback/values-sv/strings.xml b/common/res_leanback/values-sv/strings.xml
new file mode 100644
index 00000000..6866b1d2
--- /dev/null
+++ b/common/res_leanback/values-sv/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"KOM IGÅNG"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Nästa"</string>
+</resources>
diff --git a/common/res_leanback/values-sw/strings.xml b/common/res_leanback/values-sw/strings.xml
new file mode 100644
index 00000000..5f921c04
--- /dev/null
+++ b/common/res_leanback/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ANZA KUTUMIA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Inayofuata"</string>
+</resources>
diff --git a/common/res_leanback/values-ta-rIN/strings.xml b/common/res_leanback/values-ta-rIN/strings.xml
new file mode 100644
index 00000000..5b3c2749
--- /dev/null
+++ b/common/res_leanback/values-ta-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"தொடங்குக"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"அடுத்து"</string>
+</resources>
diff --git a/common/res_leanback/values-te-rIN/strings.xml b/common/res_leanback/values-te-rIN/strings.xml
new file mode 100644
index 00000000..dc1954d5
--- /dev/null
+++ b/common/res_leanback/values-te-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ప్రారంభించు"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"తదుపరి"</string>
+</resources>
diff --git a/common/res_leanback/values-th/strings.xml b/common/res_leanback/values-th/strings.xml
new file mode 100644
index 00000000..00e40d11
--- /dev/null
+++ b/common/res_leanback/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"เริ่มต้นใช้งาน"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"ถัดไป"</string>
+</resources>
diff --git a/common/res_leanback/values-tl/strings.xml b/common/res_leanback/values-tl/strings.xml
new file mode 100644
index 00000000..f4a93e7f
--- /dev/null
+++ b/common/res_leanback/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"MAGSIMULA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Susunod"</string>
+</resources>
diff --git a/common/res_leanback/values-tr/strings.xml b/common/res_leanback/values-tr/strings.xml
new file mode 100644
index 00000000..126fe3b5
--- /dev/null
+++ b/common/res_leanback/values-tr/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"BAŞLA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Sonraki"</string>
+</resources>
diff --git a/common/res_leanback/values-uk/strings.xml b/common/res_leanback/values-uk/strings.xml
new file mode 100644
index 00000000..61dd2034
--- /dev/null
+++ b/common/res_leanback/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"ПОЧАТИ"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Далі"</string>
+</resources>
diff --git a/common/res_leanback/values-ur-rPK/strings.xml b/common/res_leanback/values-ur-rPK/strings.xml
new file mode 100644
index 00000000..2a3299ff
--- /dev/null
+++ b/common/res_leanback/values-ur-rPK/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"شروع کریں"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"اگلا"</string>
+</resources>
diff --git a/common/res_leanback/values-uz-rUZ/strings.xml b/common/res_leanback/values-uz-rUZ/strings.xml
new file mode 100644
index 00000000..923ea077
--- /dev/null
+++ b/common/res_leanback/values-uz-rUZ/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"BOSHLADIK"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Keyingi"</string>
+</resources>
diff --git a/common/res_leanback/values-vi/strings.xml b/common/res_leanback/values-vi/strings.xml
new file mode 100644
index 00000000..5e2c4c07
--- /dev/null
+++ b/common/res_leanback/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"BẮT ĐẦU"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Tiếp theo"</string>
+</resources>
diff --git a/common/res_leanback/values-zh-rCN/strings.xml b/common/res_leanback/values-zh-rCN/strings.xml
new file mode 100644
index 00000000..7e032d76
--- /dev/null
+++ b/common/res_leanback/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"开始使用"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"下一页"</string>
+</resources>
diff --git a/common/res_leanback/values-zh-rHK/strings.xml b/common/res_leanback/values-zh-rHK/strings.xml
new file mode 100644
index 00000000..4c054d96
--- /dev/null
+++ b/common/res_leanback/values-zh-rHK/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"開始使用"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"下一頁"</string>
+</resources>
diff --git a/common/res_leanback/values-zh-rTW/strings.xml b/common/res_leanback/values-zh-rTW/strings.xml
new file mode 100644
index 00000000..4c054d96
--- /dev/null
+++ b/common/res_leanback/values-zh-rTW/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"開始使用"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"下一頁"</string>
+</resources>
diff --git a/common/res_leanback/values-zu/strings.xml b/common/res_leanback/values-zu/strings.xml
new file mode 100644
index 00000000..fe862d14
--- /dev/null
+++ b/common/res_leanback/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?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="lb_onboarding_get_started" msgid="1724006991213712878">"QALISA"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="113416166336573484">"Okulandelayo"</string>
+</resources>
diff --git a/common/res_leanback/values/colors.xml b/common/res_leanback/values/colors.xml
new file mode 100644
index 00000000..5230dfb8
--- /dev/null
+++ b/common/res_leanback/values/colors.xml
@@ -0,0 +1,23 @@
+<?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>
+ <!-- Onboarding screen -->
+ <color name="lb_page_indicator_dot">#014269</color>
+ <color name="lb_page_indicator_arrow_background">#EEEEEE</color>
+ <color name="lb_page_indicator_arrow_shadow">#4C000000</color>
+</resources>
diff --git a/common/res_leanback/values/dimens.xml b/common/res_leanback/values/dimens.xml
new file mode 100644
index 00000000..275d22ae
--- /dev/null
+++ b/common/res_leanback/values/dimens.xml
@@ -0,0 +1,39 @@
+<?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>
+ <!-- Onboarding screen -->
+ <dimen name="lb_onboarding_content_width">536dp</dimen>
+ <dimen name="lb_onboarding_header_height">100dp</dimen>
+ <dimen name="lb_onboarding_header_margin_top">64dp</dimen>
+ <dimen name="lb_onboarding_start_button_height">36dp</dimen>
+ <dimen name="lb_onboarding_start_button_margin_bottom">62dp</dimen>
+ <!-- This value should be lb_onboarding_header_margin_top + lb_onboarding_header_height -->
+ <dimen name="lb_onboarding_content_margin_top">164dp</dimen>
+ <!-- This value should be lb_onboarding_start_button_height + lb_onboarding_start_button_margin_bottom -->
+ <dimen name="lb_onboarding_content_margin_bottom">98dp</dimen>
+ <!-- This value should be lb_page_indicator_arrow_diameter + 2 * lb_page_indicator_arrow_shadow_radius -->
+ <dimen name="lb_onboarding_navigation_height">40dp</dimen>
+ <dimen name="lb_page_indicator_arrow_diameter">36dp</dimen>
+ <dimen name="lb_page_indicator_arrow_shadow_radius">2dp</dimen>
+ <dimen name="lb_page_indicator_arrow_shadow_offset">1dp</dimen>
+ <dimen name="lb_page_indicator_arrow_gap">32dp</dimen>
+ <!-- This value must be lb_twice page_indicator_dot_radius -->
+ <dimen name="lb_page_indicator_dot_diameter">10dp</dimen>
+ <dimen name="lb_page_indicator_dot_radius">5dp</dimen>
+ <dimen name="lb_page_indicator_dot_gap">16dp</dimen>
+</resources>
diff --git a/common/res_leanback/values/strings.xml b/common/res_leanback/values/strings.xml
new file mode 100644
index 00000000..2f585c0b
--- /dev/null
+++ b/common/res_leanback/values/strings.xml
@@ -0,0 +1,25 @@
+<?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>
+ <!-- Onboarding screen.-->
+ <eat-comment />
+ <!-- Text for "GET STARTED" button. This text should be in ALL CAPS. -->
+ <string name="lb_onboarding_get_started">GET STARTED</string>
+ <!-- Content description for page navigator. -->
+ <string name="lb_onboarding_accessibility_next">Next</string>
+</resources>
diff --git a/common/src/com/android/tv/common/AutoCloseableUtils.java b/common/src/com/android/tv/common/AutoCloseableUtils.java
new file mode 100644
index 00000000..ad364cc4
--- /dev/null
+++ b/common/src/com/android/tv/common/AutoCloseableUtils.java
@@ -0,0 +1,36 @@
+/*
+ * 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.common;
+
+import android.util.Log;
+
+/**
+ * Static utilities for AutoCloseable.
+ */
+public class AutoCloseableUtils {
+ private static final String TAG = "AutoCloseableUtils";
+
+ private AutoCloseableUtils() { }
+
+ public static void closeQuietly(AutoCloseable closeable) {
+ try {
+ closeable.close();
+ } catch (Exception ex) {
+ Log.e(TAG, "Error closing " + closeable, ex);
+ }
+ }
+}
diff --git a/common/src/com/android/tv/common/CollectionUtils.java b/common/src/com/android/tv/common/CollectionUtils.java
new file mode 100644
index 00000000..4a7a81f2
--- /dev/null
+++ b/common/src/com/android/tv/common/CollectionUtils.java
@@ -0,0 +1,78 @@
+/*
+ * 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.os.Build;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Static utilities for collections
+ */
+public class CollectionUtils {
+ /**
+ * Returns a new Set suitable for small data sets.
+ *
+ * <p>In M and above this is a {@link ArraySet} otherwise it is a {@link HashSet}.
+ */
+ public static <T> Set<T> createSmallSet() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new ArraySet<>();
+ } else {
+ return new HashSet<>();
+ }
+ }
+
+ /**
+ * Returns a new Map suitable for small data sets.
+ *
+ * <p>In M and above this is a {@link ArrayMap} otherwise it is a {@link HashMap}.
+ */
+ public static <K, V> Map<K, V> createSmallMap() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new ArrayMap<>();
+ } else {
+ return new HashMap<>();
+ }
+ }
+
+ /**
+ * Returns an array with the arrays concatenated together.
+ *
+ * @see <a href="http://stackoverflow.com/a/784842/1122089">Stackoverflow answer</a> by
+ * <a href="http://stackoverflow.com/users/40342/joachim-sauer">Joachim Sauer</a>
+ */
+ public static <T> T[] concatAll(T[] first, T[]... rest) {
+ int totalLength = first.length;
+ for (T[] array : rest) {
+ totalLength += array.length;
+ }
+ T[] result = Arrays.copyOf(first, totalLength);
+ int offset = first.length;
+ for (T[] array : rest) {
+ System.arraycopy(array, 0, result, offset, array.length);
+ offset += array.length;
+ }
+ return result;
+ }
+}
diff --git a/src/com/android/tv/util/MemoryManageable.java b/common/src/com/android/tv/common/MemoryManageable.java
index c5e5d869..0cb36103 100644
--- a/src/com/android/tv/util/MemoryManageable.java
+++ b/common/src/com/android/tv/common/MemoryManageable.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.util;
+package com.android.tv.common;
/**
* Interface for the fine-grained memory management.
diff --git a/common/src/com/android/tv/common/SharedPreferencesUtils.java b/common/src/com/android/tv/common/SharedPreferencesUtils.java
new file mode 100644
index 00000000..38daa963
--- /dev/null
+++ b/common/src/com/android/tv/common/SharedPreferencesUtils.java
@@ -0,0 +1,64 @@
+/*
+ * 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.Context;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+
+/**
+ * Static utilities for {@link android.content.SharedPreferences}
+ */
+public final class SharedPreferencesUtils {
+ // Note that changing the preference name will reset the preference values.
+ public static final String SHARED_PREF_FEATURES = "sharePreferencesFeatures";
+ public static final String SHARED_PREF_BROWSABLE = "browsable_shared_preference";
+ public static final String SHARED_PREF_WATCHED_HISTORY = "watched_history_shared_preference";
+ public static final String SHARED_PREF_AUDIO_CAPABILITIES =
+ "com.android.tv.audio_capabilities";
+ public static final String SHARED_PREF_RECURRING_RUNNER = "sharedPreferencesRecurringRunner";
+
+ private static boolean sInitializeCalled;
+
+ /**
+ * {@link android.content.SharedPreferences} loads the preference file when
+ * {@link Context#getSharedPreferences(String, int)} is called for the first time.
+ * Call {@link Context#getSharedPreferences(String, int)} as early as possible to avoid the ANR
+ * due to the file loading.
+ */
+ public static synchronized void initialize(final Context context) {
+ if (!sInitializeCalled) {
+ sInitializeCalled = true;
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ PreferenceManager.getDefaultSharedPreferences(context);
+ context.getSharedPreferences(SHARED_PREF_FEATURES, Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_BROWSABLE, Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_WATCHED_HISTORY, Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_AUDIO_CAPABILITIES,
+ Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_RECURRING_RUNNER,
+ Context.MODE_PRIVATE);
+ return null;
+ }
+ }.execute();
+ }
+ }
+
+ private SharedPreferencesUtils() { }
+}
diff --git a/common/src/com/android/tv/common/TvCommonConstants.java b/common/src/com/android/tv/common/TvCommonConstants.java
index a3c20d94..9824497e 100644
--- a/common/src/com/android/tv/common/TvCommonConstants.java
+++ b/common/src/com/android/tv/common/TvCommonConstants.java
@@ -29,11 +29,6 @@ public final class TvCommonConstants {
public static final String EXTRA_APP_LINK_CHANNEL_URI = "app_link_channel_uri";
/**
- * A flag whether this platform supports time shifting API or not.
- */
- public static final boolean HAS_TIME_SHIFT_API = Build.VERSION.SDK_INT >= 23;
-
- /**
* An intent action to launch setup activity of a TV input. The intent should include
* TV input ID in the value of {@link EXTRA_INPUT_ID}. Optionally, given the value of
* {@link EXTRA_ACTIVITY_AFTER_COMPLETION}, the activity will be launched after the setup
diff --git a/common/src/com/android/tv/common/TvContentRatingCache.java b/common/src/com/android/tv/common/TvContentRatingCache.java
new file mode 100644
index 00000000..5ca780e3
--- /dev/null
+++ b/common/src/com/android/tv/common/TvContentRatingCache.java
@@ -0,0 +1,145 @@
+/*
+ * 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.media.tv.TvContentRating;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * TvContentRating cache.
+ */
+public final class TvContentRatingCache implements MemoryManageable {
+ private final static String TAG = "TvContentRatings";
+
+ private final static TvContentRatingCache INSTANCE = new TvContentRatingCache();
+
+ public final static TvContentRatingCache getInstance() {
+ return INSTANCE;
+ }
+
+ private final Map<String, TvContentRating[]> mRatingsMultiMap = CollectionUtils
+ .createSmallMap();
+
+ /**
+ * Returns an array TvContentRatings from a string of comma separated set of rating strings
+ * creating each from {@link TvContentRating#unflattenFromString(String)} if needed.
+ * Returns {@code null} if the string is empty or contains no valid ratings.
+ */
+ @Nullable
+ public TvContentRating[] getRatings(String commaSeparatedRatings) {
+ if (TextUtils.isEmpty(commaSeparatedRatings)) {
+ return null;
+ }
+ TvContentRating[] tvContentRatings;
+ if (mRatingsMultiMap.containsKey(commaSeparatedRatings)) {
+ tvContentRatings = mRatingsMultiMap.get(commaSeparatedRatings);
+ } else {
+ String normalizedRatings = TextUtils
+ .join(",", getSortedSetFromCsv(commaSeparatedRatings));
+ if (mRatingsMultiMap.containsKey(normalizedRatings)) {
+ tvContentRatings = mRatingsMultiMap.get(normalizedRatings);
+ } else {
+ tvContentRatings = stringToContentRatings(commaSeparatedRatings);
+ mRatingsMultiMap.put(normalizedRatings, tvContentRatings);
+ }
+ if (!normalizedRatings.equals(commaSeparatedRatings)) {
+ // Add an entry so the non normalized entry points to the same result;
+ mRatingsMultiMap.put(commaSeparatedRatings, tvContentRatings);
+ }
+ }
+ return tvContentRatings;
+ }
+
+ /**
+ * Returns a sorted array of TvContentRatings from a comma separated string of ratings.
+ */
+ @VisibleForTesting
+ static TvContentRating[] stringToContentRatings(String commaSeparatedRatings) {
+ if (TextUtils.isEmpty(commaSeparatedRatings)) {
+ return null;
+ }
+ Set<String> ratingStrings = getSortedSetFromCsv(commaSeparatedRatings);
+ List<TvContentRating> contentRatings = new ArrayList<>();
+ for (String rating : ratingStrings) {
+ try {
+ contentRatings.add(TvContentRating.unflattenFromString(rating));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Can't parse the content rating: '" + rating + "'", e);
+ }
+ }
+ return contentRatings.size() == 0 ?
+ null : contentRatings.toArray(new TvContentRating[contentRatings.size()]);
+ }
+
+ private static Set<String> getSortedSetFromCsv(String commaSeparatedRatings) {
+ String[] ratingStrings = commaSeparatedRatings.split("\\s*,\\s*");
+ return toSortedSet(ratingStrings);
+ }
+
+ private static Set<String> toSortedSet(String[] ratingStrings) {
+ if (ratingStrings.length == 0) {
+ return Collections.EMPTY_SET;
+ } else if (ratingStrings.length == 1) {
+ return Collections.singleton(ratingStrings[0]);
+ } else {
+ // Using a TreeSet here is not very efficient, however it is good enough because:
+ // - the results are cached
+ // - in testing with multiple TISs, less than 50 entries are created
+ SortedSet<String> set = new TreeSet<>();
+ Collections.addAll(set, ratingStrings);
+ return set;
+ }
+ }
+
+ /**
+ * Returns a string of each flattened content rating, sorted and concatenated together
+ * with a comma.
+ */
+ public static String contentRatingsToString(TvContentRating[] contentRatings) {
+ if (contentRatings == null || contentRatings.length == 0) {
+ return null;
+ }
+ String[] ratingStrings = new String[contentRatings.length];
+ for (int i = 0; i < contentRatings.length; i++) {
+ ratingStrings[i] = contentRatings[i].flattenToString();
+ }
+ if (ratingStrings.length == 1) {
+ return ratingStrings[0];
+ } else {
+ return TextUtils.join(",", toSortedSet(ratingStrings));
+ }
+ }
+
+ @Override
+ public void performTrimMemory(int level) {
+ mRatingsMultiMap.clear();
+ }
+
+ private TvContentRatingCache() {
+ }
+}
diff --git a/common/src/com/android/tv/common/annotation/UsedByReflection.java b/common/src/com/android/tv/common/annotation/UsedByReflection.java
new file mode 100644
index 00000000..5a4517f7
--- /dev/null
+++ b/common/src/com/android/tv/common/annotation/UsedByReflection.java
@@ -0,0 +1,29 @@
+/*
+ * 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.annotation;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Denotes that the method or field is used by reflection even though it is not ever called
+ * directly.
+ */
+@Retention(SOURCE)
+public @interface UsedByReflection {
+}
diff --git a/common/src/com/android/tv/common/dvr/DvrSessionClient.java b/common/src/com/android/tv/common/dvr/DvrSessionClient.java
deleted file mode 100644
index b7dde7ff..00000000
--- a/common/src/com/android/tv/common/dvr/DvrSessionClient.java
+++ /dev/null
@@ -1,149 +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.dvr;
-
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.media.tv.TvView;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * A session used for recording.
- */
-public class DvrSessionClient {
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({RECORD_STOP_REASON_DISKFULL, RECORD_STOP_REASON_CONFLICT,
- RECORD_STOP_REASON_CONNECT_FAILED, RECORD_STOP_REASON_DISCONNECTED,
- RECORD_STOP_REASON_UNKNOWN})
- public @interface RecordStopReason {}
- public static final int RECORD_STOP_REASON_DISKFULL = 1;
- public static final int RECORD_STOP_REASON_CONFLICT = 2;
- public static final int RECORD_STOP_REASON_CONNECT_FAILED = 3;
- public static final int RECORD_STOP_REASON_DISCONNECTED = 4;
- public static final int RECORD_STOP_REASON_UNKNOWN = 10;
-
- private boolean mRecordStarted;
- private Callback mCallback;
- private TvView mTvView;
-
- public DvrSessionClient(Context context) {
- mTvView = new TvView(context);
- }
-
- /**
- * Connects the session to a specific input {@code inputId}.
- */
- public void connect(String inputId, Callback callback) {
- mCallback = callback;
- Bundle bundle = new Bundle();
- bundle.putBoolean(DvrUtils.BUNDLE_IS_DVR, true);
- mTvView.tune(inputId, TvContract.buildChannelUri(0), bundle);
- mTvView.sendAppPrivateCommand(DvrUtils.APP_PRIV_CREATE_DVR_SESSION, null);
- mTvView.setCallback(new TvView.TvInputCallback() {
- @Override
- public void onConnectionFailed(String inputId) {
- if (mCallback == null) {
- return;
- }
- mCallback.onDisconnected();
- }
-
- @Override
- public void onDisconnected(String inputId) {
- if (mCallback == null) {
- return;
- }
- mCallback.onDisconnected();
- }
-
- @Override
- public void onEvent(String inputId, String eventType, Bundle eventArgs) {
- if (mCallback == null) {
- return;
- }
- String mediaUriString = eventArgs == null ? null :
- eventArgs.getString(DvrUtils.BUNDLE_MEDIA_URI, null);
- Uri mediaUri = mediaUriString == null ? null : Uri.parse(mediaUriString);
- if (DvrUtils.EVENT_TYPE_CONNECTED.equals(eventType)) {
- mCallback.onConnected();
- } else if (DvrUtils.EVENT_TYPE_RECORD_STARTED.equals(eventType)) {
- mCallback.onRecordStarted(mediaUri);
- } else if (DvrUtils.EVENT_TYPE_RECORD_STOPPED.equals(eventType)) {
- int reason = eventArgs.getInt(DvrUtils.BUNDLE_STOPPED_REASON);
- mCallback.onRecordStopped(mediaUri, reason);
- } else if (DvrUtils.EVENT_TYPE_DELETED.equals(eventType)) {
- mCallback.onRecordDeleted(mediaUri);
- }
- }
-
- // TODO: handle track select.
- });
- }
-
- /**
- * Releases the session.
- */
- public void release() {
- mTvView.reset();
- mCallback = null;
- }
-
- /**
- * Starts recording.
- */
- public void startRecord(Uri channelUri, Uri mediaUri) {
- if (mRecordStarted) {
- throw new IllegalStateException("Don't reuse the session for simple implementation");
- }
- mRecordStarted = true;
- Bundle params = DvrUtils.buildMediaUri(mediaUri);
- params.putString(DvrUtils.BUNDLE_CHANNEL_URI, channelUri.toString());
- mTvView.sendAppPrivateCommand(DvrUtils.APP_PRIV_START_RECORD, params);
- }
-
- /**
- * Stops recording.
- */
- public void stopRecord() {
- if (!mRecordStarted) {
- return;
- }
- mRecordStarted = false;
- mTvView.sendAppPrivateCommand(DvrUtils.APP_PRIV_STOP_RECORD, null);
- }
-
- /**
- * Deletes a recorded media.
- */
- public void delete(Uri mediaUri) {
- mTvView.sendAppPrivateCommand(DvrUtils.APP_PRIV_DELETE, DvrUtils.buildMediaUri(mediaUri));
- }
-
- public abstract static class Callback {
- public void onConnected() { }
- public void onDisconnected() { }
- public void onRecordStarted(Uri mediaUri) { }
- public void onRecordStopped(Uri mediaUri, @RecordStopReason int reason) { }
- public void onRecordDeleted(Uri mediaUri) { }
- public void onRecordDeleteFailed(Uri mediaUri, int reason) { }
- }
-}
diff --git a/common/src/com/android/tv/common/dvr/DvrTvView.java b/common/src/com/android/tv/common/dvr/DvrTvView.java
deleted file mode 100644
index 247db191..00000000
--- a/common/src/com/android/tv/common/dvr/DvrTvView.java
+++ /dev/null
@@ -1,67 +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.dvr;
-
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.media.tv.TvView;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.AttributeSet;
-
-/**
- * Extend {@link TvView} to support recording playback.
- */
-public class DvrTvView extends TvView {
-
- public DvrTvView(Context context) {
- this(context, null, 0);
- }
-
- public DvrTvView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public DvrTvView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- /**
- * Start playback of recording. Once TvInput is ready to play, onVideoAvailable will be called.
- * Playback control will be done with timeshift method for seek, play, pause.
- */
- public void playMedia(String inputId, Uri mediaUri) {
- tune(inputId, TvContract.buildChannelUri(0), DvrUtils.buildMediaUri(mediaUri));
- }
-
- @Override
- public void tune(String inputId, Uri channelUri, Bundle params) {
- super.tune(inputId, channelUri, params);
- sendAppPrivateCommand(DvrUtils.APP_PRIV_CREATE_PLAYBACK_SESSION, null);
- }
-
- public void setTimeShiftPositionCallback(TimeShiftPositionCallback2 callback) {
- // TODO: implement
- }
-
- /**
- * We need end position for recording playback.
- */
- public abstract static class TimeShiftPositionCallback2 extends TimeShiftPositionCallback {
- public void onTimeShiftEndPositionChanged(String inputId, long timeMs) { }
- }
-}
diff --git a/common/src/com/android/tv/common/feature/CommonFeatures.java b/common/src/com/android/tv/common/feature/CommonFeatures.java
new file mode 100644
index 00000000..bfef19a6
--- /dev/null
+++ b/common/src/com/android/tv/common/feature/CommonFeatures.java
@@ -0,0 +1,40 @@
+/*
+ * 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.common.feature;
+
+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.TestableFeature.createTestableFeature;
+
+/**
+ * List of {@link Feature} that affect more than just the Live TV app.
+ *
+ * <p>Remove the {@code Feature} once it is launched.
+ */
+public class CommonFeatures {
+ /**
+ * DVR
+ *
+ * <p>See <a href="https://goto.google.com/atv-dvr-onepager">go/atv-dvr-onepager</a>
+ */
+ public static TestableFeature DVR = createTestableFeature(
+ AND(
+ ENG_ONLY_FEATURE,
+ new PropertyFeature("dvr_enabled", false),
+ Sdk.M_FEATURE // TODO(dvr): Sdk.N_PREVIEW_FEATURE
+ ));
+}
diff --git a/src/com/android/tv/util/EngOnlyFeature.java b/common/src/com/android/tv/common/feature/EngOnlyFeature.java
index f4cbe9cf..14d2b49b 100644
--- a/src/com/android/tv/util/EngOnlyFeature.java
+++ b/common/src/com/android/tv/common/feature/EngOnlyFeature.java
@@ -14,12 +14,11 @@
* limitations under the License
*/
-package com.android.tv.util;
+package com.android.tv.common.feature;
import android.content.Context;
-import com.android.tv.BuildConfig;
-import com.android.tv.common.feature.Feature;
+import com.android.tv.common.BuildConfig;
/**
* A feature that is only available on {@link BuildConfig#ENG} builds.
@@ -36,6 +35,6 @@ public final class EngOnlyFeature implements Feature {
@Override
public String toString() {
- return "EngOnlyFeature";
+ return "EngOnlyFeature(" + BuildConfig.ENG + ")";
}
}
diff --git a/common/src/com/android/tv/common/feature/PackageVersionFeature.java b/common/src/com/android/tv/common/feature/PackageVersionFeature.java
new file mode 100644
index 00000000..7f615d31
--- /dev/null
+++ b/common/src/com/android/tv/common/feature/PackageVersionFeature.java
@@ -0,0 +1,55 @@
+/*
+ * 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.feature;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+/*
+ * A feature controlled by package version.
+ */
+public class PackageVersionFeature implements Feature {
+ private static final String TAG = "PackageVersionFeature";
+ private static final boolean DEBUG = false;
+
+ private final String mPackageName;
+ private final int mRequiredVersionCode;
+
+ public PackageVersionFeature(String packageName, int requiredVersionCode) {
+ mPackageName = packageName;
+ mRequiredVersionCode = requiredVersionCode;
+ }
+
+ @Override
+ public boolean isEnabled(Context context) {
+ try {
+ PackageInfo pInfo = context.getPackageManager().getPackageInfo(mPackageName, 0);
+ return pInfo != null && pInfo.versionCode >= mRequiredVersionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) Log.d(TAG, "Can't find package '" + mPackageName + "'.", e);
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "PackageVersionFeature[packageName=" + mPackageName + ",requiredVersion="
+ + mRequiredVersionCode + "]";
+ }
+}
diff --git a/common/src/com/android/tv/common/feature/Sdk.java b/common/src/com/android/tv/common/feature/Sdk.java
new file mode 100644
index 00000000..1efefd89
--- /dev/null
+++ b/common/src/com/android/tv/common/feature/Sdk.java
@@ -0,0 +1,42 @@
+/*
+ * 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.common.feature;
+
+import android.content.Context;
+import android.os.Build;
+
+/**
+ * Holder for SDK version features
+ */
+public class Sdk {
+ public static Feature M_FEATURE = new SdkVersionFeature(Build.VERSION_CODES.M);
+
+ private static class SdkVersionFeature implements Feature {
+ private final int mVersionCode;
+
+ private SdkVersionFeature(int versionCode) {
+ mVersionCode = versionCode;
+ }
+
+ @Override
+ public boolean isEnabled(Context context) {
+ return Build.VERSION.SDK_INT >= mVersionCode;
+ }
+ }
+
+ 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 eb5c805f..4d3a70a8 100644
--- a/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
+++ b/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
@@ -20,14 +20,15 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
+import com.android.tv.common.SharedPreferencesUtils;
+
/**
* Feature controlled by shared preferences.
*/
public final class SharedPreferencesFeature implements Feature {
- private static final String TAG = "SharedPreferencesFeature";
+ private static final String TAG = "SharedPrefFeature";
private static final boolean DEBUG = false;
- private static final String SHARED_PREFERENCE = "sharePreferencesFeatures";
private String mKey;
private boolean mEnabled;
private boolean mDefaultValue;
@@ -54,7 +55,7 @@ public final class SharedPreferencesFeature implements Feature {
}
if (mSharedPreferences == null) {
mSharedPreferences = context.getSharedPreferences(
- SHARED_PREFERENCE, Context.MODE_PRIVATE);
+ SharedPreferencesUtils.SHARED_PREF_FEATURES, Context.MODE_PRIVATE);
mEnabled = mSharedPreferences.getBoolean(mKey, mDefaultValue);
}
if (DEBUG) Log.d(TAG, mKey + " is " + mEnabled);
@@ -70,7 +71,7 @@ public final class SharedPreferencesFeature implements Feature {
if (DEBUG) Log.d(TAG, mKey + " is set to " + enable);
if (mSharedPreferences == null) {
mSharedPreferences = context.getSharedPreferences(
- SHARED_PREFERENCE, Context.MODE_PRIVATE);
+ SharedPreferencesUtils.SHARED_PREF_FEATURES, Context.MODE_PRIVATE);
mEnabled = enable;
mSharedPreferences.edit().putBoolean(mKey, enable).apply();
} else if (mEnabled != enable) {
diff --git a/common/src/com/android/tv/common/feature/TestableFeature.java b/common/src/com/android/tv/common/feature/TestableFeature.java
index db546ec9..a02877ec 100644
--- a/common/src/com/android/tv/common/feature/TestableFeature.java
+++ b/common/src/com/android/tv/common/feature/TestableFeature.java
@@ -16,7 +16,6 @@
package com.android.tv.common.feature;
-import android.app.ActivityManager;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
@@ -31,6 +30,9 @@ import com.android.tv.common.TvCommonUtils;
*/
public class TestableFeature implements Feature {
private final static String TAG = "TestableFeature";
+ private final static String DETAIL_MESSAGE
+ = "TestableFeatures should only be changed in tests.";
+
private final Feature mDelegate;
private Boolean mTestValue = null;
@@ -44,24 +46,29 @@ public class TestableFeature implements Feature {
@VisibleForTesting
public void enableForTest() {
- if (TvCommonUtils.isRunningInTest()) {
- Log.e(TAG, "TestableFeatures should only be changed in tests. Ignoring");
+ if (!TvCommonUtils.isRunningInTest()) {
+ Log.e(TAG, "Not enabling for test:" + this,
+ new IllegalStateException(DETAIL_MESSAGE));
+ } else {
mTestValue = true;
}
}
@VisibleForTesting
public void disableForTests() {
- if (TvCommonUtils.isRunningInTest()) {
- Log.e(TAG, "TestableFeatures should only be changed in tests. Ignoring");
+ if (!TvCommonUtils.isRunningInTest()) {
+ Log.e(TAG, "Not disabling for test: " + this,
+ new IllegalStateException(DETAIL_MESSAGE));
+ } else {
mTestValue = false;
}
}
@VisibleForTesting
public void resetForTests() {
- if (TvCommonUtils.isRunningInTest()) {
- Log.e(TAG, "TestableFeatures should only be changed in tests. Ignoring");
+ if (!TvCommonUtils.isRunningInTest()) {
+ Log.e(TAG, "Not resetting feature: " + this, new IllegalStateException(DETAIL_MESSAGE));
+ } else {
mTestValue = null;
}
}
diff --git a/common/src/com/android/tv/common/recording/PlaybackTvView.java b/common/src/com/android/tv/common/recording/PlaybackTvView.java
new file mode 100644
index 00000000..e62ee06f
--- /dev/null
+++ b/common/src/com/android/tv/common/recording/PlaybackTvView.java
@@ -0,0 +1,191 @@
+/*
+ * 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.recording;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.media.tv.TvContentRating;
+import android.media.tv.TvContract;
+import android.media.tv.TvTrackInfo;
+import android.media.tv.TvView;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.AttributeSet;
+
+import com.android.tv.common.feature.CommonFeatures;
+
+import java.util.List;
+
+/**
+ * Extend {@link TvView} to support recording playback.
+ */
+@TargetApi(Build.VERSION_CODES.M) // TODO(DVR): set to N
+public class PlaybackTvView extends TvView {
+
+ final TvInputCallback mInternalCallback = new TvInputCallback() {
+ @Override
+ public void onChannelRetuned(String inputId, Uri channelUri) {
+ if (mCallback != null) {
+ mCallback.onChannelRetuned(inputId, channelUri);
+ }
+ }
+
+ @Override
+ public void onConnectionFailed(String inputId) {
+ if (mCallback != null) {
+ mCallback.onConnectionFailed(inputId);
+ }
+ }
+
+ @Override
+ public void onContentAllowed(String inputId) {
+ if (mCallback != null) {
+ mCallback.onContentAllowed(inputId);
+ }
+ }
+
+ @Override
+ public void onContentBlocked(String inputId, TvContentRating rating) {
+ if (mCallback != null) {
+ mCallback.onContentBlocked(inputId, rating);
+ }
+ }
+
+ @Override
+ public void onDisconnected(String inputId) {
+ if (mCallback != null) {
+ mCallback.onDisconnected(inputId);
+ }
+ }
+
+ @Override
+ public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+ if (mCallback != null) {
+ if (eventType.equals(RecordingUtils.EVENT_TYPE_TIMESHIFT_END_POSITION)) {
+ if (mTimeshiftCallback != null) {
+ mTimeshiftCallback.onTimeShiftEndPositionChanged(inputId,
+ eventArgs.getLong(RecordingUtils.BUNDLE_TIMESHIFT_END_POSITION));
+ }
+ return;
+ }
+ mCallback.onEvent(inputId, eventType, eventArgs);
+ }
+ }
+
+ @Override
+ public void onTimeShiftStatusChanged(String inputId, int status) {
+ if (mCallback != null) {
+ mCallback.onTimeShiftStatusChanged(inputId, status);
+ }
+ }
+
+ @Override
+ public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
+ if (mCallback != null) {
+ mCallback.onTracksChanged(inputId, tracks);
+ }
+ }
+
+ @Override
+ public void onTrackSelected(String inputId, int type, String trackId) {
+ if (mCallback != null) {
+ mCallback.onTrackSelected(inputId, type, trackId);
+ }
+ }
+
+ @Override
+ public void onVideoAvailable(String inputId) {
+ if (mCallback != null) {
+ mCallback.onVideoAvailable(inputId);
+ }
+ }
+
+ @Override
+ public void onVideoSizeChanged(String inputId, int width, int height) {
+ if (mCallback != null) {
+ mCallback.onVideoSizeChanged(inputId, width, height);
+ }
+ }
+
+ @Override
+ public void onVideoUnavailable(String inputId, int reason) {
+ if (mCallback != null) {
+ mCallback.onVideoUnavailable(inputId, reason);
+ }
+ }
+ };
+
+ private TvInputCallback mCallback;
+ private TimeShiftPositionCallback2 mTimeshiftCallback;
+
+ public PlaybackTvView(Context context) {
+ this(context, null, 0);
+ }
+
+ public PlaybackTvView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PlaybackTvView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * Start playback of recording. Once TvInput is ready to play, onVideoAvailable will be called.
+ * Playback control will be done with timeshift method for seek, play, pause.
+ */
+ public void playMedia(String inputId, Uri mediaUri) {
+ tune(inputId, TvContract.buildChannelUri(0), RecordingUtils.buildMediaUri(mediaUri));
+ }
+
+ @Override
+ public void tune(String inputId, Uri channelUri, Bundle params) {
+ super.tune(inputId, channelUri, params);
+ if (CommonFeatures.DVR.isEnabled(getContext())) {
+ sendAppPrivateCommand(RecordingUtils.APP_PRIV_CREATE_PLAYBACK_SESSION, null);
+ }
+ }
+
+ public void setTimeShiftPositionCallback(TimeShiftPositionCallback2 callback) {
+ if (CommonFeatures.DVR.isEnabled(getContext())) {
+ mTimeshiftCallback = callback;
+ }
+ super.setTimeShiftPositionCallback(callback);
+ }
+
+ @Override
+ public void setCallback(TvInputCallback callback) {
+ if (CommonFeatures.DVR.isEnabled(getContext())) {
+ mCallback = callback;
+ if (callback == null) {
+ super.setCallback(null);
+ } else {
+ super.setCallback(mInternalCallback);
+ }
+ } else {
+ super.setCallback(callback);
+ }
+ }
+
+ /**
+ * We need end position for recording playback.
+ */
+ public abstract static class TimeShiftPositionCallback2 extends TimeShiftPositionCallback {
+ public void onTimeShiftEndPositionChanged(String inputId, long timeMs) { }
+ }
+}
diff --git a/common/src/com/android/tv/common/recording/RecordingCapability.java b/common/src/com/android/tv/common/recording/RecordingCapability.java
new file mode 100644
index 00000000..266fd271
--- /dev/null
+++ b/common/src/com/android/tv/common/recording/RecordingCapability.java
@@ -0,0 +1,181 @@
+/*
+ * 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.recording;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Static representation of the recording capability of a TvInputService.
+ */
+public final class RecordingCapability implements Parcelable{
+ /**
+ * The inputId this capability represents.
+ */
+ public final String inputId;
+
+ /**
+ * The max number of concurrent sessions that require a tuner.
+ *
+ * <p>Both recording and playing live TV requires a Tuner.
+ */
+ public final int maxConcurrentTunedSessions;
+
+ /**
+ * The max number concurrent session that play a stream.
+ *
+ *<p>This is often limited by the number of decoders available.
+ * The count includes both playing live TV and playing a recorded stream.
+ */
+ public final int maxConcurrentPlayingSessions;
+
+ /**
+ * Max number of concurrent sessions all types.
+ *
+ * <p>This may be limited by bandwidth or CPU or other factors.
+ */
+ public final int maxConcurrentSessionsOfAllTypes;
+
+ /**
+ * True if a tuned session can support recording and playback from the same resource.
+ */
+ public final boolean playbackWhileRecording;
+
+ private RecordingCapability(String inputId, int maxConcurrentTunedSessions,
+ int maxConcurrentPlayingSessions, int maxConcurrentSessionsOfAllTypes,
+ boolean playbackWhileRecording) {
+ this.inputId = inputId;
+ this.maxConcurrentTunedSessions = maxConcurrentTunedSessions;
+ this.maxConcurrentPlayingSessions = maxConcurrentPlayingSessions;
+ this.maxConcurrentSessionsOfAllTypes = maxConcurrentSessionsOfAllTypes;
+ this.playbackWhileRecording = playbackWhileRecording;
+ }
+
+ protected RecordingCapability(Parcel in) {
+ inputId = in.readString();
+ maxConcurrentTunedSessions = in.readInt();
+ maxConcurrentPlayingSessions = in.readInt();
+ maxConcurrentSessionsOfAllTypes = in.readInt();
+ playbackWhileRecording = in.readByte() != 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(inputId);
+ parcel.writeInt(maxConcurrentTunedSessions);
+ parcel.writeInt(maxConcurrentPlayingSessions);
+ parcel.writeInt(maxConcurrentSessionsOfAllTypes);
+ parcel.writeByte((byte) (playbackWhileRecording ? 1 : 0));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof RecordingCapability)) {
+ return false;
+ }
+ RecordingCapability that = (RecordingCapability) o;
+ return Objects.equals(maxConcurrentTunedSessions, that.maxConcurrentTunedSessions) &&
+ Objects.equals(maxConcurrentPlayingSessions, that.maxConcurrentPlayingSessions) &&
+ Objects.equals(maxConcurrentSessionsOfAllTypes,
+ that.maxConcurrentSessionsOfAllTypes) &&
+ Objects.equals(playbackWhileRecording, that.playbackWhileRecording) &&
+ Objects.equals(inputId, that.inputId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(inputId);
+ }
+
+ @Override
+ public String toString() {
+ return "RecordingCapability{" +
+ "inputId='" + inputId + '\'' +
+ ", maxConcurrentTunedSessions=" + maxConcurrentTunedSessions +
+ ", maxConcurrentPlayingSessions=" + maxConcurrentPlayingSessions +
+ ", maxConcurrentSessionsOfAllTypes=" + maxConcurrentSessionsOfAllTypes +
+ ", playbackWhileRecording=" + playbackWhileRecording +
+ '}';
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<RecordingCapability> CREATOR = new Creator<RecordingCapability>() {
+ @Override
+ public RecordingCapability createFromParcel(Parcel in) {
+ return new RecordingCapability(in);
+ }
+
+ @Override
+ public RecordingCapability[] newArray(int size) {
+ return new RecordingCapability[size];
+ }
+ };
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+ private String mInputId;
+ private int mMaxConcurrentTunedSessions;
+ private int mMaxConcurrentPlayingSessions;
+ private int mMaxConcurrentSessionsOfAllTypes;
+ private boolean mPlaybackWhileRecording;
+
+ public Builder setInputId(String inputId) {
+ mInputId = inputId;
+ return this;
+ }
+
+ public Builder setMaxConcurrentTunedSessions(int maxConcurrentTunedSessions) {
+ mMaxConcurrentTunedSessions = maxConcurrentTunedSessions;
+ return this;
+ }
+
+ public Builder setMaxConcurrentPlayingSessions(int maxConcurrentPlayingSessions) {
+ mMaxConcurrentPlayingSessions = maxConcurrentPlayingSessions;
+ return this;
+ }
+
+ public Builder setMaxConcurrentSessionsOfAllTypes(int maxConcurrentSessionsOfAllTypes) {
+ mMaxConcurrentSessionsOfAllTypes = maxConcurrentSessionsOfAllTypes;
+ return this;
+ }
+
+ public Builder setPlaybackWhileRecording(boolean playbackWhileRecording) {
+ mPlaybackWhileRecording = playbackWhileRecording;
+ return this;
+ }
+
+ public RecordingCapability build() {
+ return new RecordingCapability(mInputId, mMaxConcurrentTunedSessions,
+ mMaxConcurrentPlayingSessions, mMaxConcurrentSessionsOfAllTypes,
+ mPlaybackWhileRecording);
+ }
+ }
+}
+
+
diff --git a/common/src/com/android/tv/common/dvr/DvrTvInputService.java b/common/src/com/android/tv/common/recording/RecordingTvInputService.java
index ecf90656..6eea6ae7 100644
--- a/common/src/com/android/tv/common/dvr/DvrTvInputService.java
+++ b/common/src/com/android/tv/common/recording/RecordingTvInputService.java
@@ -14,33 +14,35 @@
* limitations under the License.
*/
-package com.android.tv.common.dvr;
+package com.android.tv.common.recording;
+import android.annotation.TargetApi;
import android.content.Context;
import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputService;
import android.media.tv.TvTrackInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
+import com.android.tv.common.feature.CommonFeatures;
+
import java.util.List;
/**
- * {@link TvInputService} class supporting DVR feature.
+ * {@link TvInputService} class that supports recording and playback.
*/
-public abstract class DvrTvInputService extends TvInputService {
+@TargetApi(Build.VERSION_CODES.M) // TODO(DVR): set to N
+public abstract class RecordingTvInputService extends TvInputService {
private static final String TAG = "DvrTvInputService";
- private static final boolean DEBUG = false;
- // TODO: use Features.DVR.
- private static final boolean FEATURE_DVR = false;
+ private static final boolean DEBUG = true;
@Override
public final Session onCreateSession(String inputId) {
- if (FEATURE_DVR) {
+ if (CommonFeatures.DVR.isEnabled(this)) {
return new InternalSession(this, inputId);
} else {
return onCreatePlaybackSession(inputId);
@@ -48,9 +50,9 @@ public abstract class DvrTvInputService extends TvInputService {
}
/**
- * Called when {@link com.android.tv.common.dvr.DvrSession#connect} is called.
+ * Called when {@link com.android.tv.common.recording.DvrSession#connect} is called.
*/
- protected DvrSession onCreateDvrSession(String inputId) {
+ protected TvRecording.RecordingSession onCreateDvrSession(String inputId) {
return null;
}
@@ -89,15 +91,15 @@ public abstract class DvrTvInputService extends TvInputService {
@Override
public void onAppPrivateCommand(String action, Bundle data) {
- if (action.equals(DvrUtils.APP_PRIV_CREATE_DVR_SESSION)) {
+ if (action.equals(RecordingUtils.APP_PRIV_CREATE_DVR_SESSION)) {
if (mSessionImpl == null) {
mSessionImpl = onCreateDvrSession(mInputId);
if (mSessionImpl != null) {
mSessionImpl.setPassthroughSession(this);
- notifySessionEvent(DvrUtils.EVENT_TYPE_CONNECTED, null);
+ notifySessionEvent(RecordingUtils.EVENT_TYPE_CONNECTED, null);
}
}
- } else if (action.equals(DvrUtils.APP_PRIV_CREATE_PLAYBACK_SESSION)) {
+ } else if (action.equals(RecordingUtils.APP_PRIV_CREATE_PLAYBACK_SESSION)) {
if (mSessionImpl == null) {
mSessionImpl = onCreatePlaybackSession(mInputId);
if (mSessionImpl != null) {
@@ -219,7 +221,7 @@ public abstract class DvrTvInputService extends TvInputService {
}
/**
- * Base class for {@link PlaybackSession} and {@link DvrSession}. Do not use it directly
+ * Base class for {@link PlaybackSession} and {@link TvRecording.RecordingSession}. Do not use it directly
* outside of this class.
*/
public static abstract class BaseSession extends TvInputService.Session {
@@ -325,121 +327,50 @@ public abstract class DvrTvInputService extends TvInputService {
}
/**
- * Session linked to {@link com.android.tv.common.dvr.DvrSession} to record contents.
+ * Session linked to {@link android.media.tv.TvView} to tune to a channel or play an recording.
*/
- public static abstract class DvrSession extends BaseSession {
- public DvrSession(Context context) {
- super(context);
- }
-
- @Override
- public final boolean onTune(Uri channelUri) {
- // no-op
- return false;
- }
-
- @Override
- public final boolean onSetSurface(Surface surface) {
- // no-op
- return false;
- }
-
- @Override
- public final void onSetStreamVolume(float volume) {
- // no-op
- }
-
- @Override
- public final void onSetCaptionEnabled(boolean enabled) {
- // no-op
- }
-
- /**
- * Called when it starts to record {@code channelUri}. {@link #notifyRecordStarted()}
- * should be called as soon as starting recording.
- */
- public abstract void onStartRecord(Uri channelUri, Uri mediaUri);
-
- /**
- * Called when it stops to record.
- */
- public abstract void onStopRecord();
-
- /**
- * Called when it is requested to delete {@code mediaUri}.
- */
- public abstract void onDelete(Uri mediaUri);
+ public static abstract class PlaybackSession extends BaseSession {
+ private boolean mIsRecordingPlayback;
- /**
- * Notifies when recording starts. It is an response of {@link #onStartRecord}.
- */
- public void notifyRecordStarted(Uri mediaUri) {
- notifySessionEvent(DvrUtils.EVENT_TYPE_RECORD_STARTED,
- DvrUtils.buildMediaUri(mediaUri));
+ public PlaybackSession(Context context) {
+ super(context);
}
/**
- * Notifies when recording is unexpectedly stopped.
+ * Returns {@code true}, if the current playback is for a recording.
*/
- public void notifyRecordUnexpectedlyStopped(Uri mediaUri, int reason) {
- Bundle params = DvrUtils.buildMediaUri(mediaUri);
- params.putInt(DvrUtils.BUNDLE_STOPPED_REASON, reason);
- notifySessionEvent(DvrUtils.EVENT_TYPE_RECORD_STOPPED, params);
+ public boolean isRecordingPlayback() {
+ return mIsRecordingPlayback;
}
/**
- * Notifies when the recording {@code mediaUri} is deleted.
+ * Called when it is requested to play an recording {@code mediaUri}. When playback and
+ * rendering starts, {@link #notifyVideoAvailable} should be called.
*/
- public void notifyDeleted(Uri mediaUri) {
- notifySessionEvent(DvrUtils.EVENT_TYPE_DELETED, DvrUtils.buildMediaUri(mediaUri));
- }
+ public void onPlayMedia(Uri mediaUri) { }
/**
- * Notifies when the deletion of the recording {@code mediaUri} is requested through
- * {@link #onDelete} but failed.
+ * Notifies TimeShift end position. It should have the form like onTimeShiftEndPosition.
+ * But, it's not trivial to add that in the prototyping. The method is recommended to be
+ * called inside {@link #onTimeShiftGetStartPosition()}, when a recording is played.
*/
- public void notifyDeleteFailed(Uri mediaUri, int reason) {
- Bundle params = DvrUtils.buildMediaUri(mediaUri);
- params.putInt(DvrUtils.BUNDLE_DELETE_FAILED_REASON, reason);
- notifySessionEvent(DvrUtils.EVENT_TYPE_DELETE_FAILED, params);
+ public void notifyTimeShiftEndPosition(long endPosition) {
+ Bundle params = new Bundle();
+ params.putLong(RecordingUtils.BUNDLE_TIMESHIFT_END_POSITION, endPosition);
+ notifySessionEvent(RecordingUtils.EVENT_TYPE_TIMESHIFT_END_POSITION, params);
}
@Override
- public void onAppPrivateCommand(String action, Bundle data) {
- if (DvrUtils.APP_PRIV_START_RECORD.equals(action)) {
- onStartRecord(Uri.parse(data.getString(DvrUtils.BUNDLE_CHANNEL_URI)),
- Uri.parse(data.getString(DvrUtils.BUNDLE_CHANNEL_URI)));
- } else if (DvrUtils.APP_PRIV_STOP_RECORD.equals(action)) {
- onStopRecord();
- } else if (DvrUtils.APP_PRIV_DELETE.equals(action)) {
- onDelete(Uri.parse(data.getString(DvrUtils.BUNDLE_CHANNEL_URI)));
- }
- }
- }
-
- /**
- * Session linked to {@link android.media.tv.TvView} to tune to a channel or play an recording.
- */
- public static abstract class PlaybackSession extends BaseSession {
- public PlaybackSession(Context context) {
- super(context);
- }
-
- /**
- * Called when it is requested to play an recording {@code mediaUri}. When playback and
- * rendering starts, {@link #notifyVideoAvailable} should be called.
- */
- public void onPlayMedia(Uri mediaUri) { }
-
- @Override
public final boolean onTune(Uri channelUri, Bundle params) {
- if (params != null && params.getBoolean(DvrUtils.BUNDLE_IS_DVR, false)) {
- notifySessionEvent(DvrUtils.EVENT_TYPE_CONNECTED, null);
+ if (params != null && params.getBoolean(RecordingUtils.BUNDLE_IS_DVR, false)) {
+ notifySessionEvent(RecordingUtils.EVENT_TYPE_CONNECTED, null);
return true;
- } else if (params != null && params.containsKey(DvrUtils.BUNDLE_MEDIA_URI)) {
- onPlayMedia(Uri.parse(params.getString(DvrUtils.BUNDLE_CHANNEL_URI)));
+ } else if (params != null && params.containsKey(RecordingUtils.BUNDLE_MEDIA_URI)) {
+ mIsRecordingPlayback = true;
+ onPlayMedia(Uri.parse(params.getString(RecordingUtils.BUNDLE_MEDIA_URI)));
return true;
} else {
+ mIsRecordingPlayback = false;
return onTune(channelUri);
}
}
diff --git a/common/src/com/android/tv/common/dvr/DvrUtils.java b/common/src/com/android/tv/common/recording/RecordingUtils.java
index 0a3e536b..ae91659f 100644
--- a/common/src/com/android/tv/common/dvr/DvrUtils.java
+++ b/common/src/com/android/tv/common/recording/RecordingUtils.java
@@ -14,40 +14,37 @@
* limitations under the License.
*/
-package com.android.tv.common.dvr;
+package com.android.tv.common.recording;
import android.net.Uri;
import android.os.Bundle;
-public class DvrUtils {
+public class RecordingUtils {
static final int ACTION_START_RECORD = 10055;
static final int ACTION_STOP_RECORD = 10056;
static final String EVENT_TYPE_CONNECTED = "event_type_connected";
- static final String EVENT_TYPE_RECORD_STARTED = "event_type_record_started";
- static final String EVENT_TYPE_RECORD_STOPPED = "event_type_record_stopped";
- static final String EVENT_TYPE_DELETED = "event_type_deleted";
- static final String EVENT_TYPE_DELETE_FAILED = "event_type_delete_failed";
+ static final String EVENT_TYPE_TIMESHIFT_END_POSITION = "event_type_timeshift_end_position";
static final String APP_PRIV_CREATE_PLAYBACK_SESSION = "app_priv_create_playback_session";
static final String APP_PRIV_CREATE_DVR_SESSION = "app_priv_create_dvr_session";
- static final String APP_PRIV_START_RECORD = "app_priv_start_record";
- static final String APP_PRIV_STOP_RECORD = "app_priv_stop_record";
- static final String APP_PRIV_DELETE = "app_priv_delete";
+
// Type: boolean
static final String BUNDLE_IS_DVR = "bundle_is_dvr";
// Type: String (Uri)
static final String BUNDLE_MEDIA_URI = "bundle_media_uri";
// Type: String
static final String BUNDLE_CHANNEL_URI = "bundle_channel_uri";
- // Type: int
- static final String BUNDLE_STOPPED_REASON = "stopped_reason";
- // Type: int
- static final String BUNDLE_DELETE_FAILED_REASON = "delete_failed_reason";
+ // Type: long
+ static final String BUNDLE_TIMESHIFT_END_POSITION = "timeshift_end_position";
- static Bundle buildMediaUri(Uri mediaUri) {
+ /**
+ * Builds a {@link Bundle} with {@code mediaUri}. If the bundle is sent with tune command,
+ * the {@code mediaUri} will be played.
+ */
+ public static Bundle buildMediaUri(Uri mediaUri) {
Bundle params = new Bundle();
- params.putString(DvrUtils.BUNDLE_MEDIA_URI, mediaUri.toString());
+ params.putString(RecordingUtils.BUNDLE_MEDIA_URI, mediaUri.toString());
return params;
}
}
diff --git a/common/src/com/android/tv/common/recording/TvRecording.java b/common/src/com/android/tv/common/recording/TvRecording.java
new file mode 100644
index 00000000..28a611a0
--- /dev/null
+++ b/common/src/com/android/tv/common/recording/TvRecording.java
@@ -0,0 +1,384 @@
+/*
+ * 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.recording;
+
+import android.content.Context;
+import android.media.tv.TvContract;
+import android.media.tv.TvView;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.IntDef;
+import android.util.Log;
+import android.view.Surface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * API for making TV Recordings.
+ * This class holds both the API under development and the session app private command magic needed
+ * to simulate the API.
+ */
+public final class TvRecording {
+ private static final String TAG = "TvRecording";
+ private static final boolean DEBUG = true; // STOPSHIP(DVR)
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({RECORD_STOP_REASON_DISKFULL, RECORD_STOP_REASON_CONFLICT,
+ RECORD_STOP_REASON_CONNECT_FAILED, RECORD_STOP_REASON_DISCONNECTED,
+ RECORD_STOP_REASON_UNKNOWN})
+ public @interface RecordStopReason {
+ }
+
+ private static final int FIRST_REASON = 1;
+ public static final int RECORD_STOP_REASON_DISKFULL = 1;
+ public static final int RECORD_STOP_REASON_CONFLICT = 2;
+ public static final int RECORD_STOP_REASON_CONNECT_FAILED = 3;
+ public static final int RECORD_STOP_REASON_DISCONNECTED = 4;
+ public static final int RECORD_STOP_REASON_UNKNOWN = 5;
+ private static final int LAST_REASON = 5;
+
+ public abstract static class ClientCallback {
+ public void onConnected() { }
+
+ public void onDisconnected() { }
+
+ public void onRecordStarted(Uri mediaUri) { }
+
+ public void onRecordStopped(Uri mediaUri, @RecordStopReason int reason) { }
+
+ public void onRecordDeleted(Uri mediaUri) { }
+
+ public void onRecordDeleteFailed(Uri mediaUri, int reason) { }
+
+ public void onCapabilityReceived(RecordingCapability capability) { }
+ }
+
+ public interface RecordingClientApi {
+ void release();
+
+ void startRecord(Uri channelUri, Uri mediaUri);
+
+ void stopRecord();
+
+ void delete(Uri mediaUri);
+
+ void getCapability();
+ }
+
+ public interface RecordingSessionApi {
+ /**
+ * Start recording on {@code channelUri}.
+ * <p>{@link RecordingSession#notifyRecordStarted(Uri)} should be called as soon as the
+ * recording is started.
+ */
+ void onStartRecord(Uri channelUri, Uri mediaUri);
+
+ /**
+ * Called when it stops to record.
+ */
+ void onStopRecord();
+
+ /**
+ * Called when it is requested to delete {@code mediaUri}.
+ */
+ void onDelete(Uri mediaUri);
+
+ /**
+ * Called when the client request {@link RecordingCapability}.
+ */
+ RecordingCapability onGetCapability();
+ }
+
+ ///////////
+ // BELOW IS IMPLEMENTATION DETAILS OFTEN SPECIFIC TO USING APP PRIVATE COMMANDS
+ //////////
+
+ private static final String PREFIX = "record_";
+
+ private static final String APP_PRIV_DELETE = PREFIX + "app_priv_delete";
+ private static final String APP_PRIV_GET_CAPABILITY = PREFIX + "app_priv_get_capability";
+ private static final String APP_PRIV_START_RECORD = PREFIX + "app_priv_start_record";
+ private static final String APP_PRIV_STOP_RECORD = PREFIX + "app_priv_stop_record";
+
+ private static final String EVENT_TYPE_DELETED = PREFIX + "event_type_deleted";
+ private static final String EVENT_TYPE_DELETE_FAILED = PREFIX + "event_type_delete_failed";
+ private static final String EVENT_TYPE_CAPABILITY_RECEIVED = PREFIX
+ + "event_type_capability_received";
+ private static final String EVENT_TYPE_RECORD_STARTED = PREFIX + "event_type_record_started";
+ private static final String EVENT_TYPE_RECORD_STOPPED = PREFIX + "event_type_record_stopped";
+
+ // Type: int
+ private static final String BUNDLE_STOPPED_REASON = PREFIX + "stopped_reason";
+ // Type: int
+ private static final String BUNDLE_DELETE_FAILED_REASON = PREFIX + "delete_failed_reason";
+ // Type: RecordingCapability
+ private static final String BUNDLE_CAPABILITY = PREFIX + "capability";
+
+
+ /**
+ * Session linked to {@link TvRecordingClient} to record contents.
+ */
+ public static abstract class RecordingSession extends RecordingTvInputService.BaseSession
+ implements RecordingSessionApi {
+ private final static String TAG = "RecordingSession";
+
+ public RecordingSession(Context context) {
+ super(context);
+ }
+
+ @Override
+ public final boolean onTune(Uri channelUri) {
+ // no-op
+ return false;
+ }
+
+ @Override
+ public final boolean onSetSurface(Surface surface) {
+ // no-op
+ return false;
+ }
+
+ @Override
+ public final void onSetStreamVolume(float volume) {
+ // no-op
+ }
+
+ @Override
+ public final void onSetCaptionEnabled(boolean enabled) {
+ // no-op
+ }
+
+ /**
+ * Notifies when recording starts. It is an response of {@link #onStartRecord}.
+ */
+ public final void notifyRecordStarted(Uri mediaUri) {
+ notifySessionEvent(EVENT_TYPE_RECORD_STARTED, RecordingUtils.buildMediaUri(mediaUri));
+ }
+
+ /**
+ * Notifies when recording is unexpectedly stopped.
+ */
+ public final void notifyRecordUnexpectedlyStopped(Uri mediaUri, int reason) {
+ Bundle params = RecordingUtils.buildMediaUri(mediaUri);
+ params.putInt(BUNDLE_STOPPED_REASON, reason);
+ notifySessionEvent(EVENT_TYPE_RECORD_STOPPED, params);
+ }
+
+ /**
+ * Notifies when the recording {@code mediaUri} is deleted.
+ */
+ public final void notifyDeleted(Uri mediaUri) {
+ notifySessionEvent(EVENT_TYPE_DELETED, RecordingUtils.buildMediaUri(mediaUri));
+ }
+
+ /**
+ * Notifies when the deletion of the recording {@code mediaUri} is requested through
+ * {@link #onDelete} but failed.
+ */
+ public final void notifyDeleteFailed(Uri mediaUri, int reason) {
+ Bundle params = RecordingUtils.buildMediaUri(mediaUri);
+ params.putInt(BUNDLE_DELETE_FAILED_REASON, reason);
+ notifySessionEvent(EVENT_TYPE_DELETE_FAILED, params);
+ }
+
+ @Override
+ public final void onAppPrivateCommand(String action, Bundle data) {
+ if (DEBUG) Log.d(TAG, "onAppPrivateCommand(" + action + ", " + data + ")");
+ switch (action) {
+ case APP_PRIV_GET_CAPABILITY:
+ RecordingCapability capability = onGetCapability();
+ Bundle params = new Bundle();
+ params.putParcelable(BUNDLE_CAPABILITY, capability);
+ notifySessionEvent(EVENT_TYPE_CAPABILITY_RECEIVED, params);
+ break;
+ case APP_PRIV_DELETE:
+ onDelete(Uri.parse(data.getString(RecordingUtils.BUNDLE_CHANNEL_URI)));
+ break;
+ case APP_PRIV_START_RECORD:
+ onStartRecord(Uri.parse(data.getString(RecordingUtils.BUNDLE_CHANNEL_URI)),
+ Uri.parse(data.getString(RecordingUtils.BUNDLE_MEDIA_URI)));
+ break;
+ case APP_PRIV_STOP_RECORD:
+ onStopRecord();
+ break;
+ }
+ }
+ }
+
+ /**
+ * A session used for recording.
+ */
+ public static class TvRecordingClient implements RecordingClientApi {
+ private static final String TAG = "DvrSessionClient";
+
+ private ClientCallback mCallback;
+ private TvView mTvView;
+
+ public TvRecordingClient(Context context) {
+ if (DEBUG) {
+ Log.d(TAG, "creating client");
+ }
+ mTvView = new TvView(context);
+ }
+
+ /**
+ * Connects the session to a specific input {@code inputId}.
+ */
+ public void connect(String inputId, ClientCallback callback) {
+ if (DEBUG) {
+ Log.d(TAG, "connect " + inputId + " with " + callback);
+ }
+ mCallback = callback;
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(RecordingUtils.BUNDLE_IS_DVR, true);
+ mTvView.tune(inputId, TvContract.buildChannelUri(0), bundle);
+ mTvView.sendAppPrivateCommand(RecordingUtils.APP_PRIV_CREATE_DVR_SESSION, null);
+ mTvView.setCallback(new TvView.TvInputCallback() {
+ @Override
+ public void onConnectionFailed(String inputId) {
+ if (mCallback == null) {
+ return;
+ }
+ mCallback.onDisconnected();
+ }
+
+ @Override
+ public void onDisconnected(String inputId) {
+ if (mCallback == null) {
+ return;
+ }
+ mCallback.onDisconnected();
+ }
+
+ @Override
+ public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+ if (mCallback == null) {
+ return;
+ }
+ String mediaUriString = eventArgs == null ? null
+ : eventArgs.getString(RecordingUtils.BUNDLE_MEDIA_URI, null);
+ Uri mediaUri = mediaUriString == null ? null : Uri.parse(mediaUriString);
+ switch (eventType) {
+ case RecordingUtils.EVENT_TYPE_CONNECTED:
+ mCallback.onConnected();
+ break;
+ case EVENT_TYPE_DELETED:
+ mCallback.onRecordDeleted(mediaUri);
+ break;
+ case EVENT_TYPE_DELETE_FAILED: {
+ // TODO(DVR) use reasons from API
+ int reason = eventArgs == null ? 0
+ : eventArgs.getInt(BUNDLE_DELETE_FAILED_REASON);
+ mCallback.onRecordDeleteFailed(mediaUri, reason);
+ break;
+ }
+ case EVENT_TYPE_CAPABILITY_RECEIVED: {
+ RecordingCapability capability = eventArgs
+ .getParcelable(BUNDLE_CAPABILITY);
+ mCallback.onCapabilityReceived(capability);
+ break;
+ }
+ case EVENT_TYPE_RECORD_STARTED:
+ mCallback.onRecordStarted(mediaUri);
+ break;
+ case EVENT_TYPE_RECORD_STOPPED: {
+ int reason = getRecordStopReason(eventArgs);
+ mCallback.onRecordStopped(mediaUri, reason);
+ break;
+ }
+ }
+ }
+
+ // TODO: handle track select.
+ });
+ }
+
+ /**
+ * Releases the session.
+ */
+ @Override
+ public void release() {
+ if (DEBUG) {
+ Log.d(TAG, "release " + this);
+ }
+ mTvView.reset();
+ mCallback = null;
+ }
+
+ /**
+ * Starts recording.
+ */
+ @Override
+ public void startRecord(Uri channelUri, Uri mediaUri) {
+ if (DEBUG) {
+ Log.d(TAG, "startRecord " + channelUri + ", " + mediaUri);
+ }
+ Bundle params = RecordingUtils.buildMediaUri(mediaUri);
+ params.putString(RecordingUtils.BUNDLE_CHANNEL_URI, channelUri.toString());
+ mTvView.sendAppPrivateCommand(APP_PRIV_START_RECORD, params);
+ }
+
+ /**
+ * Stops recording.
+ */
+ @Override
+ public void stopRecord() {
+ if (DEBUG) {
+ Log.d(TAG, "stopRecord " + this);
+ }
+ mTvView.sendAppPrivateCommand(APP_PRIV_STOP_RECORD, null);
+ }
+
+ /**
+ * Deletes a recorded media.
+ */
+ @Override
+ public void delete(Uri mediaUri) {
+ mTvView.sendAppPrivateCommand(APP_PRIV_DELETE,
+ RecordingUtils.buildMediaUri(mediaUri));
+ }
+
+ @Override
+ public void getCapability() {
+ mTvView.sendAppPrivateCommand(APP_PRIV_GET_CAPABILITY, null);
+ }
+
+ @Override
+ public String toString() {
+ return TvRecordingClient.class.getName() + "{" + "callBack=" + mCallback + "}";
+ }
+ }
+
+ @SuppressWarnings("ResourceType")
+ @RecordStopReason
+ private static int getRecordStopReason(Bundle eventArgs) {
+ if(eventArgs == null) {
+ if (DEBUG) Log.d(TAG, "Null stop reason");
+ return RECORD_STOP_REASON_UNKNOWN;
+ }
+ int reason = eventArgs.getInt(BUNDLE_STOPPED_REASON);
+ if (reason < FIRST_REASON || reason > LAST_REASON) {
+ if (DEBUG) Log.d(TAG, "Unknown stop reason " + reason);
+ reason = RECORD_STOP_REASON_UNKNOWN;
+ }
+ return reason;
+ }
+
+ private TvRecording() {
+ }
+}
diff --git a/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java b/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
index 39af2d83..15b38f02 100644
--- a/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
+++ b/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
@@ -23,7 +23,8 @@ public interface OnActionClickListener {
/**
* Called when the action is clicked.
*
+ * @param category action category.
* @param id action id.
*/
- void onActionClick(int id);
+ void onActionClick(String category, int id);
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java b/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
index ed999990..0f44ce06 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
@@ -17,6 +17,8 @@
package com.android.tv.common.ui.setup;
import android.app.Fragment;
+import android.view.View;
+import android.view.View.OnClickListener;
/**
* Helper class for the execution in the fragment.
@@ -25,9 +27,46 @@ public class SetupActionHelper {
/**
* Executes the action of the given {@code actionId}.
*/
- public static void onActionClick(Fragment fragment, int actionId) {
- if (fragment.getActivity() instanceof OnActionClickListener) {
- ((OnActionClickListener) fragment.getActivity()).onActionClick(actionId);
+ public static void onActionClick(Fragment fragment, String category, int actionId) {
+ OnActionClickListener listener = null;
+ if (fragment instanceof SetupFragment) {
+ listener = ((SetupFragment) fragment).getOnActionClickListener();
+ }
+ if (listener == null && fragment.getActivity() instanceof OnActionClickListener) {
+ listener = (OnActionClickListener) fragment.getActivity();
+ }
+ if (listener != null) {
+ listener.onActionClick(category, actionId);
}
}
+
+ /**
+ * Creates an {@link OnClickListener} to handle the action.
+ */
+ public static OnClickListener createOnClickListenerForAction(OnActionClickListener listener,
+ String category, int actionId) {
+ return new OnActionClickListenerForAction(listener, category, actionId);
+ }
+
+ private static class OnActionClickListenerForAction implements OnClickListener {
+ private final OnActionClickListener mListener;
+ private final String mCategory;
+ private final int mActionId;
+
+ OnActionClickListenerForAction(OnActionClickListener listener, String category,
+ int actionId) {
+ mListener = listener;
+ mCategory = category;
+ mActionId = actionId;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mListener != null) {
+ mListener.onActionClick(mCategory, mActionId);
+ }
+ }
+ }
+
+ private SetupActionHelper() { }
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupActivity.java b/common/src/com/android/tv/common/ui/setup/SetupActivity.java
new file mode 100644
index 00000000..8c7b1b8e
--- /dev/null
+++ b/common/src/com/android/tv/common/ui/setup/SetupActivity.java
@@ -0,0 +1,168 @@
+/*
+ * 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.ui.setup;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.annotation.NonNull;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.view.View;
+import android.view.ViewTreeObserver.OnPreDrawListener;
+
+import com.android.tv.common.R;
+import com.android.tv.common.WeakHandler;
+import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
+
+/**
+ * Setup activity for onboarding screens or TIS.
+ *
+ * <p>The inherited class should add theme {@code Theme.Setup.GuidedStep} to its definition in
+ * AndroidManifest.xml.
+ */
+public abstract class SetupActivity extends Activity implements OnActionClickListener {
+ private static final int MSG_EXECUTE_ACTION = 1;
+
+ private boolean mShowInitialFragment = true;
+ private long mFragmentTransitionDuration;
+ private final Handler mHandler = new SetupActivityHandler(this);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_setup);
+ mFragmentTransitionDuration = getResources().getInteger(
+ R.integer.setup_fragment_transition_duration);
+ // Show initial fragment only when the saved state is not restored, because the last
+ // fragment is restored if savesInstanceState is not null.
+ if (savedInstanceState == null) {
+ // This is the workaround to show the first fragment with delay to show the fragment
+ // enter transition. See http://b/26255145
+ getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(
+ new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ getWindow().getDecorView().getViewTreeObserver()
+ .removeOnPreDrawListener(this);
+ showInitialFragment();
+ return true;
+ }
+ });
+ } else {
+ mShowInitialFragment = false;
+ }
+ }
+
+ /**
+ * The inherited class should provide the initial fragment to show.
+ *
+ * <p>If this method returns {@code null} during {@link #onCreate}, then call
+ * {@link #showInitialFragment} explicitly later with non null initial fragment.
+ */
+ protected abstract Fragment onCreateInitialFragment();
+
+ /**
+ * Shows the initial fragment.
+ *
+ * <p>The inherited class can call this method later explicitly if it doesn't want the initial
+ * fragment to be shown in onCreate().
+ */
+ protected void showInitialFragment() {
+ if (!mShowInitialFragment) {
+ return;
+ }
+ Fragment fragment = onCreateInitialFragment();
+ if (fragment != null) {
+ showFragment(fragment, false);
+ mShowInitialFragment = false;
+ }
+ }
+
+ /**
+ * Shows the given fragment.
+ */
+ protected FragmentTransaction showFragment(Fragment fragment, boolean addToBackStack) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ if (fragment instanceof SetupFragment) {
+ int[] sharedElements = ((SetupFragment) fragment).getSharedElementIds();
+ if (sharedElements != null && sharedElements.length > 0) {
+ Transition sharedTransition = TransitionInflater.from(this)
+ .inflateTransition(R.transition.transition_action_background);
+ sharedTransition.setDuration(getSharedElementTransitionDuration());
+ SetupAnimationHelper.applyAnimationTimeScale(sharedTransition);
+ fragment.setSharedElementEnterTransition(sharedTransition);
+ fragment.setSharedElementReturnTransition(sharedTransition);
+ for (int id : sharedElements) {
+ View sharedView = findViewById(id);
+ if (sharedView != null) {
+ ft.addSharedElement(sharedView, sharedView.getTransitionName());
+ }
+ }
+ }
+ }
+ String tag = fragment.getClass().getCanonicalName();
+ if (addToBackStack) {
+ ft.addToBackStack(tag);
+ }
+ ft.replace(R.id.fragment_container, fragment, tag).commit();
+
+ return ft;
+ }
+
+ @Override
+ public void onActionClick(String category, int actionId) {
+ if (mHandler.hasMessages(MSG_EXECUTE_ACTION)) {
+ return;
+ }
+ executeAction(category, actionId);
+ }
+
+ protected void executeActionWithDelay(Runnable action, int delayMs) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_EXECUTE_ACTION, action), delayMs);
+ }
+
+ // Override this method if the inherited class wants to handle the action.
+ protected void executeAction(String category, int actionId) { }
+
+ /**
+ * Returns the duration of the shared element transition.
+ *
+ * <p>It's (exit transition) + (delayed animation) + (enter transition).
+ */
+ private long getSharedElementTransitionDuration() {
+ return (mFragmentTransitionDuration + SetupAnimationHelper.DELAY_BETWEEN_SIBLINGS_MS) * 2;
+ }
+
+ private static class SetupActivityHandler extends WeakHandler<SetupActivity> {
+ SetupActivityHandler(SetupActivity activity) {
+ // Should run on main thread because onAc3SupportChanged will be called on main thread.
+ super(Looper.getMainLooper(), activity);
+ }
+
+ @Override
+ protected void handleMessage(Message msg, @NonNull SetupActivity activity) {
+ if (msg.what == MSG_EXECUTE_ACTION) {
+ ((Runnable) msg.obj).run();
+ }
+ }
+ }
+}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupFragment.java b/common/src/com/android/tv/common/ui/setup/SetupFragment.java
index 0ae96d63..df7256d3 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupFragment.java
@@ -20,6 +20,7 @@ import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -41,14 +42,54 @@ public abstract class SetupFragment extends Fragment {
value = {FRAGMENT_ENTER_TRANSITION, FRAGMENT_EXIT_TRANSITION,
FRAGMENT_REENTER_TRANSITION, FRAGMENT_RETURN_TRANSITION})
public @interface FragmentTransitionType {}
- protected static final int FRAGMENT_ENTER_TRANSITION = 0x01;
- protected static final int FRAGMENT_EXIT_TRANSITION = FRAGMENT_ENTER_TRANSITION << 1;
- protected static final int FRAGMENT_REENTER_TRANSITION = FRAGMENT_ENTER_TRANSITION << 2;
- protected static final int FRAGMENT_RETURN_TRANSITION = FRAGMENT_ENTER_TRANSITION << 3;
+ public static final int FRAGMENT_ENTER_TRANSITION = 0x01;
+ public static final int FRAGMENT_EXIT_TRANSITION = FRAGMENT_ENTER_TRANSITION << 1;
+ public static final int FRAGMENT_REENTER_TRANSITION = FRAGMENT_ENTER_TRANSITION << 2;
+ public static final int FRAGMENT_RETURN_TRANSITION = FRAGMENT_ENTER_TRANSITION << 3;
+
+ private OnActionClickListener mOnActionClickListener;
+
+ private boolean mEnterTransitionRunning;
+
+ private TransitionListener mTransitionListener = new TransitionListener() {
+ @Override
+ public void onTransitionStart(Transition transition) {
+ mEnterTransitionRunning = true;
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ mEnterTransitionRunning = false;
+ onEnterTransitionEnd();
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) { }
+
+ @Override
+ public void onTransitionPause(Transition transition) { }
+
+ @Override
+ public void onTransitionResume(Transition transition) { }
+ };
+
+ /**
+ * Returns {@code true} if the enter/reenter transition is running.
+ */
+ protected boolean isEnterTransitionRunning() {
+ return mEnterTransitionRunning;
+ }
+
+ /**
+ * Called when the enter/reenter transition ends.
+ */
+ protected void onEnterTransitionEnd() { }
public SetupFragment() {
setAllowEnterTransitionOverlap(false);
setAllowReturnTransitionOverlap(false);
+ enableFragmentTransition(FRAGMENT_ENTER_TRANSITION | FRAGMENT_EXIT_TRANSITION
+ | FRAGMENT_REENTER_TRANSITION | FRAGMENT_RETURN_TRANSITION);
}
@Override
@@ -62,21 +103,51 @@ public abstract class SetupFragment extends Fragment {
}
/**
+ * Returns action click listener.
+ */
+ public OnActionClickListener getOnActionClickListener() {
+ return mOnActionClickListener;
+ }
+
+ /**
+ * Sets action click listener.
+ */
+ public void setOnActionClickListener(OnActionClickListener onActionClickListener) {
+ mOnActionClickListener = onActionClickListener;
+ }
+
+ /**
* Returns the layout resource ID for this fragment.
*/
- protected abstract int getLayoutResourceId();
+ abstract protected int getLayoutResourceId();
- protected void setOnClickAction(View view, final int actionId) {
+ protected void setOnClickAction(View view, final String category, final int actionId) {
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
- onActionClick(actionId);
+ onActionClick(category, actionId);
}
});
}
- protected void onActionClick(int actionId) {
- SetupActionHelper.onActionClick(this, actionId);
+ protected void onActionClick(String category, int actionId) {
+ SetupActionHelper.onActionClick(this, category, actionId);
+ }
+
+ @Override
+ public void setEnterTransition(Transition transition) {
+ super.setEnterTransition(transition);
+ if (transition != null) {
+ transition.addListener(mTransitionListener);
+ }
+ }
+
+ @Override
+ public void setReenterTransition(Transition transition) {
+ super.setReenterTransition(transition);
+ if (transition != null) {
+ transition.addListener(mTransitionListener);
+ }
}
/**
@@ -100,8 +171,7 @@ public abstract class SetupFragment extends Fragment {
/**
* Sets the transition with the given {@code slidEdge}.
*/
- protected void setFragmentTransition(@FragmentTransitionType int transitionType,
- int slideEdge) {
+ public void setFragmentTransition(@FragmentTransitionType int transitionType, int slideEdge) {
switch (transitionType) {
case FRAGMENT_ENTER_TRANSITION:
setEnterTransition(createTransition(slideEdge));
@@ -127,46 +197,32 @@ public abstract class SetupFragment extends Fragment {
}
/**
- * Sets the distance of the fragment transition.
+ * Changes the move distance of the transitions to short distance.
*/
- public void setTransitionDistance(int distance) {
- Transition transition = getEnterTransition();
- if (transition instanceof FadeAndShortSlide) {
- ((FadeAndShortSlide) transition).setDistance(distance);
- }
- transition = getExitTransition();
- if (transition instanceof FadeAndShortSlide) {
- ((FadeAndShortSlide) transition).setDistance(distance);
- }
- transition = getReenterTransition();
- if (transition instanceof FadeAndShortSlide) {
- ((FadeAndShortSlide) transition).setDistance(distance);
- }
- transition = getReturnTransition();
- if (transition instanceof FadeAndShortSlide) {
- ((FadeAndShortSlide) transition).setDistance(distance);
- }
- }
-
- /**
- * Sets the duration of the fragment transition.
- */
- public void setTransitionDuration(long duration) {
- Transition transition = getEnterTransition();
- if (transition != null) {
- transition.setDuration(duration);
+ public void setShortDistance(@FragmentTransitionType int mask) {
+ if ((mask & FRAGMENT_ENTER_TRANSITION) != 0) {
+ Transition transition = getEnterTransition();
+ if (transition instanceof FadeAndShortSlide) {
+ SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
+ }
}
- transition = getExitTransition();
- if (transition != null) {
- transition.setDuration(duration);
+ if ((mask & FRAGMENT_EXIT_TRANSITION) != 0) {
+ Transition transition = getExitTransition();
+ if (transition instanceof FadeAndShortSlide) {
+ SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
+ }
}
- transition = getReenterTransition();
- if (transition != null) {
- transition.setDuration(duration);
+ if ((mask & FRAGMENT_REENTER_TRANSITION) != 0) {
+ Transition transition = getReenterTransition();
+ if (transition instanceof FadeAndShortSlide) {
+ SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
+ }
}
- transition = getReturnTransition();
- if (transition != null) {
- transition.setDuration(duration);
+ if ((mask & FRAGMENT_RETURN_TRANSITION) != 0) {
+ Transition transition = getReturnTransition();
+ if (transition instanceof FadeAndShortSlide) {
+ SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
+ }
}
}
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 65575adc..aa912a97 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
@@ -24,8 +24,8 @@ import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.LinearLayout;
import com.android.tv.common.R;
@@ -45,37 +45,31 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
Bundle arguments = getArguments();
- view.findViewById(R.id.action_fragment).setPadding(0, 0, 0, 0);
+ view.findViewById(R.id.action_fragment_root).setPadding(0, 0, 0, 0);
+ LinearLayout.LayoutParams guidanceLayoutParams = (LinearLayout.LayoutParams)
+ view.findViewById(R.id.content_fragment).getLayoutParams();
+ guidanceLayoutParams.weight = 0;
if (arguments != null && arguments.getBoolean(KEY_THREE_PANE, false)) {
- boolean isRtl = view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
// Content fragment.
- LayoutParams layoutParams = view.findViewById(R.id.content_fragment).getLayoutParams();
- layoutParams.width = getResources().getDimensionPixelOffset(
- R.dimen.setup_guidedstep_guidance_section_width_3pane);
+ guidanceLayoutParams.width = getResources().getDimensionPixelOffset(
+ R.dimen.setup_guidedstep_guidance_section_width_3pane);
int doneButtonWidth = getResources().getDimensionPixelOffset(
R.dimen.setup_done_button_container_width);
- // Guided actions selector.
- int endMargin = getResources().getDimensionPixelOffset(
- R.dimen.setup_guidedactions_selector_margin_end);
+ // Guided actions list
+ View list = view.findViewById(R.id.guidedactions_list);
+ View list2 = view.findViewById(R.id.guidedactions_list2);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.findViewById(
- R.id.guidedactions_selector).getLayoutParams();
- if (isRtl) {
- marginLayoutParams.leftMargin = endMargin + doneButtonWidth;
+ R.id.guidedactions_list).getLayoutParams();
+ // Use content view to check layout direction while view is being created.
+ if (getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_LTR) {
+ marginLayoutParams.rightMargin = doneButtonWidth;
} else {
- marginLayoutParams.rightMargin = endMargin + doneButtonWidth;
- }
- // Guided actions list
- marginLayoutParams = (MarginLayoutParams) view.findViewById(R.id.guidedactions_list)
- .getLayoutParams();
- if (isRtl) {
marginLayoutParams.leftMargin = doneButtonWidth;
- } else {
- marginLayoutParams.rightMargin = doneButtonWidth;
}
} else {
// Content fragment.
- LayoutParams layoutParams = view.findViewById(R.id.content_fragment).getLayoutParams();
- layoutParams.width = getResources().getDimensionPixelOffset(
+ guidanceLayoutParams.width = getResources().getDimensionPixelOffset(
R.dimen.setup_guidedstep_guidance_section_width_2pane);
}
// gridView Alignment
@@ -91,6 +85,8 @@ 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;
}
@@ -110,13 +106,20 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
};
}
+ abstract protected String getActionCategory();
+
@Override
public void onGuidedActionClicked(GuidedAction action) {
- SetupActionHelper.onActionClick(this, (int) action.getId());
+ SetupActionHelper.onActionClick(this, getActionCategory(), (int) action.getId());
}
@Override
protected void onProvideFragmentTransitions() {
// Don't use the fragment transition defined in GuidedStepFragment.
}
+
+ @Override
+ public boolean isFocusOutEndAllowed() {
+ return true;
+ }
}
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 fa946ae3..fea9bf4a 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
@@ -28,12 +28,7 @@ import com.android.tv.common.R;
* A fragment for channel source info/setup.
*/
public abstract class SetupMultiPaneFragment extends SetupFragment {
- public static final int ACTION_DONE = 1;
-
- public SetupMultiPaneFragment() {
- enableFragmentTransition(FRAGMENT_ENTER_TRANSITION | FRAGMENT_EXIT_TRANSITION
- | FRAGMENT_REENTER_TRANSITION | FRAGMENT_RETURN_TRANSITION);
- }
+ public static final int ACTION_DONE = Integer.MAX_VALUE;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -43,10 +38,12 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
getChildFragmentManager().beginTransaction()
.replace(R.id.guided_step_fragment_container, contentFragment).commit();
if (needsDoneButton()) {
- setOnClickAction(view.findViewById(R.id.button_done), ACTION_DONE);
+ setOnClickAction(view.findViewById(R.id.button_done), getActionCategory(), ACTION_DONE);
} else {
View doneButtonContainer = view.findViewById(R.id.done_button_container);
- if (view.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
+ // Use content view to check layout direction while view is being created.
+ if (getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_LTR) {
((MarginLayoutParams) doneButtonContainer.getLayoutParams()).rightMargin =
-getResources().getDimensionPixelOffset(
R.dimen.setup_done_button_container_width);
@@ -67,6 +64,8 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
abstract protected SetupGuidedStepFragment onCreateContentFragment();
+ abstract protected String getActionCategory();
+
protected boolean needsDoneButton() {
return true;
}
@@ -78,6 +77,6 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
@Override
public int[] getSharedElementIds() {
- return new int[] {R.id.guidedactions_background, R.id.done_button_container};
+ return new int[] {R.id.action_fragment_background, R.id.done_button_container};
}
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupStep.java b/common/src/com/android/tv/common/ui/setup/SetupStep.java
deleted file mode 100644
index 7545906d..00000000
--- a/common/src/com/android/tv/common/ui/setup/SetupStep.java
+++ /dev/null
@@ -1,75 +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.ui.setup;
-
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.support.annotation.Nullable;
-
-/**
- * An interface for the setup step.
- */
-public abstract class SetupStep {
- private final SetupStep mPreviousStep;
- private final int mPreviousBackStackRecordCount;
- private Fragment mFragment;
-
- public SetupStep(FragmentManager fragmentManager, @Nullable SetupStep previousStep) {
- mPreviousStep = previousStep;
- mPreviousBackStackRecordCount = fragmentManager.getBackStackEntryCount();
- }
-
- /**
- * Creates and Returns a fragment for this step.
- */
- public Fragment createFragment() {
- mFragment = onCreateFragment();
- return mFragment;
- }
-
- /**
- * Returns fragment to represent this step.
- */
- protected abstract Fragment onCreateFragment();
-
- /**
- * Executes the given action.
- */
- public abstract void executeAction(int actionId);
-
- /**
- * Returns the back stack record count at the moment when this step starts.
- */
- public int getPreviousBackStackRecordCount() {
- return mPreviousBackStackRecordCount;
- }
-
- /**
- * Returns the previous step.
- */
- @Nullable
- public SetupStep getPreviousStep() {
- return mPreviousStep;
- }
-
- /**
- * Returns the fragment which represents this step.
- */
- public Fragment getFragment() {
- return mFragment;
- }
-}
diff --git a/common/src/com/android/tv/common/ui/setup/SteppedSetupActivity.java b/common/src/com/android/tv/common/ui/setup/SteppedSetupActivity.java
deleted file mode 100644
index 984c6c7f..00000000
--- a/common/src/com/android/tv/common/ui/setup/SteppedSetupActivity.java
+++ /dev/null
@@ -1,148 +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.ui.setup;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager.OnBackStackChangedListener;
-import android.app.FragmentTransaction;
-import android.os.Bundle;
-import android.transition.Transition;
-import android.transition.TransitionInflater;
-import android.view.View;
-
-import com.android.tv.common.R;
-import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
-
-/**
- * Stepped setup activity for onboarding screens or setup activity for TIS.
- *
- * <p>The inherited class should add theme {@code Theme.Setup.GuidedStep} to its definition in
- * AndroidManifest.xml.
- */
-public abstract class SteppedSetupActivity extends Activity implements OnActionClickListener {
- private boolean mStartedInitialStep = false;
- private SetupStep mStep;
- private long mFragmentTransitionDuration;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_stepped_setup);
- startInitialStep();
- getFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() {
- @Override
- public void onBackStackChanged() {
- if (mStep != null) {
- // Need to change step to the previous one if the current step is popped from
- // the back stack.
- if (getFragmentManager().getBackStackEntryCount()
- <= mStep.getPreviousBackStackRecordCount()) {
- mStep = mStep.getPreviousStep();
- }
- }
- }
- });
- mFragmentTransitionDuration = getResources().getInteger(
- R.integer.setup_fragment_transition_duration);
- SetupAnimationHelper.setFragmentTransitionDuration(mFragmentTransitionDuration);
- SetupAnimationHelper.setFragmentTransitionDistance(getResources().getDimensionPixelOffset(
- R.dimen.setup_fragment_transition_distance));
- }
-
- /**
- * Returns the current step.
- */
- public SetupStep getCurrentStep() {
- return mStep;
- }
-
- /**
- * The inherited class should provide the initial step.
- *
- * <p>If this method returns {@code null} during {@link #onCreate}, then call
- * {@link #startInitialStep} explicitly later with non null initial setup step.
- *
- * @see SetupStep
- */
- protected abstract SetupStep onCreateInitialStep();
-
- /**
- * Starts the initial step.
- *
- * <p>The inherited class can call this method later explicitly if it doesn't want the initial
- * step to be started in onCreate().
- *
- * @see SetupStep
- */
- protected void startInitialStep() {
- if (mStartedInitialStep) {
- return;
- }
- SetupStep step = onCreateInitialStep();
- if (step != null) {
- startStep(step, false);
- mStartedInitialStep = true;
- }
- }
-
- /**
- * Starts next step.
- */
- protected FragmentTransaction startStep(SetupStep step, boolean addToBackStack) {
- mStep = step;
- Fragment fragment = step.createFragment();
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- if (fragment instanceof SetupFragment) {
- int[] sharedElements = ((SetupFragment) fragment).getSharedElementIds();
- if (sharedElements != null && sharedElements.length > 0) {
- Transition sharedTransition = TransitionInflater.from(this)
- .inflateTransition(R.transition.transition_action_background);
- sharedTransition.setDuration(getSharedElementTransitionDuration());
- SetupAnimationHelper.applyAnimationTimeScale(sharedTransition);
- fragment.setSharedElementEnterTransition(sharedTransition);
- fragment.setSharedElementReturnTransition(sharedTransition);
- for (int id : sharedElements) {
- View sharedView = findViewById(id);
- if (sharedView != null) {
- ft.addSharedElement(sharedView, sharedView.getTransitionName());
- }
- }
- }
- }
- if (addToBackStack) {
- ft.addToBackStack(null);
- }
- ft.replace(R.id.fragment_container, fragment).commit();
-
- return ft;
- }
-
- @Override
- public void onActionClick(int actionId) {
- mStep.executeAction(actionId);
- }
-
- /**
- * Returns the duration of the shared element transition.
- *
- * <p>It's (exit transition) + (delayed animation) + (enter transition).
- */
- private long getSharedElementTransitionDuration() {
- return (mFragmentTransitionDuration + SetupAnimationHelper.DELAY_BETWEEN_SIBLINGS_MS) * 2;
- }
-}
diff --git a/common/src/com/android/tv/common/ui/setup/animation/CustomTransition.java b/common/src/com/android/tv/common/ui/setup/animation/CustomTransition.java
deleted file mode 100644
index 58d9b695..00000000
--- a/common/src/com/android/tv/common/ui/setup/animation/CustomTransition.java
+++ /dev/null
@@ -1,54 +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.ui.setup.animation;
-
-import android.animation.Animator;
-import android.transition.Transition;
-import android.transition.TransitionValues;
-import android.view.ViewGroup;
-
-/**
- * Simple custom transition.
- */
-public class CustomTransition extends Transition {
- private CustomTransitionProvider mTransitionProvider;
-
- public CustomTransition(CustomTransitionProvider transitionProvider) {
- mTransitionProvider = transitionProvider;
- }
-
- @Override
- public void captureStartValues(TransitionValues transitionValues) {
- }
-
- @Override
- public void captureEndValues(TransitionValues transitionValues) {
- }
-
- @Override
- public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- Animator animator;
- if (startValues != null) {
- animator = mTransitionProvider.onDisappear(sceneRoot, startValues.view, startValues,
- endValues);
- } else {
- animator = mTransitionProvider.onAppear(sceneRoot, endValues.view, startValues,
- endValues);
- }
- return animator == null ? null : SetupAnimationHelper.applyAnimationTimeScale(animator);
- }
-}
diff --git a/common/src/com/android/tv/common/ui/setup/animation/CustomTransitionProvider.java b/common/src/com/android/tv/common/ui/setup/animation/CustomTransitionProvider.java
deleted file mode 100644
index 5f492503..00000000
--- a/common/src/com/android/tv/common/ui/setup/animation/CustomTransitionProvider.java
+++ /dev/null
@@ -1,43 +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.ui.setup.animation;
-
-import android.animation.Animator;
-import android.transition.TransitionValues;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Provides custom fragment transition animation.
- */
-public interface CustomTransitionProvider {
- /**
- * Create appearing animator.
- *
- * @see android.transition.Visibility#onAppear
- */
- Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
- TransitionValues endValues);
-
- /**
- * Create disappearing animator.
- *
- * @see android.transition.Visibility#onDisappear
- */
- Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
- TransitionValues endValues);
-}
-
diff --git a/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java b/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
index 0bd9f7b2..28ab97de 100644
--- a/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
+++ b/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
@@ -26,9 +26,15 @@ import android.transition.Visibility;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
/**
* Execute horizontal slide of 1/4 width and fade (to workaround bug 23718734)
*/
@@ -76,12 +82,15 @@ public class FadeAndShortSlide extends Visibility {
}
};
+ private static final ViewPositionComparator sViewPositionComparator =
+ new ViewPositionComparator();
+
+ private int mSlideEdge;
private CalculateSlide mSlideCalculator = sCalculateEnd;
private Visibility mFade = new Fade();
// TODO: Consider using TransitionPropagation.
private int[] mParentIdsForDelay;
- private boolean mDelayChildFound;
private int mDistance = DEFAULT_DISTANCE;
public FadeAndShortSlide() {
@@ -110,16 +119,23 @@ public class FadeAndShortSlide extends Visibility {
transitionValues.values.put(PROPNAME_SCREEN_POSITION, position);
}
- private int getDelayOrder(View view) {
+ private int getDelayOrder(View view, boolean appear) {
if (mParentIdsForDelay == null) {
return -1;
}
- View parentForDelay = findParentForDelay(view);
+ final View parentForDelay = findParentForDelay(view);
if (parentForDelay == null || !(parentForDelay instanceof ViewGroup)) {
return -1;
}
- mDelayChildFound = false;
- return getTransitionTargetIndex((ViewGroup) parentForDelay, view, 0);
+ List<View> transitionTargets = new ArrayList<>();
+ getTransitionTargets((ViewGroup) parentForDelay, transitionTargets);
+ sViewPositionComparator.mParentForDelay = parentForDelay;
+ sViewPositionComparator.mIsLtr = view.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
+ sViewPositionComparator.mToLeft = sViewPositionComparator.mIsLtr
+ ? mSlideEdge == (appear ? Gravity.END : Gravity.START)
+ : mSlideEdge == (appear ? Gravity.START : Gravity.END);
+ Collections.sort(transitionTargets, sViewPositionComparator);
+ return transitionTargets.indexOf(view);
}
private View findParentForDelay(View view) {
@@ -145,28 +161,16 @@ public class FadeAndShortSlide extends Visibility {
return false;
}
- private int getTransitionTargetIndex(ViewGroup parent, View view, int delayIndex) {
- int checked = 0;
+ private void getTransitionTargets(ViewGroup parent, List<View> transitionTargets) {
int count = parent.getChildCount();
for (int i = 0; i < count; ++i) {
View child = parent.getChildAt(i);
if (child instanceof ViewGroup && !((ViewGroup) child).isTransitionGroup()) {
- int result = getTransitionTargetIndex((ViewGroup) child, view, delayIndex);
- if (mDelayChildFound) {
- return delayIndex + result;
- }
- delayIndex += result;
- checked += result;
+ getTransitionTargets((ViewGroup) child, transitionTargets);
} else {
- if (child == view) {
- mDelayChildFound = true;
- return delayIndex;
- }
- ++delayIndex;
- ++checked;
+ transitionTargets.add(child);
}
}
- return checked;
}
@Override
@@ -174,7 +178,7 @@ public class FadeAndShortSlide extends Visibility {
super.captureStartValues(transitionValues);
mFade.captureStartValues(transitionValues);
captureValues(transitionValues);
- int delayIndex = getDelayOrder(transitionValues.view);
+ int delayIndex = getDelayOrder(transitionValues.view, false);
if (delayIndex > 0) {
transitionValues.values.put(PROPNAME_DELAY,
delayIndex * SetupAnimationHelper.DELAY_BETWEEN_SIBLINGS_MS);
@@ -186,7 +190,7 @@ public class FadeAndShortSlide extends Visibility {
super.captureEndValues(transitionValues);
mFade.captureEndValues(transitionValues);
captureValues(transitionValues);
- int delayIndex = getDelayOrder(transitionValues.view);
+ int delayIndex = getDelayOrder(transitionValues.view, true);
if (delayIndex > 0) {
transitionValues.values.put(PROPNAME_DELAY,
delayIndex * SetupAnimationHelper.DELAY_BETWEEN_SIBLINGS_MS);
@@ -194,6 +198,7 @@ public class FadeAndShortSlide extends Visibility {
}
public void setSlideEdge(int slideEdge) {
+ mSlideEdge = slideEdge;
switch (slideEdge) {
case Gravity.START:
mSlideCalculator = sCalculateStart;
@@ -272,8 +277,7 @@ public class FadeAndShortSlide extends Visibility {
@Override
public Transition clone() {
- FadeAndShortSlide clone = null;
- clone = (FadeAndShortSlide) super.clone();
+ FadeAndShortSlide clone = (FadeAndShortSlide) super.clone();
clone.mFade = (Visibility) mFade.clone();
return clone;
}
@@ -291,4 +295,78 @@ public class FadeAndShortSlide extends Visibility {
public void setDistance(int distance) {
mDistance = distance;
}
+
+ private static class ViewPositionComparator implements Comparator<View> {
+ View mParentForDelay;
+ boolean mIsLtr;
+ boolean mToLeft;
+
+ @Override
+ public int compare(View lhs, View rhs) {
+ int start1;
+ int start2;
+ if (mIsLtr) {
+ start1 = getRelativeLeft(lhs, mParentForDelay);
+ start2 = getRelativeLeft(rhs, mParentForDelay);
+ } else {
+ start1 = getRelativeRight(lhs, mParentForDelay);
+ start2 = getRelativeRight(rhs, mParentForDelay);
+ }
+ if (mToLeft) {
+ if (start1 > start2) {
+ return 1;
+ } else if (start1 < start2) {
+ return -1;
+ }
+ } else {
+ if (start1 > start2) {
+ return -1;
+ } else if (start1 < start2) {
+ return 1;
+ }
+ }
+ int top1 = getRelativeTop(lhs, mParentForDelay);
+ int top2 = getRelativeTop(rhs, mParentForDelay);
+ return Integer.compare(top1, top2);
+ }
+
+ private int getRelativeLeft(View child, View ancestor) {
+ ViewParent parent = child.getParent();
+ int left = child.getLeft();
+ while (parent instanceof View) {
+ if (parent == ancestor) {
+ break;
+ }
+ left += ((View) parent).getLeft();
+ parent = parent.getParent();
+ }
+ return left;
+ }
+
+ private int getRelativeRight(View child, View ancestor) {
+ ViewParent parent = child.getParent();
+ int right = child.getRight();
+ while (parent instanceof View) {
+ if (parent == ancestor) {
+ break;
+ }
+ right += ((View) parent).getLeft();
+ parent = parent.getParent();
+ }
+ return right;
+ }
+
+ private int getRelativeTop(View child, View ancestor) {
+ ViewParent parent = child.getParent();
+ int top = child.getTop();
+ while (parent instanceof View) {
+ if (parent == ancestor) {
+ break;
+ }
+ top += ((View) parent).getTop();
+ parent = parent.getParent();
+ }
+ return top;
+ }
+ }
}
diff --git a/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java b/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
index 9d2efcd0..0c5849ea 100644
--- a/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
+++ b/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
@@ -21,46 +21,60 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
+import android.content.Context;
import android.transition.Transition;
import android.transition.TransitionSet;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
+import com.android.tv.common.R;
+
/**
* A helper class for setup animation.
*/
public final class SetupAnimationHelper {
public static final long DELAY_BETWEEN_SIBLINGS_MS = applyAnimationTimeScale(33);
- private static final float ANIMATION_SCALE = 1.0f;
+ private static final float ANIMATION_TIME_SCALE = 1.0f;
+ private static boolean sInitialized;
private static long sFragmentTransitionDuration;
- private static int sFragmentTransitionDistance;
+ private static int sFragmentTransitionLongDistance;
+ private static int sFragmentTransitionShortDistance;
private SetupAnimationHelper() { }
/**
- * Sets the duration of the fragment transition.
+ * Load initial parameters. This method should be called before using this class.
*/
- public static void setFragmentTransitionDuration(long duration) {
- sFragmentTransitionDuration = duration;
+ public static void initialize(Context context) {
+ sFragmentTransitionDuration = context.getResources()
+ .getInteger(R.integer.setup_fragment_transition_duration);
+ sFragmentTransitionLongDistance = context.getResources()
+ .getDimensionPixelOffset(R.dimen.setup_fragment_transition_long_distance);
+ sFragmentTransitionShortDistance = context.getResources()
+ .getDimensionPixelOffset(R.dimen.setup_fragment_transition_short_distance);
+ sInitialized = true;
}
- /**
- * Sets the distance of the fragment transition.
- */
- public static void setFragmentTransitionDistance(int distance) {
- sFragmentTransitionDistance = distance;
+ private static void checkInitialized() {
+ if (!sInitialized) {
+ throw new IllegalStateException("SetupAnimationHelper not initialized");
+ }
}
public static class TransitionBuilder {
private int mSlideEdge = Gravity.START;
- private int mDistance = sFragmentTransitionDistance;
+ private int mDistance = sFragmentTransitionLongDistance;
private long mDuration = sFragmentTransitionDuration;
private int[] mParentIdForDelay;
private int[] mExcludeIds;
+ public TransitionBuilder() {
+ checkInitialized();
+ }
+
/**
* Sets the edge of the slide transition.
*
@@ -114,6 +128,22 @@ public final class SetupAnimationHelper {
}
/**
+ * Changes the move distance of the {@code transition} to long distance.
+ */
+ public static void setLongDistance(FadeAndShortSlide transition) {
+ checkInitialized();
+ transition.setDistance(sFragmentTransitionLongDistance);
+ }
+
+ /**
+ * Changes the move distance of the {@code transition} to short distance.
+ */
+ public static void setShortDistance(FadeAndShortSlide transition) {
+ checkInitialized();
+ transition.setDistance(sFragmentTransitionShortDistance);
+ }
+
+ /**
* Applies the animation scale to the given {@code animator}.
*/
public static Animator applyAnimationTimeScale(Animator animator) {
@@ -123,9 +153,9 @@ public final class SetupAnimationHelper {
}
}
if (animator.getDuration() > 0) {
- animator.setDuration((long) (animator.getDuration() * ANIMATION_SCALE));
+ animator.setDuration((long) (animator.getDuration() * ANIMATION_TIME_SCALE));
}
- animator.setStartDelay((long) (animator.getStartDelay() * ANIMATION_SCALE));
+ animator.setStartDelay((long) (animator.getStartDelay() * ANIMATION_TIME_SCALE));
return animator;
}
@@ -141,9 +171,9 @@ public final class SetupAnimationHelper {
}
}
if (transition.getDuration() > 0) {
- transition.setDuration((long) (transition.getDuration() * ANIMATION_SCALE));
+ transition.setDuration((long) (transition.getDuration() * ANIMATION_TIME_SCALE));
}
- transition.setStartDelay((long) (transition.getStartDelay() * ANIMATION_SCALE));
+ transition.setStartDelay((long) (transition.getStartDelay() * ANIMATION_TIME_SCALE));
return transition;
}
@@ -151,11 +181,11 @@ public final class SetupAnimationHelper {
* Applies the animation scale to the given {@code time}.
*/
public static long applyAnimationTimeScale(long time) {
- return (long) (time * ANIMATION_SCALE);
+ return (long) (time * ANIMATION_TIME_SCALE);
}
/**
- * Returns an animator which animate the source image of the {@link ImageView}.
+ * Returns an animator which animates the source image of the {@link ImageView}.
*
* <p>The frame rate is 60 fps.
*/
@@ -164,7 +194,7 @@ public final class SetupAnimationHelper {
}
/**
- * Returns an animator which animate the source image of the {@link ImageView} with start delay.
+ * Returns an animator which animates the source image of the {@link ImageView} with start delay.
*
* <p>The frame rate is 60 fps.
*/
@@ -192,9 +222,10 @@ public final class SetupAnimationHelper {
* @param makeVisibleAfterAnimation If {@code true}, the view will become visible after the
* animation ends.
*/
- public static Animator createFadeOutAnimator(final View view, int duration,
+ public static Animator createFadeOutAnimator(final View view, long duration,
boolean makeVisibleAfterAnimation) {
- ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f);
+ ObjectAnimator animator =
+ ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f).setDuration(duration);
if (makeVisibleAfterAnimation) {
animator.addListener(new AnimatorListenerAdapter() {
@Override
diff --git a/common/src/com/android/tv/common/ui/setup/leanback/OnboardingFragment.java b/common/src/com/android/tv/common/ui/setup/leanback/OnboardingFragment.java
new file mode 100644
index 00000000..adbd98c2
--- /dev/null
+++ b/common/src/com/android/tv/common/ui/setup/leanback/OnboardingFragment.java
@@ -0,0 +1,531 @@
+/*
+ * 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.ui.setup.leanback;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnKeyListener;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnPreDrawListener;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.tv.common.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An OnboardingFragment provides a common and simple way to build onboarding screen for
+ * applications.
+ * <p>
+ * <h3>Building the screen</h3>
+ * The view structure of onboarding screen is composed of the common parts and custom parts. The
+ * common parts are composed of title, description and page navigator and the custom parts are
+ * composed of background, contents and foreground.
+ * <p>
+ * To build the screen views, the inherited class should override:
+ * <ul>
+ * <li>{@link #onCreateBackgroundView} to provide the background view. Background view has the same
+ * size as the screen and the lowest z-order.</li>
+ * <li>{@link #onCreateContentView} to provide the contents view. The content view is located in
+ * the content area at the center of the screen.</li>
+ * <li>{@link #onCreateForegroundView} to provide the foreground view. Foreground view has the same
+ * size as the screen and the highest z-order</li>
+ * </ul>
+ * <p>
+ * Each of these methods can return {@code null} if the application doesn't want to provide it.
+ * <p>
+ * <h3>Page information</h3>
+ * The onboarding screen may have several pages which explain the functionality of the application.
+ * The inherited class should provide the page information by overriding the methods:
+ * <p>
+ * <ul>
+ * <li>{@link #getPageCount} to provide the number of pages.</li>
+ * <li>{@link #getPageTitle} to provide the title of the page.</li>
+ * <li>{@link #getPageDescription} to provide the description of the page.</li>
+ * </ul>
+ * <p>
+ * <h3><a name="logoAnimation">Logo Splash Animation</a></h3>
+ * When onboarding screen appears, the logo splash animation is played by default. The animation
+ * fades in the logo image, pauses in a few seconds and fades it out. To support this animation with
+ * its own logo image, the inherited class should override the following method.
+ * <p>
+ * <ul>
+ * <li>{@link #getLogoResourceId()}</li>
+ * </ul>
+ * <p>
+ * <h3>Animation</h3>
+ * This page has three kinds of animations:
+ * <p>
+ * <ul>
+ * <li><b>Logo splash animation</b> which starts as soon as onboarding screen is shown as described
+ * in <a href="#logoAnimation">Logo Splash Animation</a>.</li>
+ * <li><b>Page enter animation</b> which runs just after the logo animation finishes. The
+ * application can run the animations of their custom views by overriding
+ * {@link #onStartEnterAnimation}.</li>
+ * <li><b>Page change animation</b> which runs when the page changes. The pages can move backward or
+ * forward direction and the application can start the page change animations by overriding
+ * {@link #onStartPageChangeAnimation}.</li>
+ * </ul>
+ * <p>
+ * <h3>Finishing the screen</h3>
+ * <p>
+ * If the user finishes the onboarding screen after navigating all the pages,
+ * {@link #onFinishFragment} is called. The inherited class can override this method to show another
+ * fragment or activity, or just remove this fragment.
+ *
+ * @hide
+ */
+abstract public class OnboardingFragment extends Fragment {
+ private static final long LOGO_SPLASH_PAUSE_DURATION_MS = 1333;
+ private static final long START_DELAY_TITLE_MS = 33;
+ private static final long START_DELAY_DESCRIPTION_MS = 33;
+
+ private static final long HEADER_ANIMATION_DURATION_MS = 417;
+ private static final long DESCRIPTION_START_DELAY_MS = 33;
+ private static final long HEADER_APPEAR_DELAY_MS = 500;
+ private static final int SLIDE_DISTANCE = 60;
+
+ private static int sSlideDistance;
+
+ private static final TimeInterpolator HEADER_APPEAR_INTERPOLATOR = new DecelerateInterpolator();
+ private static final TimeInterpolator HEADER_DISAPPEAR_INTERPOLATOR
+ = new AccelerateInterpolator();
+
+ private PagingIndicator mPageIndicator;
+ private View mStartButton;
+ private ImageView mLogoView;
+ private TextView mTitleView;
+ private TextView mDescriptionView;
+
+ private boolean mEnterTransitionFinished;
+ private int mCurrentPageIndex;
+
+ private AnimatorSet mAnimator;
+
+ /**
+ * Called to have the inherited class create its own start animation. The start animation runs
+ * after logo splash animation ends.
+ */
+ abstract protected void onStartEnterAnimation();
+
+ private final OnClickListener mOnClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (!mEnterTransitionFinished) {
+ // Do not change page until the enter transition finishes.
+ return;
+ }
+ if (mCurrentPageIndex == getPageCount() - 1) {
+ onFinishFragment();
+ } else {
+ ++mCurrentPageIndex;
+ onPageChanged(mCurrentPageIndex - 1);
+ }
+ }
+ };
+
+ private final OnKeyListener mOnKeyListener = new OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (!mEnterTransitionFinished) {
+ // Ignore key event until the enter transition finishes.
+ return keyCode != KeyEvent.KEYCODE_BACK;
+ }
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ return false;
+ }
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (mCurrentPageIndex == 0) {
+ return false;
+ }
+ // pass through
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (mCurrentPageIndex > 0) {
+ --mCurrentPageIndex;
+ onPageChanged(mCurrentPageIndex + 1);
+ }
+ return true;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (mCurrentPageIndex < getPageCount() - 1) {
+ ++mCurrentPageIndex;
+ onPageChanged(mCurrentPageIndex - 1);
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, final ViewGroup container,
+ Bundle savedInstanceState) {
+ ViewGroup view = (ViewGroup) inflater.inflate(R.layout.lb_onboarding_fragment, container,
+ false);
+ mPageIndicator = (PagingIndicator) view.findViewById(R.id.page_indicator);
+ mPageIndicator.setPageCount(getPageCount());
+ mPageIndicator.setOnClickListener(mOnClickListener);
+ mPageIndicator.setOnKeyListener(mOnKeyListener);
+ mStartButton = view.findViewById(R.id.button_start);
+ mStartButton.setOnClickListener(mOnClickListener);
+ mStartButton.setOnKeyListener(mOnKeyListener);
+ mLogoView = (ImageView) view.findViewById(R.id.logo);
+ mLogoView.setImageResource(getLogoResourceId());
+ mTitleView = (TextView) view.findViewById(R.id.title);
+ mTitleView.setText(getPageTitle(0));
+ mDescriptionView = (TextView) view.findViewById(R.id.description);
+ mDescriptionView.setText(getPageDescription(0));
+ if (sSlideDistance == 0) {
+ sSlideDistance = (int) (SLIDE_DISTANCE * getActivity().getResources()
+ .getDisplayMetrics().scaledDensity);
+ }
+ mCurrentPageIndex = 0;
+ mPageIndicator.onPageSelected(0, false);
+ view.requestFocus();
+ if (getLogoResourceId() != 0) {
+ container.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ container.getViewTreeObserver().removeOnPreDrawListener(this);
+ startLogoAnimation();
+ return true;
+ }
+ });
+ } else {
+ onLogoAnimationFinished();
+ }
+ return view;
+ }
+
+ private void startLogoAnimation() {
+ mLogoView.setVisibility(View.VISIBLE);
+ Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_logo_enter);
+ Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_logo_exit);
+ outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS);
+ AnimatorSet animator = new AnimatorSet();
+ animator.playSequentially(inAnimator, outAnimator);
+ animator.setTarget(mLogoView);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mEnterTransitionFinished = true;
+ if (getActivity() != null) {
+ onLogoAnimationFinished();
+ onStartEnterAnimation();
+ }
+ }
+ });
+ animator.start();
+ }
+
+ private void onLogoAnimationFinished() {
+ mLogoView.setVisibility(View.GONE);
+ // Create custom views.
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ ViewGroup backgroundContainer = (ViewGroup) getView().findViewById(
+ R.id.background_container);
+ View background = onCreateBackgroundView(inflater, backgroundContainer);
+ if (background != null) {
+ backgroundContainer.setVisibility(View.VISIBLE);
+ backgroundContainer.addView(background);
+ }
+ ViewGroup contentContainer = (ViewGroup) getView().findViewById(R.id.content_container);
+ View content = onCreateContentView(inflater, contentContainer);
+ if (content != null) {
+ contentContainer.setVisibility(View.VISIBLE);
+ contentContainer.addView(content);
+ }
+ ViewGroup foregroundContainer = (ViewGroup) getView().findViewById(
+ R.id.foreground_container);
+ View foreground = onCreateForegroundView(inflater, foregroundContainer);
+ if (foreground != null) {
+ foregroundContainer.setVisibility(View.VISIBLE);
+ foregroundContainer.addView(foreground);
+ }
+ // Make views visible which were invisible while logo animation is running.
+ getView().findViewById(R.id.page_container).setVisibility(View.VISIBLE);
+ getView().findViewById(R.id.content_container).setVisibility(View.VISIBLE);
+
+ List<Animator> animators = new ArrayList<>();
+ Animator animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_page_indicator_enter);
+ if (getPageCount() <= 1) {
+ // Start button
+ mStartButton.setVisibility(View.VISIBLE);
+ animator.setTarget(mStartButton);
+ } else {
+ // Page indicator
+ mPageIndicator.setVisibility(View.VISIBLE);
+ animator.setTarget(mPageIndicator);
+ }
+ animators.add(animator);
+ // Header title
+ View view = getActivity().findViewById(R.id.title);
+ view.setAlpha(0);
+ animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_title_enter);
+ animator.setStartDelay(START_DELAY_TITLE_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ // Header description
+ view = getActivity().findViewById(R.id.description);
+ view.setAlpha(0);
+ animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_description_enter);
+ animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ mAnimator = new AnimatorSet();
+ mAnimator.playTogether(animators);
+ mAnimator.start();
+ onStartEnterAnimation();
+ // Search focus and give the focus to the appropriate child which has become visible.
+ getView().requestFocus();
+ }
+
+ /**
+ * Returns the page count.
+ *
+ * @return The page count.
+ */
+ abstract protected int getPageCount();
+
+ /**
+ * Returns the title of the given page.
+ *
+ * @param pageIndex The page index.
+ *
+ * @return The title of the page.
+ */
+ abstract protected String getPageTitle(int pageIndex);
+
+ /**
+ * Returns the description of the given page.
+ *
+ * @param pageIndex The page index.
+ *
+ * @return The description of the page.
+ */
+ abstract protected String getPageDescription(int pageIndex);
+
+ /**
+ * Returns the index of the current page.
+ *
+ * @return The index of the current page.
+ */
+ protected final int getCurrentPageIndex() {
+ return mCurrentPageIndex;
+ }
+
+ /**
+ * Returns the resource ID of the splash logo image.
+ *
+ * @return The resource ID of the splash logo image.
+ */
+ abstract protected int getLogoResourceId();
+
+ /**
+ * Called to have the inherited class create background view. This is optional and the fragment
+ * which doesn't have the background view can return {@code null}. This is called inside
+ * {@link #onCreateView}.
+ *
+ * @param inflater The LayoutInflater object that can be used to inflate the views,
+ * @param container The parent view that the additional views are attached to.The fragment
+ * should not add the view by itself.
+ *
+ * @return The background view for the onboarding screen, or {@code null}.
+ */
+ @Nullable
+ abstract protected View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container);
+
+ /**
+ * Called to have the inherited class create content view. This is optional and the fragment
+ * which doesn't have the content view can return {@code null}. This is called inside
+ * {@link #onCreateView}.
+ *
+ * <p>The content view would be located at the center of the screen.
+ *
+ * @param inflater The LayoutInflater object that can be used to inflate the views,
+ * @param container The parent view that the additional views are attached to.The fragment
+ * should not add the view by itself.
+ *
+ * @return The content view for the onboarding screen, or {@code null}.
+ */
+ @Nullable
+ abstract protected View onCreateContentView(LayoutInflater inflater, ViewGroup container);
+
+ /**
+ * Called to have the inherited class create foreground view. This is optional and the fragment
+ * which doesn't need the foreground view can return {@code null}. This is called inside
+ * {@link #onCreateView}.
+ *
+ * <p>This foreground view would have the highest z-order.
+ *
+ * @param inflater The LayoutInflater object that can be used to inflate the views,
+ * @param container The parent view that the additional views are attached to.The fragment
+ * should not add the view by itself.
+ *
+ * @return The foreground view for the onboarding screen, or {@code null}.
+ */
+ @Nullable
+ abstract protected View onCreateForegroundView(LayoutInflater inflater, ViewGroup container);
+
+ /**
+ * Called when the onboarding flow finishes.
+ */
+ protected void onFinishFragment() { }
+
+ /**
+ * Called when the page changes.
+ */
+ private void onPageChanged(int previousPage) {
+ if (mAnimator != null) {
+ mAnimator.end();
+ }
+ mPageIndicator.onPageSelected(mCurrentPageIndex, true);
+
+ List<Animator> animators = new ArrayList<>();
+ // Header animation
+ Animator fadeAnimator = null;
+ if (previousPage < getCurrentPageIndex()) {
+ // sliding to left
+ animators.add(createAnimator(mTitleView, false, Gravity.START, 0));
+ animators.add(fadeAnimator = createAnimator(mDescriptionView, false, Gravity.START,
+ DESCRIPTION_START_DELAY_MS));
+ animators.add(createAnimator(mTitleView, true, Gravity.END,
+ HEADER_APPEAR_DELAY_MS));
+ animators.add(createAnimator(mDescriptionView, true, Gravity.END,
+ HEADER_APPEAR_DELAY_MS + DESCRIPTION_START_DELAY_MS));
+ } else {
+ // sliding to right
+ animators.add(createAnimator(mTitleView, false, Gravity.END, 0));
+ animators.add(fadeAnimator = createAnimator(mDescriptionView, false, Gravity.END,
+ DESCRIPTION_START_DELAY_MS));
+ animators.add(createAnimator(mTitleView, true, Gravity.START,
+ HEADER_APPEAR_DELAY_MS));
+ animators.add(createAnimator(mDescriptionView, true, Gravity.START,
+ HEADER_APPEAR_DELAY_MS + DESCRIPTION_START_DELAY_MS));
+ }
+ final int currentPageIndex = getCurrentPageIndex();
+ fadeAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mTitleView.setText(getPageTitle(currentPageIndex));
+ mDescriptionView.setText(getPageDescription(currentPageIndex));
+ }
+ });
+
+ // Animator for switching between page indicator and button.
+ if (getCurrentPageIndex() == getPageCount() - 1) {
+ mStartButton.setVisibility(View.VISIBLE);
+ Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_page_indicator_fade_out);
+ navigatorFadeOutAnimator.setTarget(mPageIndicator);
+ Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_start_button_fade_in);
+ buttonFadeInAnimator.setTarget(mStartButton);
+ animators.add(navigatorFadeOutAnimator);
+ navigatorFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPageIndicator.setVisibility(View.GONE);
+ }
+ });
+ animators.add(buttonFadeInAnimator);
+ } else if (previousPage == getPageCount() - 1) {
+ mPageIndicator.setVisibility(View.VISIBLE);
+ Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_page_indicator_fade_in);
+ navigatorFadeInAnimator.setTarget(mPageIndicator);
+ Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.lb_onboarding_start_button_fade_out);
+ buttonFadeOutAnimator.setTarget(mStartButton);
+ buttonFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStartButton.setVisibility(View.GONE);
+ }
+ });
+ mAnimator = new AnimatorSet();
+ mAnimator.playTogether(navigatorFadeInAnimator, buttonFadeOutAnimator);
+ mAnimator.start();
+ }
+ mAnimator = new AnimatorSet();
+ mAnimator.playTogether(animators);
+ mAnimator.start();
+ onStartPageChangeAnimation(previousPage);
+ }
+
+ private Animator createAnimator(View view, boolean fadeIn, int slideDirection,
+ long startDelay) {
+ boolean isLtr = getView().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
+ boolean slideRight = (isLtr && slideDirection == Gravity.END)
+ || (!isLtr && slideDirection == Gravity.START)
+ || slideDirection == Gravity.RIGHT;
+ Animator fadeAnimator;
+ Animator slideAnimator;
+ if (fadeIn) {
+ fadeAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 0.0f, 1.0f);
+ slideAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
+ slideRight ? sSlideDistance : -sSlideDistance, 0);
+ fadeAnimator.setInterpolator(HEADER_APPEAR_INTERPOLATOR);
+ slideAnimator.setInterpolator(HEADER_APPEAR_INTERPOLATOR);
+ } else {
+ fadeAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f);
+ slideAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 0,
+ slideRight ? sSlideDistance : -sSlideDistance);
+ fadeAnimator.setInterpolator(HEADER_DISAPPEAR_INTERPOLATOR);
+ slideAnimator.setInterpolator(HEADER_DISAPPEAR_INTERPOLATOR);
+ }
+ fadeAnimator.setDuration(HEADER_ANIMATION_DURATION_MS);
+ fadeAnimator.setTarget(view);
+ slideAnimator.setDuration(HEADER_ANIMATION_DURATION_MS);
+ slideAnimator.setTarget(view);
+ AnimatorSet animator = new AnimatorSet();
+ animator.playTogether(fadeAnimator, slideAnimator);
+ if (startDelay > 0) {
+ animator.setStartDelay(startDelay);
+ }
+ return animator;
+ }
+
+ /**
+ * Called to have the inherited class run its own page change animation
+ *
+ * @param previousPage The previous page.
+ */
+ abstract protected void onStartPageChangeAnimation(int previousPage);
+}
diff --git a/common/src/com/android/tv/common/ui/setup/leanback/PagingIndicator.java b/common/src/com/android/tv/common/ui/setup/leanback/PagingIndicator.java
new file mode 100644
index 00000000..e2c9be72
--- /dev/null
+++ b/common/src/com/android/tv/common/ui/setup/leanback/PagingIndicator.java
@@ -0,0 +1,377 @@
+/*
+ * 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.ui.setup.leanback;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Build;
+import android.support.annotation.ColorInt;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.tv.common.R;
+import com.android.tv.common.annotation.UsedByReflection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A page indicator with dots.
+ * @hide
+ */
+public class PagingIndicator extends View {
+ // attribute
+ private final int mDotDiameter;
+ private final int mDotRadius;
+ private final int mDotGap;
+ private final int mArrowDiameter;
+ private final int mArrowRadius;
+ private final int mArrowGap;
+ private final int mShadowRadius;
+ private Dot[] mDots;
+ // X position when the dot is selected.
+ private int[] mDotSelectedX;
+ // X position when the dot is located to the left of the selected dot.
+ private int[] mDotSelectedLeftX;
+ // X position when the dot is located to the right of the selected dot.
+ private int[] mDotSelectedRightX;
+ private int mDotCenterY;
+
+ // state
+ private int mPageCount;
+ private int mCurrentPage;
+ private int mPreviousPage;
+
+ // drawing
+ @ColorInt
+ private final int mDotFgSelectColor;
+ private final Paint mBgPaint;
+ private final Paint mFgPaint;
+ private final Animator mShowAnimator;
+ private final Animator mHideAnimator;
+ private final AnimatorSet mAnimator = new AnimatorSet();
+ private final Bitmap mArrow;
+ private final Rect mArrowRect;
+ private final float mArrowToBgRatio;
+
+ public PagingIndicator(Context context) {
+ this(context, null, 0);
+ }
+
+ public PagingIndicator(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PagingIndicator(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ Resources res = getResources();
+ mDotRadius = res.getDimensionPixelSize(R.dimen.lb_page_indicator_dot_radius);
+ mDotDiameter = mDotRadius * 2;
+ mDotGap = res.getDimensionPixelSize(R.dimen.lb_page_indicator_dot_gap);
+ mArrowGap = res.getDimensionPixelSize(R.dimen.lb_page_indicator_arrow_gap);
+ mArrowDiameter = res.getDimensionPixelSize(R.dimen.lb_page_indicator_arrow_diameter);
+ mArrowRadius = mArrowDiameter / 2;
+ mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mDotFgSelectColor = res.getColor(R.color.lb_page_indicator_arrow_background);
+ int bgColor = res.getColor(R.color.lb_page_indicator_dot);
+ int shadowColor = res.getColor(R.color.lb_page_indicator_arrow_shadow);
+ mBgPaint.setColor(bgColor);
+ mShadowRadius = res.getDimensionPixelSize(R.dimen.lb_page_indicator_arrow_shadow_radius);
+ mFgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ int shadowOffset = res.getDimensionPixelSize(R.dimen.lb_page_indicator_arrow_shadow_offset);
+ mFgPaint.setShadowLayer(mShadowRadius, shadowOffset, shadowOffset, shadowColor);
+ mArrow = BitmapFactory.decodeResource(res, R.drawable.lb_ic_nav_arrow);
+ mArrowRect = new Rect(0, 0, mArrow.getWidth(), mArrow.getHeight());
+ mArrowToBgRatio = (float) mArrow.getWidth() / (float) mArrowDiameter;
+ // Initialize animations.
+ List<Animator> animators = new ArrayList<>();
+ mShowAnimator = AnimatorInflater.loadAnimator(getContext(),
+ R.animator.lb_page_indicator_dot_show);
+ mHideAnimator = AnimatorInflater.loadAnimator(getContext(),
+ R.animator.lb_page_indicator_dot_hide);
+ animators.add(mShowAnimator);
+ animators.add(mHideAnimator);
+ mAnimator.playTogether(animators);
+ // Use software layer to show shadows.
+ setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ }
+
+ /**
+ * Sets the page count.
+ */
+ public void setPageCount(int pages) {
+ if (pages <= 0) {
+ throw new IllegalArgumentException("The page count should be a positive integer");
+ }
+ mPageCount = pages;
+ mDots = new Dot[mPageCount];
+ for (int i = 0; i < mPageCount; ++i) {
+ mDots[i] = new Dot();
+ }
+ calculateDotPositions();
+ setSelectedPage(0);
+ }
+
+ /**
+ * Called when the page has been selected.
+ */
+ public void onPageSelected(int pageIndex, boolean withAnimation) {
+ if (mCurrentPage == pageIndex) {
+ return;
+ }
+ if (mAnimator.isStarted()) {
+ mAnimator.end();
+ }
+ mPreviousPage = mCurrentPage;
+ if (withAnimation) {
+ mHideAnimator.setTarget(mDots[mPreviousPage]);
+ mShowAnimator.setTarget(mDots[pageIndex]);
+ mAnimator.start();
+ }
+ setSelectedPage(pageIndex);
+ }
+
+ private void calculateDotPositions() {
+ int left = getPaddingLeft();
+ int top = getPaddingTop();
+ int right = getWidth() - getPaddingRight();
+ int requiredWidth = getRequiredWidth();
+ int mid = (left + right) / 2;
+ int startLeft = mid - requiredWidth / 2;
+ mDotSelectedX = new int[mPageCount];
+ mDotSelectedLeftX = new int[mPageCount];
+ mDotSelectedRightX = new int[mPageCount];
+ // mDotSelectedX[0] should be mDotSelectedLeftX[-1] + mArrowGap
+ mDotSelectedX[0] = startLeft + mDotRadius - mDotGap + mArrowGap;
+ mDotSelectedLeftX[0] = startLeft + mDotRadius;
+ mDotSelectedRightX[0] = 0;
+ for (int i = 1; i < mPageCount; i++) {
+ mDotSelectedX[i] = mDotSelectedLeftX[i - 1] + mArrowGap;
+ mDotSelectedLeftX[i] = mDotSelectedLeftX[i - 1] + mDotGap;
+ mDotSelectedRightX[i] = mDotSelectedX[i - 1] + mArrowGap;
+ }
+ mDotCenterY = top + mArrowRadius;
+ adjustDotPosition();
+ }
+
+ @VisibleForTesting
+ int getPageCount() {
+ return mPageCount;
+ }
+
+ @VisibleForTesting
+ int[] getDotSelectedX() {
+ return mDotSelectedX;
+ }
+
+ @VisibleForTesting
+ int[] getDotSelectedLeftX() {
+ return mDotSelectedLeftX;
+ }
+
+ @VisibleForTesting
+ int[] getDotSelectedRightX() {
+ return mDotSelectedRightX;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int desiredHeight = getDesiredHeight();
+ int height;
+ switch (MeasureSpec.getMode(heightMeasureSpec)) {
+ case MeasureSpec.EXACTLY:
+ height = MeasureSpec.getSize(heightMeasureSpec);
+ break;
+ case MeasureSpec.AT_MOST:
+ height = Math.min(desiredHeight, MeasureSpec.getSize(heightMeasureSpec));
+ break;
+ case MeasureSpec.UNSPECIFIED:
+ default:
+ height = desiredHeight;
+ break;
+ }
+ int desiredWidth = getDesiredWidth();
+ int width;
+ switch (MeasureSpec.getMode(widthMeasureSpec)) {
+ case MeasureSpec.EXACTLY:
+ width = MeasureSpec.getSize(widthMeasureSpec);
+ break;
+ case MeasureSpec.AT_MOST:
+ width = Math.min(desiredWidth, MeasureSpec.getSize(widthMeasureSpec));
+ break;
+ case MeasureSpec.UNSPECIFIED:
+ default:
+ width = desiredWidth;
+ break;
+ }
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
+ setMeasuredDimension(width, height);
+ calculateDotPositions();
+ }
+
+ private int getDesiredHeight() {
+ return getPaddingTop() + mArrowDiameter + getPaddingBottom() + mShadowRadius;
+ }
+
+ private int getRequiredWidth() {
+ return 2 * mDotRadius + 2 * mArrowGap + (mPageCount - 3) * mDotGap;
+ }
+
+ private int getDesiredWidth() {
+ return getPaddingLeft() + getRequiredWidth() + getPaddingRight();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ for (int i = 0; i < mPageCount; ++i) {
+ mDots[i].draw(canvas);
+ }
+ }
+
+ private void setSelectedPage(int now) {
+ if (now == mCurrentPage) {
+ return;
+ }
+
+ mCurrentPage = now;
+ adjustDotPosition();
+ }
+
+ private void adjustDotPosition() {
+ for (int i = 0; i < mCurrentPage; ++i) {
+ mDots[i].deselect();
+ mDots[i].mDirection = i == mPreviousPage ? Dot.LEFT : Dot.RIGHT;
+ mDots[i].mCenterX = mDotSelectedLeftX[i];
+ }
+ mDots[mCurrentPage].select();
+ mDots[mCurrentPage].mDirection = mPreviousPage < mCurrentPage ? Dot.LEFT : Dot.RIGHT;
+ mDots[mCurrentPage].mCenterX = mDotSelectedX[mCurrentPage];
+ for (int i = mCurrentPage + 1; i < mPageCount; ++i) {
+ mDots[i].deselect();
+ mDots[i].mDirection = Dot.RIGHT;
+ mDots[i].mCenterX = mDotSelectedRightX[i];
+ }
+ }
+
+ public class Dot {
+ static final float LEFT = -1;
+ static final float RIGHT = 1;
+
+ float mAlpha;
+ @ColorInt
+ int mBgColor;
+ @ColorInt
+ int mFgColor;
+ float mTranslationX;
+ float mCenterX;
+ float mDiameter;
+ float mRadius;
+ float mArrowImageRadius;
+ float mDirection = RIGHT;
+
+ void select() {
+ mTranslationX = 0.0f;
+ mCenterX = 0.0f;
+ mDiameter = mArrowDiameter;
+ mRadius = mArrowRadius;
+ mArrowImageRadius = mRadius * mArrowToBgRatio;
+ mAlpha = 1.0f;
+ adjustAlpha();
+ }
+
+ void deselect() {
+ mTranslationX = 0.0f;
+ mCenterX = 0.0f;
+ mDiameter = mDotDiameter;
+ mRadius = mDotRadius;
+ mArrowImageRadius = mRadius * mArrowToBgRatio;
+ mAlpha = 0.0f;
+ adjustAlpha();
+ }
+
+ public void adjustAlpha() {
+ int alpha = Math.round(0xFF * mAlpha);
+ int red = Color.red(mDotFgSelectColor);
+ int green = Color.green(mDotFgSelectColor);
+ int blue = Color.blue(mDotFgSelectColor);
+ mFgColor = Color.argb(alpha, red, green, blue);
+ }
+
+ @UsedByReflection
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ @UsedByReflection
+ public void setAlpha(float alpha) {
+ this.mAlpha = alpha;
+ adjustAlpha();
+ invalidate();
+ }
+
+ @UsedByReflection
+ public float getTranslationX() {
+ return mTranslationX;
+ }
+
+ @UsedByReflection
+ public void setTranslationX(float translationX) {
+ this.mTranslationX = translationX * mDirection;
+ invalidate();
+ }
+
+ @UsedByReflection
+ public float getDiameter() {
+ return mDiameter;
+ }
+
+ @UsedByReflection
+ public void setDiameter(float diameter) {
+ this.mDiameter = diameter;
+ this.mRadius = diameter / 2;
+ this.mArrowImageRadius = diameter / 2 * mArrowToBgRatio;
+ invalidate();
+ }
+
+ void draw(Canvas canvas) {
+ float centerX = mCenterX + mTranslationX;
+ canvas.drawCircle(centerX, mDotCenterY, mRadius, mBgPaint);
+ if (mAlpha > 0) {
+ mFgPaint.setColor(mFgColor);
+ canvas.drawCircle(centerX, mDotCenterY, mRadius, mFgPaint);
+ canvas.drawBitmap(mArrow, mArrowRect, new Rect((int) (centerX - mArrowImageRadius),
+ (int) (mDotCenterY - mArrowImageRadius),
+ (int) (centerX + mArrowImageRadius),
+ (int) (mDotCenterY + mArrowImageRadius)), null);
+ }
+ }
+ }
+}
diff --git a/proguard.flags b/proguard.flags
index 80ae826d..067ccca3 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -28,7 +28,7 @@
-dontwarn com.google.android.common.**
# Keep the methods called from native code.
--keepclasseswithmembers class com.android.usbtuner.UsbTunerInterface {
+-keepclasseswithmembers class com.android.usbtuner.TunerHal {
int openDvbFrontEndFd();
int openDvbDemuxFd();
int openDvbDvrFd();
@@ -39,6 +39,12 @@
void close();
}
+# Keep method which is used for reflection.
+-keep @com.android.tv.common.annotation.UsedByReflection class * {*;}
+-keepclasseswithmembers class * {
+ @com.android.tv.common.annotation.UsedByReflection <methods>;
+}
+
# For tests
-keep @android.support.annotation.VisibleForTesting class * {*;}
-keepclasseswithmembers class * {
diff --git a/res/drawable-xhdpi/ic_playstore.png b/res/drawable-xhdpi/ic_playstore.png
new file mode 100644
index 00000000..8f7c6a5c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_playstore.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_settings.png b/res/drawable-xhdpi/ic_settings.png
new file mode 100644
index 00000000..85ae13c0
--- /dev/null
+++ b/res/drawable-xhdpi/ic_settings.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_store.png b/res/drawable-xhdpi/ic_store.png
new file mode 100644
index 00000000..d57b5427
--- /dev/null
+++ b/res/drawable-xhdpi/ic_store.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvoption_about.png b/res/drawable-xhdpi/ic_tvoption_about.png
deleted file mode 100644
index b242df7d..00000000
--- a/res/drawable-xhdpi/ic_tvoption_about.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvoption_parental.png b/res/drawable-xhdpi/ic_tvoption_parental.png
deleted file mode 100644
index d3499a63..00000000
--- a/res/drawable-xhdpi/ic_tvoption_parental.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_100.png b/res/drawable-xhdpi/tv_4a_100.png
deleted file mode 100644
index 373d2840..00000000
--- a/res/drawable-xhdpi/tv_4a_100.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_101.png b/res/drawable-xhdpi/tv_4a_101.png
deleted file mode 100644
index c9564e9b..00000000
--- a/res/drawable-xhdpi/tv_4a_101.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_102.png b/res/drawable-xhdpi/tv_4a_102.png
deleted file mode 100644
index 8bc3212c..00000000
--- a/res/drawable-xhdpi/tv_4a_102.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_103.png b/res/drawable-xhdpi/tv_4a_103.png
deleted file mode 100644
index 2c53dceb..00000000
--- a/res/drawable-xhdpi/tv_4a_103.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_104.png b/res/drawable-xhdpi/tv_4a_104.png
deleted file mode 100644
index a1a1a738..00000000
--- a/res/drawable-xhdpi/tv_4a_104.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_105.png b/res/drawable-xhdpi/tv_4a_105.png
deleted file mode 100644
index 3467cfb3..00000000
--- a/res/drawable-xhdpi/tv_4a_105.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_106.png b/res/drawable-xhdpi/tv_4a_106.png
deleted file mode 100644
index 9f9bdb58..00000000
--- a/res/drawable-xhdpi/tv_4a_106.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_107.png b/res/drawable-xhdpi/tv_4a_107.png
deleted file mode 100644
index 8a2baccf..00000000
--- a/res/drawable-xhdpi/tv_4a_107.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_108.png b/res/drawable-xhdpi/tv_4a_108.png
deleted file mode 100644
index 2082a32b..00000000
--- a/res/drawable-xhdpi/tv_4a_108.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_109.png b/res/drawable-xhdpi/tv_4a_109.png
deleted file mode 100644
index 1abc3bcb..00000000
--- a/res/drawable-xhdpi/tv_4a_109.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_110.png b/res/drawable-xhdpi/tv_4a_110.png
deleted file mode 100644
index ecdcc19b..00000000
--- a/res/drawable-xhdpi/tv_4a_110.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_111.png b/res/drawable-xhdpi/tv_4a_111.png
deleted file mode 100644
index 050a0209..00000000
--- a/res/drawable-xhdpi/tv_4a_111.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_112.png b/res/drawable-xhdpi/tv_4a_112.png
deleted file mode 100644
index 8ec6af72..00000000
--- a/res/drawable-xhdpi/tv_4a_112.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_113.png b/res/drawable-xhdpi/tv_4a_113.png
deleted file mode 100644
index cb377be3..00000000
--- a/res/drawable-xhdpi/tv_4a_113.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_114.png b/res/drawable-xhdpi/tv_4a_114.png
deleted file mode 100644
index e3036e97..00000000
--- a/res/drawable-xhdpi/tv_4a_114.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_115.png b/res/drawable-xhdpi/tv_4a_115.png
deleted file mode 100644
index 6465e645..00000000
--- a/res/drawable-xhdpi/tv_4a_115.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_116.png b/res/drawable-xhdpi/tv_4a_116.png
deleted file mode 100644
index b486541f..00000000
--- a/res/drawable-xhdpi/tv_4a_116.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_117.png b/res/drawable-xhdpi/tv_4a_117.png
deleted file mode 100644
index 22ea452c..00000000
--- a/res/drawable-xhdpi/tv_4a_117.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_118.png b/res/drawable-xhdpi/tv_4a_118.png
deleted file mode 100644
index b547b64d..00000000
--- a/res/drawable-xhdpi/tv_4a_118.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_119.png b/res/drawable-xhdpi/tv_4a_119.png
deleted file mode 100644
index bf996217..00000000
--- a/res/drawable-xhdpi/tv_4a_119.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_120.png b/res/drawable-xhdpi/tv_4a_120.png
deleted file mode 100644
index 70810de4..00000000
--- a/res/drawable-xhdpi/tv_4a_120.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_121.png b/res/drawable-xhdpi/tv_4a_121.png
deleted file mode 100644
index 6f884b5a..00000000
--- a/res/drawable-xhdpi/tv_4a_121.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_122.png b/res/drawable-xhdpi/tv_4a_122.png
deleted file mode 100644
index 536e736d..00000000
--- a/res/drawable-xhdpi/tv_4a_122.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_123.png b/res/drawable-xhdpi/tv_4a_123.png
deleted file mode 100644
index 71bef97b..00000000
--- a/res/drawable-xhdpi/tv_4a_123.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_124.png b/res/drawable-xhdpi/tv_4a_124.png
deleted file mode 100644
index 8cab15c2..00000000
--- a/res/drawable-xhdpi/tv_4a_124.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_125.png b/res/drawable-xhdpi/tv_4a_125.png
deleted file mode 100644
index b282515e..00000000
--- a/res/drawable-xhdpi/tv_4a_125.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_126.png b/res/drawable-xhdpi/tv_4a_126.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_126.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_127.png b/res/drawable-xhdpi/tv_4a_127.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_127.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_128.png b/res/drawable-xhdpi/tv_4a_128.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_128.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_129.png b/res/drawable-xhdpi/tv_4a_129.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_129.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_130.png b/res/drawable-xhdpi/tv_4a_130.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_130.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_131.png b/res/drawable-xhdpi/tv_4a_131.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_131.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_132.png b/res/drawable-xhdpi/tv_4a_132.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_132.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_133.png b/res/drawable-xhdpi/tv_4a_133.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_133.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_134.png b/res/drawable-xhdpi/tv_4a_134.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_134.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_135.png b/res/drawable-xhdpi/tv_4a_135.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_135.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_136.png b/res/drawable-xhdpi/tv_4a_136.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_136.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_137.png b/res/drawable-xhdpi/tv_4a_137.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_137.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_138.png b/res/drawable-xhdpi/tv_4a_138.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_138.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_139.png b/res/drawable-xhdpi/tv_4a_139.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_139.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_140.png b/res/drawable-xhdpi/tv_4a_140.png
deleted file mode 100644
index 64bc7c66..00000000
--- a/res/drawable-xhdpi/tv_4a_140.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_141.png b/res/drawable-xhdpi/tv_4a_141.png
deleted file mode 100644
index 6a408dc0..00000000
--- a/res/drawable-xhdpi/tv_4a_141.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_142.png b/res/drawable-xhdpi/tv_4a_142.png
deleted file mode 100644
index 92a7a091..00000000
--- a/res/drawable-xhdpi/tv_4a_142.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_143.png b/res/drawable-xhdpi/tv_4a_143.png
deleted file mode 100644
index cdccea06..00000000
--- a/res/drawable-xhdpi/tv_4a_143.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_144.png b/res/drawable-xhdpi/tv_4a_144.png
deleted file mode 100644
index 519c9501..00000000
--- a/res/drawable-xhdpi/tv_4a_144.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_145.png b/res/drawable-xhdpi/tv_4a_145.png
deleted file mode 100644
index b6458c7e..00000000
--- a/res/drawable-xhdpi/tv_4a_145.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_146.png b/res/drawable-xhdpi/tv_4a_146.png
deleted file mode 100644
index 6478e4da..00000000
--- a/res/drawable-xhdpi/tv_4a_146.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_147.png b/res/drawable-xhdpi/tv_4a_147.png
deleted file mode 100644
index 34be97f0..00000000
--- a/res/drawable-xhdpi/tv_4a_147.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_148.png b/res/drawable-xhdpi/tv_4a_148.png
deleted file mode 100644
index 95974383..00000000
--- a/res/drawable-xhdpi/tv_4a_148.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_149.png b/res/drawable-xhdpi/tv_4a_149.png
deleted file mode 100644
index 46b999d5..00000000
--- a/res/drawable-xhdpi/tv_4a_149.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_15.png b/res/drawable-xhdpi/tv_4a_15.png
deleted file mode 100644
index 97d676aa..00000000
--- a/res/drawable-xhdpi/tv_4a_15.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_150.png b/res/drawable-xhdpi/tv_4a_150.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_150.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_151.png b/res/drawable-xhdpi/tv_4a_151.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_151.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_152.png b/res/drawable-xhdpi/tv_4a_152.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_152.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_153.png b/res/drawable-xhdpi/tv_4a_153.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_153.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_154.png b/res/drawable-xhdpi/tv_4a_154.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_154.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_155.png b/res/drawable-xhdpi/tv_4a_155.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_155.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_156.png b/res/drawable-xhdpi/tv_4a_156.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_156.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_157.png b/res/drawable-xhdpi/tv_4a_157.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_157.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_158.png b/res/drawable-xhdpi/tv_4a_158.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_158.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_159.png b/res/drawable-xhdpi/tv_4a_159.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_159.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_16.png b/res/drawable-xhdpi/tv_4a_16.png
deleted file mode 100644
index 06ae31cb..00000000
--- a/res/drawable-xhdpi/tv_4a_16.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_160.png b/res/drawable-xhdpi/tv_4a_160.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_160.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_161.png b/res/drawable-xhdpi/tv_4a_161.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_161.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_162.png b/res/drawable-xhdpi/tv_4a_162.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_162.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_163.png b/res/drawable-xhdpi/tv_4a_163.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_163.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_164.png b/res/drawable-xhdpi/tv_4a_164.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_164.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_165.png b/res/drawable-xhdpi/tv_4a_165.png
deleted file mode 100644
index 6a840a2d..00000000
--- a/res/drawable-xhdpi/tv_4a_165.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_166.png b/res/drawable-xhdpi/tv_4a_166.png
deleted file mode 100644
index f6396919..00000000
--- a/res/drawable-xhdpi/tv_4a_166.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_167.png b/res/drawable-xhdpi/tv_4a_167.png
deleted file mode 100644
index 6eb38144..00000000
--- a/res/drawable-xhdpi/tv_4a_167.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_168.png b/res/drawable-xhdpi/tv_4a_168.png
deleted file mode 100644
index a6872851..00000000
--- a/res/drawable-xhdpi/tv_4a_168.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_169.png b/res/drawable-xhdpi/tv_4a_169.png
deleted file mode 100644
index fe6cd488..00000000
--- a/res/drawable-xhdpi/tv_4a_169.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_17.png b/res/drawable-xhdpi/tv_4a_17.png
deleted file mode 100644
index 2059c016..00000000
--- a/res/drawable-xhdpi/tv_4a_17.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_170.png b/res/drawable-xhdpi/tv_4a_170.png
deleted file mode 100644
index 3ffae5ec..00000000
--- a/res/drawable-xhdpi/tv_4a_170.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_171.png b/res/drawable-xhdpi/tv_4a_171.png
deleted file mode 100644
index 5bc52a10..00000000
--- a/res/drawable-xhdpi/tv_4a_171.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_172.png b/res/drawable-xhdpi/tv_4a_172.png
deleted file mode 100644
index c388d145..00000000
--- a/res/drawable-xhdpi/tv_4a_172.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_173.png b/res/drawable-xhdpi/tv_4a_173.png
deleted file mode 100644
index df8c1efc..00000000
--- a/res/drawable-xhdpi/tv_4a_173.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_174.png b/res/drawable-xhdpi/tv_4a_174.png
deleted file mode 100644
index 623cd805..00000000
--- a/res/drawable-xhdpi/tv_4a_174.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_175.png b/res/drawable-xhdpi/tv_4a_175.png
deleted file mode 100644
index 6a58400f..00000000
--- a/res/drawable-xhdpi/tv_4a_175.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_176.png b/res/drawable-xhdpi/tv_4a_176.png
deleted file mode 100644
index 8110dde2..00000000
--- a/res/drawable-xhdpi/tv_4a_176.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_177.png b/res/drawable-xhdpi/tv_4a_177.png
deleted file mode 100644
index e4812c44..00000000
--- a/res/drawable-xhdpi/tv_4a_177.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_178.png b/res/drawable-xhdpi/tv_4a_178.png
deleted file mode 100644
index 297bf1d2..00000000
--- a/res/drawable-xhdpi/tv_4a_178.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_179.png b/res/drawable-xhdpi/tv_4a_179.png
deleted file mode 100644
index 3becb760..00000000
--- a/res/drawable-xhdpi/tv_4a_179.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_18.png b/res/drawable-xhdpi/tv_4a_18.png
deleted file mode 100644
index 2bbbdc89..00000000
--- a/res/drawable-xhdpi/tv_4a_18.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_180.png b/res/drawable-xhdpi/tv_4a_180.png
deleted file mode 100644
index a1e5dcf2..00000000
--- a/res/drawable-xhdpi/tv_4a_180.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_181.png b/res/drawable-xhdpi/tv_4a_181.png
deleted file mode 100644
index 698ef7e4..00000000
--- a/res/drawable-xhdpi/tv_4a_181.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_182.png b/res/drawable-xhdpi/tv_4a_182.png
deleted file mode 100644
index c85cb63f..00000000
--- a/res/drawable-xhdpi/tv_4a_182.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_183.png b/res/drawable-xhdpi/tv_4a_183.png
deleted file mode 100644
index 7d731c26..00000000
--- a/res/drawable-xhdpi/tv_4a_183.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_184.png b/res/drawable-xhdpi/tv_4a_184.png
deleted file mode 100644
index faec8777..00000000
--- a/res/drawable-xhdpi/tv_4a_184.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_185.png b/res/drawable-xhdpi/tv_4a_185.png
deleted file mode 100644
index 60caa633..00000000
--- a/res/drawable-xhdpi/tv_4a_185.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_186.png b/res/drawable-xhdpi/tv_4a_186.png
deleted file mode 100644
index 02f4d165..00000000
--- a/res/drawable-xhdpi/tv_4a_186.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_187.png b/res/drawable-xhdpi/tv_4a_187.png
deleted file mode 100644
index 67226887..00000000
--- a/res/drawable-xhdpi/tv_4a_187.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_188.png b/res/drawable-xhdpi/tv_4a_188.png
deleted file mode 100644
index 78c59f84..00000000
--- a/res/drawable-xhdpi/tv_4a_188.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_189.png b/res/drawable-xhdpi/tv_4a_189.png
deleted file mode 100644
index dd2e6845..00000000
--- a/res/drawable-xhdpi/tv_4a_189.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_19.png b/res/drawable-xhdpi/tv_4a_19.png
deleted file mode 100644
index 12765e87..00000000
--- a/res/drawable-xhdpi/tv_4a_19.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_190.png b/res/drawable-xhdpi/tv_4a_190.png
deleted file mode 100644
index a2072a19..00000000
--- a/res/drawable-xhdpi/tv_4a_190.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_191.png b/res/drawable-xhdpi/tv_4a_191.png
deleted file mode 100644
index 0fdfa157..00000000
--- a/res/drawable-xhdpi/tv_4a_191.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_192.png b/res/drawable-xhdpi/tv_4a_192.png
deleted file mode 100644
index c502157e..00000000
--- a/res/drawable-xhdpi/tv_4a_192.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_193.png b/res/drawable-xhdpi/tv_4a_193.png
deleted file mode 100644
index 628b19af..00000000
--- a/res/drawable-xhdpi/tv_4a_193.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_194.png b/res/drawable-xhdpi/tv_4a_194.png
deleted file mode 100644
index 33ac611e..00000000
--- a/res/drawable-xhdpi/tv_4a_194.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_195.png b/res/drawable-xhdpi/tv_4a_195.png
deleted file mode 100644
index dd527c29..00000000
--- a/res/drawable-xhdpi/tv_4a_195.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_196.png b/res/drawable-xhdpi/tv_4a_196.png
deleted file mode 100644
index 8070001d..00000000
--- a/res/drawable-xhdpi/tv_4a_196.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_197.png b/res/drawable-xhdpi/tv_4a_197.png
deleted file mode 100644
index 035e742b..00000000
--- a/res/drawable-xhdpi/tv_4a_197.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_198.png b/res/drawable-xhdpi/tv_4a_198.png
deleted file mode 100644
index c53b1af4..00000000
--- a/res/drawable-xhdpi/tv_4a_198.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_199.png b/res/drawable-xhdpi/tv_4a_199.png
deleted file mode 100644
index efdcd137..00000000
--- a/res/drawable-xhdpi/tv_4a_199.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_20.png b/res/drawable-xhdpi/tv_4a_20.png
deleted file mode 100644
index 58852b05..00000000
--- a/res/drawable-xhdpi/tv_4a_20.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_200.png b/res/drawable-xhdpi/tv_4a_200.png
deleted file mode 100644
index b81b2986..00000000
--- a/res/drawable-xhdpi/tv_4a_200.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_201.png b/res/drawable-xhdpi/tv_4a_201.png
deleted file mode 100644
index 29d73af5..00000000
--- a/res/drawable-xhdpi/tv_4a_201.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_202.png b/res/drawable-xhdpi/tv_4a_202.png
deleted file mode 100644
index 8cbfa467..00000000
--- a/res/drawable-xhdpi/tv_4a_202.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_203.png b/res/drawable-xhdpi/tv_4a_203.png
deleted file mode 100644
index 13d9081e..00000000
--- a/res/drawable-xhdpi/tv_4a_203.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_204.png b/res/drawable-xhdpi/tv_4a_204.png
deleted file mode 100644
index ecdb46af..00000000
--- a/res/drawable-xhdpi/tv_4a_204.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_205.png b/res/drawable-xhdpi/tv_4a_205.png
deleted file mode 100644
index f7dcae02..00000000
--- a/res/drawable-xhdpi/tv_4a_205.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_206.png b/res/drawable-xhdpi/tv_4a_206.png
deleted file mode 100644
index 03bf61ed..00000000
--- a/res/drawable-xhdpi/tv_4a_206.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_207.png b/res/drawable-xhdpi/tv_4a_207.png
deleted file mode 100644
index bb7dce10..00000000
--- a/res/drawable-xhdpi/tv_4a_207.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_208.png b/res/drawable-xhdpi/tv_4a_208.png
deleted file mode 100644
index ea29f33d..00000000
--- a/res/drawable-xhdpi/tv_4a_208.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_209.png b/res/drawable-xhdpi/tv_4a_209.png
deleted file mode 100644
index d0e06989..00000000
--- a/res/drawable-xhdpi/tv_4a_209.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_21.png b/res/drawable-xhdpi/tv_4a_21.png
deleted file mode 100644
index bbb5102b..00000000
--- a/res/drawable-xhdpi/tv_4a_21.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_210.png b/res/drawable-xhdpi/tv_4a_210.png
deleted file mode 100644
index 06493959..00000000
--- a/res/drawable-xhdpi/tv_4a_210.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_211.png b/res/drawable-xhdpi/tv_4a_211.png
deleted file mode 100644
index 86392dc7..00000000
--- a/res/drawable-xhdpi/tv_4a_211.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_212.png b/res/drawable-xhdpi/tv_4a_212.png
deleted file mode 100644
index 332c33c5..00000000
--- a/res/drawable-xhdpi/tv_4a_212.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_213.png b/res/drawable-xhdpi/tv_4a_213.png
deleted file mode 100644
index c9bcf17e..00000000
--- a/res/drawable-xhdpi/tv_4a_213.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_214.png b/res/drawable-xhdpi/tv_4a_214.png
deleted file mode 100644
index 3e36d0c2..00000000
--- a/res/drawable-xhdpi/tv_4a_214.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_215.png b/res/drawable-xhdpi/tv_4a_215.png
deleted file mode 100644
index 6ba79f6b..00000000
--- a/res/drawable-xhdpi/tv_4a_215.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_216.png b/res/drawable-xhdpi/tv_4a_216.png
deleted file mode 100644
index 0edea929..00000000
--- a/res/drawable-xhdpi/tv_4a_216.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_217.png b/res/drawable-xhdpi/tv_4a_217.png
deleted file mode 100644
index 5cfa716d..00000000
--- a/res/drawable-xhdpi/tv_4a_217.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_218.png b/res/drawable-xhdpi/tv_4a_218.png
deleted file mode 100644
index 811f580b..00000000
--- a/res/drawable-xhdpi/tv_4a_218.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_219.png b/res/drawable-xhdpi/tv_4a_219.png
deleted file mode 100644
index 4dd15bbb..00000000
--- a/res/drawable-xhdpi/tv_4a_219.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_22.png b/res/drawable-xhdpi/tv_4a_22.png
deleted file mode 100644
index 570e0ce5..00000000
--- a/res/drawable-xhdpi/tv_4a_22.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_220.png b/res/drawable-xhdpi/tv_4a_220.png
deleted file mode 100644
index 5af35c06..00000000
--- a/res/drawable-xhdpi/tv_4a_220.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_221.png b/res/drawable-xhdpi/tv_4a_221.png
deleted file mode 100644
index 6509b945..00000000
--- a/res/drawable-xhdpi/tv_4a_221.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_222.png b/res/drawable-xhdpi/tv_4a_222.png
deleted file mode 100644
index dc298744..00000000
--- a/res/drawable-xhdpi/tv_4a_222.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_223.png b/res/drawable-xhdpi/tv_4a_223.png
deleted file mode 100644
index 9e9e1d90..00000000
--- a/res/drawable-xhdpi/tv_4a_223.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_224.png b/res/drawable-xhdpi/tv_4a_224.png
deleted file mode 100644
index f3260215..00000000
--- a/res/drawable-xhdpi/tv_4a_224.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_225.png b/res/drawable-xhdpi/tv_4a_225.png
deleted file mode 100644
index bdca9337..00000000
--- a/res/drawable-xhdpi/tv_4a_225.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_226.png b/res/drawable-xhdpi/tv_4a_226.png
deleted file mode 100644
index 75026d6b..00000000
--- a/res/drawable-xhdpi/tv_4a_226.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_227.png b/res/drawable-xhdpi/tv_4a_227.png
deleted file mode 100644
index 0531ea06..00000000
--- a/res/drawable-xhdpi/tv_4a_227.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_228.png b/res/drawable-xhdpi/tv_4a_228.png
deleted file mode 100644
index c558dbf5..00000000
--- a/res/drawable-xhdpi/tv_4a_228.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_229.png b/res/drawable-xhdpi/tv_4a_229.png
deleted file mode 100644
index 570e0ce5..00000000
--- a/res/drawable-xhdpi/tv_4a_229.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_23.png b/res/drawable-xhdpi/tv_4a_23.png
deleted file mode 100644
index 1fd59aca..00000000
--- a/res/drawable-xhdpi/tv_4a_23.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_230.png b/res/drawable-xhdpi/tv_4a_230.png
deleted file mode 100644
index 58852b05..00000000
--- a/res/drawable-xhdpi/tv_4a_230.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_231.png b/res/drawable-xhdpi/tv_4a_231.png
deleted file mode 100644
index 2bbbdc89..00000000
--- a/res/drawable-xhdpi/tv_4a_231.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_232.png b/res/drawable-xhdpi/tv_4a_232.png
deleted file mode 100644
index 06ae31cb..00000000
--- a/res/drawable-xhdpi/tv_4a_232.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_233.png b/res/drawable-xhdpi/tv_4a_233.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_233.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_234.png b/res/drawable-xhdpi/tv_4a_234.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_234.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_235.png b/res/drawable-xhdpi/tv_4a_235.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_235.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_236.png b/res/drawable-xhdpi/tv_4a_236.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_236.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_237.png b/res/drawable-xhdpi/tv_4a_237.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_237.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_238.png b/res/drawable-xhdpi/tv_4a_238.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_238.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_239.png b/res/drawable-xhdpi/tv_4a_239.png
deleted file mode 100644
index 0617761f..00000000
--- a/res/drawable-xhdpi/tv_4a_239.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_24.png b/res/drawable-xhdpi/tv_4a_24.png
deleted file mode 100644
index c558dbf5..00000000
--- a/res/drawable-xhdpi/tv_4a_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_25.png b/res/drawable-xhdpi/tv_4a_25.png
deleted file mode 100644
index 6ab3b6ce..00000000
--- a/res/drawable-xhdpi/tv_4a_25.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_26.png b/res/drawable-xhdpi/tv_4a_26.png
deleted file mode 100644
index 0531ea06..00000000
--- a/res/drawable-xhdpi/tv_4a_26.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_27.png b/res/drawable-xhdpi/tv_4a_27.png
deleted file mode 100644
index ff3b004a..00000000
--- a/res/drawable-xhdpi/tv_4a_27.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_28.png b/res/drawable-xhdpi/tv_4a_28.png
deleted file mode 100644
index 75026d6b..00000000
--- a/res/drawable-xhdpi/tv_4a_28.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_29.png b/res/drawable-xhdpi/tv_4a_29.png
deleted file mode 100644
index e3e0dd78..00000000
--- a/res/drawable-xhdpi/tv_4a_29.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_30.png b/res/drawable-xhdpi/tv_4a_30.png
deleted file mode 100644
index bdca9337..00000000
--- a/res/drawable-xhdpi/tv_4a_30.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_31.png b/res/drawable-xhdpi/tv_4a_31.png
deleted file mode 100644
index 9e4396fa..00000000
--- a/res/drawable-xhdpi/tv_4a_31.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_32.png b/res/drawable-xhdpi/tv_4a_32.png
deleted file mode 100644
index f3260215..00000000
--- a/res/drawable-xhdpi/tv_4a_32.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_33.png b/res/drawable-xhdpi/tv_4a_33.png
deleted file mode 100644
index 7092a216..00000000
--- a/res/drawable-xhdpi/tv_4a_33.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_34.png b/res/drawable-xhdpi/tv_4a_34.png
deleted file mode 100644
index 9e9e1d90..00000000
--- a/res/drawable-xhdpi/tv_4a_34.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_35.png b/res/drawable-xhdpi/tv_4a_35.png
deleted file mode 100644
index 2225b8eb..00000000
--- a/res/drawable-xhdpi/tv_4a_35.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_36.png b/res/drawable-xhdpi/tv_4a_36.png
deleted file mode 100644
index dc298744..00000000
--- a/res/drawable-xhdpi/tv_4a_36.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_37.png b/res/drawable-xhdpi/tv_4a_37.png
deleted file mode 100644
index 3d070286..00000000
--- a/res/drawable-xhdpi/tv_4a_37.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_38.png b/res/drawable-xhdpi/tv_4a_38.png
deleted file mode 100644
index 6509b945..00000000
--- a/res/drawable-xhdpi/tv_4a_38.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_39.png b/res/drawable-xhdpi/tv_4a_39.png
deleted file mode 100644
index 3c454231..00000000
--- a/res/drawable-xhdpi/tv_4a_39.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_40.png b/res/drawable-xhdpi/tv_4a_40.png
deleted file mode 100644
index 5af35c06..00000000
--- a/res/drawable-xhdpi/tv_4a_40.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_41.png b/res/drawable-xhdpi/tv_4a_41.png
deleted file mode 100644
index 0df5a8a3..00000000
--- a/res/drawable-xhdpi/tv_4a_41.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_42.png b/res/drawable-xhdpi/tv_4a_42.png
deleted file mode 100644
index 4dd15bbb..00000000
--- a/res/drawable-xhdpi/tv_4a_42.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_43.png b/res/drawable-xhdpi/tv_4a_43.png
deleted file mode 100644
index 3ea61b8a..00000000
--- a/res/drawable-xhdpi/tv_4a_43.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_44.png b/res/drawable-xhdpi/tv_4a_44.png
deleted file mode 100644
index 811f580b..00000000
--- a/res/drawable-xhdpi/tv_4a_44.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_45.png b/res/drawable-xhdpi/tv_4a_45.png
deleted file mode 100644
index a6a32472..00000000
--- a/res/drawable-xhdpi/tv_4a_45.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_46.png b/res/drawable-xhdpi/tv_4a_46.png
deleted file mode 100644
index 5cfa716d..00000000
--- a/res/drawable-xhdpi/tv_4a_46.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_47.png b/res/drawable-xhdpi/tv_4a_47.png
deleted file mode 100644
index ce9cdb15..00000000
--- a/res/drawable-xhdpi/tv_4a_47.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_48.png b/res/drawable-xhdpi/tv_4a_48.png
deleted file mode 100644
index 0edea929..00000000
--- a/res/drawable-xhdpi/tv_4a_48.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_49.png b/res/drawable-xhdpi/tv_4a_49.png
deleted file mode 100644
index 7a220c97..00000000
--- a/res/drawable-xhdpi/tv_4a_49.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_50.png b/res/drawable-xhdpi/tv_4a_50.png
deleted file mode 100644
index 6ba79f6b..00000000
--- a/res/drawable-xhdpi/tv_4a_50.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_51.png b/res/drawable-xhdpi/tv_4a_51.png
deleted file mode 100644
index 0a01e6a7..00000000
--- a/res/drawable-xhdpi/tv_4a_51.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_52.png b/res/drawable-xhdpi/tv_4a_52.png
deleted file mode 100644
index 3e36d0c2..00000000
--- a/res/drawable-xhdpi/tv_4a_52.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_53.png b/res/drawable-xhdpi/tv_4a_53.png
deleted file mode 100644
index bcafb89f..00000000
--- a/res/drawable-xhdpi/tv_4a_53.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_54.png b/res/drawable-xhdpi/tv_4a_54.png
deleted file mode 100644
index c9bcf17e..00000000
--- a/res/drawable-xhdpi/tv_4a_54.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_55.png b/res/drawable-xhdpi/tv_4a_55.png
deleted file mode 100644
index f7c38cd9..00000000
--- a/res/drawable-xhdpi/tv_4a_55.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_56.png b/res/drawable-xhdpi/tv_4a_56.png
deleted file mode 100644
index 332c33c5..00000000
--- a/res/drawable-xhdpi/tv_4a_56.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_57.png b/res/drawable-xhdpi/tv_4a_57.png
deleted file mode 100644
index f3efda4d..00000000
--- a/res/drawable-xhdpi/tv_4a_57.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_58.png b/res/drawable-xhdpi/tv_4a_58.png
deleted file mode 100644
index 86392dc7..00000000
--- a/res/drawable-xhdpi/tv_4a_58.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_59.png b/res/drawable-xhdpi/tv_4a_59.png
deleted file mode 100644
index a7099c3c..00000000
--- a/res/drawable-xhdpi/tv_4a_59.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_60.png b/res/drawable-xhdpi/tv_4a_60.png
deleted file mode 100644
index 06493959..00000000
--- a/res/drawable-xhdpi/tv_4a_60.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_61.png b/res/drawable-xhdpi/tv_4a_61.png
deleted file mode 100644
index 077a6b70..00000000
--- a/res/drawable-xhdpi/tv_4a_61.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_62.png b/res/drawable-xhdpi/tv_4a_62.png
deleted file mode 100644
index a6d9e927..00000000
--- a/res/drawable-xhdpi/tv_4a_62.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_63.png b/res/drawable-xhdpi/tv_4a_63.png
deleted file mode 100644
index 581acb9f..00000000
--- a/res/drawable-xhdpi/tv_4a_63.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_64.png b/res/drawable-xhdpi/tv_4a_64.png
deleted file mode 100644
index 80813622..00000000
--- a/res/drawable-xhdpi/tv_4a_64.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_65.png b/res/drawable-xhdpi/tv_4a_65.png
deleted file mode 100644
index 728a1b8d..00000000
--- a/res/drawable-xhdpi/tv_4a_65.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_66.png b/res/drawable-xhdpi/tv_4a_66.png
deleted file mode 100644
index ece01e33..00000000
--- a/res/drawable-xhdpi/tv_4a_66.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_67.png b/res/drawable-xhdpi/tv_4a_67.png
deleted file mode 100644
index ffdf5930..00000000
--- a/res/drawable-xhdpi/tv_4a_67.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_68.png b/res/drawable-xhdpi/tv_4a_68.png
deleted file mode 100644
index 31bf96b0..00000000
--- a/res/drawable-xhdpi/tv_4a_68.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_69.png b/res/drawable-xhdpi/tv_4a_69.png
deleted file mode 100644
index 0cd18ae7..00000000
--- a/res/drawable-xhdpi/tv_4a_69.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_70.png b/res/drawable-xhdpi/tv_4a_70.png
deleted file mode 100644
index 61d9acdd..00000000
--- a/res/drawable-xhdpi/tv_4a_70.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_71.png b/res/drawable-xhdpi/tv_4a_71.png
deleted file mode 100644
index ea506d9f..00000000
--- a/res/drawable-xhdpi/tv_4a_71.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_72.png b/res/drawable-xhdpi/tv_4a_72.png
deleted file mode 100644
index 51b48268..00000000
--- a/res/drawable-xhdpi/tv_4a_72.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_73.png b/res/drawable-xhdpi/tv_4a_73.png
deleted file mode 100644
index 1e654a74..00000000
--- a/res/drawable-xhdpi/tv_4a_73.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_74.png b/res/drawable-xhdpi/tv_4a_74.png
deleted file mode 100644
index 76d9e8fd..00000000
--- a/res/drawable-xhdpi/tv_4a_74.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_75.png b/res/drawable-xhdpi/tv_4a_75.png
deleted file mode 100644
index 09e7fc98..00000000
--- a/res/drawable-xhdpi/tv_4a_75.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_76.png b/res/drawable-xhdpi/tv_4a_76.png
deleted file mode 100644
index 26582ffd..00000000
--- a/res/drawable-xhdpi/tv_4a_76.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_77.png b/res/drawable-xhdpi/tv_4a_77.png
deleted file mode 100644
index e1676f05..00000000
--- a/res/drawable-xhdpi/tv_4a_77.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_78.png b/res/drawable-xhdpi/tv_4a_78.png
deleted file mode 100644
index 5120eb64..00000000
--- a/res/drawable-xhdpi/tv_4a_78.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_79.png b/res/drawable-xhdpi/tv_4a_79.png
deleted file mode 100644
index bff6fb05..00000000
--- a/res/drawable-xhdpi/tv_4a_79.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_80.png b/res/drawable-xhdpi/tv_4a_80.png
deleted file mode 100644
index 78b70cb7..00000000
--- a/res/drawable-xhdpi/tv_4a_80.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_81.png b/res/drawable-xhdpi/tv_4a_81.png
deleted file mode 100644
index d959d611..00000000
--- a/res/drawable-xhdpi/tv_4a_81.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_82.png b/res/drawable-xhdpi/tv_4a_82.png
deleted file mode 100644
index 412ad787..00000000
--- a/res/drawable-xhdpi/tv_4a_82.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_83.png b/res/drawable-xhdpi/tv_4a_83.png
deleted file mode 100644
index bc071b4d..00000000
--- a/res/drawable-xhdpi/tv_4a_83.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_84.png b/res/drawable-xhdpi/tv_4a_84.png
deleted file mode 100644
index c12f110c..00000000
--- a/res/drawable-xhdpi/tv_4a_84.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_85.png b/res/drawable-xhdpi/tv_4a_85.png
deleted file mode 100644
index dfa92468..00000000
--- a/res/drawable-xhdpi/tv_4a_85.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_86.png b/res/drawable-xhdpi/tv_4a_86.png
deleted file mode 100644
index 70f744b7..00000000
--- a/res/drawable-xhdpi/tv_4a_86.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_87.png b/res/drawable-xhdpi/tv_4a_87.png
deleted file mode 100644
index 0f3edd9a..00000000
--- a/res/drawable-xhdpi/tv_4a_87.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_88.png b/res/drawable-xhdpi/tv_4a_88.png
deleted file mode 100644
index c747c956..00000000
--- a/res/drawable-xhdpi/tv_4a_88.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_89.png b/res/drawable-xhdpi/tv_4a_89.png
deleted file mode 100644
index a9845213..00000000
--- a/res/drawable-xhdpi/tv_4a_89.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_90.png b/res/drawable-xhdpi/tv_4a_90.png
deleted file mode 100644
index d6739c39..00000000
--- a/res/drawable-xhdpi/tv_4a_90.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_91.png b/res/drawable-xhdpi/tv_4a_91.png
deleted file mode 100644
index 160665f6..00000000
--- a/res/drawable-xhdpi/tv_4a_91.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_92.png b/res/drawable-xhdpi/tv_4a_92.png
deleted file mode 100644
index 3131c25c..00000000
--- a/res/drawable-xhdpi/tv_4a_92.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_93.png b/res/drawable-xhdpi/tv_4a_93.png
deleted file mode 100644
index 6028a9cb..00000000
--- a/res/drawable-xhdpi/tv_4a_93.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_94.png b/res/drawable-xhdpi/tv_4a_94.png
deleted file mode 100644
index 32e490cf..00000000
--- a/res/drawable-xhdpi/tv_4a_94.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_95.png b/res/drawable-xhdpi/tv_4a_95.png
deleted file mode 100644
index b6647429..00000000
--- a/res/drawable-xhdpi/tv_4a_95.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_96.png b/res/drawable-xhdpi/tv_4a_96.png
deleted file mode 100644
index a2246180..00000000
--- a/res/drawable-xhdpi/tv_4a_96.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_97.png b/res/drawable-xhdpi/tv_4a_97.png
deleted file mode 100644
index 6940909b..00000000
--- a/res/drawable-xhdpi/tv_4a_97.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_98.png b/res/drawable-xhdpi/tv_4a_98.png
deleted file mode 100644
index 4726c064..00000000
--- a/res/drawable-xhdpi/tv_4a_98.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_4a_99.png b/res/drawable-xhdpi/tv_4a_99.png
deleted file mode 100644
index 9764fd62..00000000
--- a/res/drawable-xhdpi/tv_4a_99.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_0.png b/res/drawable-xhdpi/tv_5a_0.png
new file mode 100644
index 00000000..3d753702
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_0.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_1.png b/res/drawable-xhdpi/tv_5a_1.png
new file mode 100644
index 00000000..9cc9fa3e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_1.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_10.png b/res/drawable-xhdpi/tv_5a_10.png
new file mode 100644
index 00000000..38b9d484
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_10.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_100.png b/res/drawable-xhdpi/tv_5a_100.png
new file mode 100644
index 00000000..8ed2652b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_100.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_101.png b/res/drawable-xhdpi/tv_5a_101.png
new file mode 100644
index 00000000..07e22d1b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_101.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_102.png b/res/drawable-xhdpi/tv_5a_102.png
new file mode 100644
index 00000000..cc24e4d0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_102.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_103.png b/res/drawable-xhdpi/tv_5a_103.png
new file mode 100644
index 00000000..76a1924e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_103.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_104.png b/res/drawable-xhdpi/tv_5a_104.png
new file mode 100644
index 00000000..f5b47313
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_104.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_105.png b/res/drawable-xhdpi/tv_5a_105.png
new file mode 100644
index 00000000..23050cf8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_105.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_106.png b/res/drawable-xhdpi/tv_5a_106.png
new file mode 100644
index 00000000..e2e80bf6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_106.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_107.png b/res/drawable-xhdpi/tv_5a_107.png
new file mode 100644
index 00000000..d992438d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_107.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_108.png b/res/drawable-xhdpi/tv_5a_108.png
new file mode 100644
index 00000000..55ea31b0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_108.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_109.png b/res/drawable-xhdpi/tv_5a_109.png
new file mode 100644
index 00000000..176e044f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_109.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_11.png b/res/drawable-xhdpi/tv_5a_11.png
new file mode 100644
index 00000000..44916dde
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_11.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_110.png b/res/drawable-xhdpi/tv_5a_110.png
new file mode 100644
index 00000000..2cad75ab
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_110.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_111.png b/res/drawable-xhdpi/tv_5a_111.png
new file mode 100644
index 00000000..9ac668f0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_111.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_112.png b/res/drawable-xhdpi/tv_5a_112.png
new file mode 100644
index 00000000..e47141c8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_112.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_113.png b/res/drawable-xhdpi/tv_5a_113.png
new file mode 100644
index 00000000..bba837a9
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_113.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_114.png b/res/drawable-xhdpi/tv_5a_114.png
new file mode 100644
index 00000000..e9ae154e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_114.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_115.png b/res/drawable-xhdpi/tv_5a_115.png
new file mode 100644
index 00000000..02576883
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_115.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_116.png b/res/drawable-xhdpi/tv_5a_116.png
new file mode 100644
index 00000000..e5790b52
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_116.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_117.png b/res/drawable-xhdpi/tv_5a_117.png
new file mode 100644
index 00000000..905c1f82
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_117.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_118.png b/res/drawable-xhdpi/tv_5a_118.png
new file mode 100644
index 00000000..41368661
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_118.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_119.png b/res/drawable-xhdpi/tv_5a_119.png
new file mode 100644
index 00000000..1f18d2e7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_119.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_12.png b/res/drawable-xhdpi/tv_5a_12.png
new file mode 100644
index 00000000..fce782ab
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_12.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_120.png b/res/drawable-xhdpi/tv_5a_120.png
new file mode 100644
index 00000000..1f15afa9
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_120.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_121.png b/res/drawable-xhdpi/tv_5a_121.png
new file mode 100644
index 00000000..774c7c01
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_121.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_122.png b/res/drawable-xhdpi/tv_5a_122.png
new file mode 100644
index 00000000..b1423dca
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_122.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_123.png b/res/drawable-xhdpi/tv_5a_123.png
new file mode 100644
index 00000000..39121f4f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_123.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_124.png b/res/drawable-xhdpi/tv_5a_124.png
new file mode 100644
index 00000000..4cd4b2d0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_124.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_125.png b/res/drawable-xhdpi/tv_5a_125.png
new file mode 100644
index 00000000..dfdcfa9e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_125.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_126.png b/res/drawable-xhdpi/tv_5a_126.png
new file mode 100644
index 00000000..843257af
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_126.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_127.png b/res/drawable-xhdpi/tv_5a_127.png
new file mode 100644
index 00000000..b476e46a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_127.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_128.png b/res/drawable-xhdpi/tv_5a_128.png
new file mode 100644
index 00000000..f3035b35
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_128.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_129.png b/res/drawable-xhdpi/tv_5a_129.png
new file mode 100644
index 00000000..538eb014
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_129.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_13.png b/res/drawable-xhdpi/tv_5a_13.png
new file mode 100644
index 00000000..e17b230c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_13.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_130.png b/res/drawable-xhdpi/tv_5a_130.png
new file mode 100644
index 00000000..925495e8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_130.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_131.png b/res/drawable-xhdpi/tv_5a_131.png
new file mode 100644
index 00000000..9635a451
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_131.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_132.png b/res/drawable-xhdpi/tv_5a_132.png
new file mode 100644
index 00000000..8b43bb56
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_132.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_133.png b/res/drawable-xhdpi/tv_5a_133.png
new file mode 100644
index 00000000..a19c7086
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_133.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_134.png b/res/drawable-xhdpi/tv_5a_134.png
new file mode 100644
index 00000000..a751a957
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_134.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_135.png b/res/drawable-xhdpi/tv_5a_135.png
new file mode 100644
index 00000000..31cc274e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_135.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_136.png b/res/drawable-xhdpi/tv_5a_136.png
new file mode 100644
index 00000000..f3279a46
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_136.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_137.png b/res/drawable-xhdpi/tv_5a_137.png
new file mode 100644
index 00000000..8d790220
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_137.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_138.png b/res/drawable-xhdpi/tv_5a_138.png
new file mode 100644
index 00000000..6ab3d5cb
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_138.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_139.png b/res/drawable-xhdpi/tv_5a_139.png
new file mode 100644
index 00000000..909dff91
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_139.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_14.png b/res/drawable-xhdpi/tv_5a_14.png
new file mode 100644
index 00000000..9bc86099
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_14.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_140.png b/res/drawable-xhdpi/tv_5a_140.png
new file mode 100644
index 00000000..09775707
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_140.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_141.png b/res/drawable-xhdpi/tv_5a_141.png
new file mode 100644
index 00000000..20fedcf6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_141.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_142.png b/res/drawable-xhdpi/tv_5a_142.png
new file mode 100644
index 00000000..2475ee01
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_142.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_143.png b/res/drawable-xhdpi/tv_5a_143.png
new file mode 100644
index 00000000..11eb54fa
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_143.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_144.png b/res/drawable-xhdpi/tv_5a_144.png
new file mode 100644
index 00000000..cc2d5003
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_144.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_145.png b/res/drawable-xhdpi/tv_5a_145.png
new file mode 100644
index 00000000..6916f6ed
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_145.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_146.png b/res/drawable-xhdpi/tv_5a_146.png
new file mode 100644
index 00000000..5858da84
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_146.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_147.png b/res/drawable-xhdpi/tv_5a_147.png
new file mode 100644
index 00000000..2a027432
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_147.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_148.png b/res/drawable-xhdpi/tv_5a_148.png
new file mode 100644
index 00000000..e3a1c3f8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_148.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_149.png b/res/drawable-xhdpi/tv_5a_149.png
new file mode 100644
index 00000000..0f1ec7bc
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_149.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_15.png b/res/drawable-xhdpi/tv_5a_15.png
new file mode 100644
index 00000000..02b2dd2e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_15.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_150.png b/res/drawable-xhdpi/tv_5a_150.png
new file mode 100644
index 00000000..ece4ebcc
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_150.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_151.png b/res/drawable-xhdpi/tv_5a_151.png
new file mode 100644
index 00000000..b58cd0a8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_151.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_152.png b/res/drawable-xhdpi/tv_5a_152.png
new file mode 100644
index 00000000..c4f82ab8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_152.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_153.png b/res/drawable-xhdpi/tv_5a_153.png
new file mode 100644
index 00000000..32dbc075
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_153.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_154.png b/res/drawable-xhdpi/tv_5a_154.png
new file mode 100644
index 00000000..64c12438
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_154.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_155.png b/res/drawable-xhdpi/tv_5a_155.png
new file mode 100644
index 00000000..512b61c8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_155.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_156.png b/res/drawable-xhdpi/tv_5a_156.png
new file mode 100644
index 00000000..3b88a6c9
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_156.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_157.png b/res/drawable-xhdpi/tv_5a_157.png
new file mode 100644
index 00000000..a6efdc3d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_157.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_158.png b/res/drawable-xhdpi/tv_5a_158.png
new file mode 100644
index 00000000..7e8e2895
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_158.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_159.png b/res/drawable-xhdpi/tv_5a_159.png
new file mode 100644
index 00000000..ece0a2e6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_159.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_16.png b/res/drawable-xhdpi/tv_5a_16.png
new file mode 100644
index 00000000..1c698441
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_16.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_160.png b/res/drawable-xhdpi/tv_5a_160.png
new file mode 100644
index 00000000..6e0104ff
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_160.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_161.png b/res/drawable-xhdpi/tv_5a_161.png
new file mode 100644
index 00000000..d48b5af3
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_161.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_162.png b/res/drawable-xhdpi/tv_5a_162.png
new file mode 100644
index 00000000..7723103f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_162.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_163.png b/res/drawable-xhdpi/tv_5a_163.png
new file mode 100644
index 00000000..18b048ee
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_163.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_164.png b/res/drawable-xhdpi/tv_5a_164.png
new file mode 100644
index 00000000..eee70024
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_164.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_165.png b/res/drawable-xhdpi/tv_5a_165.png
new file mode 100644
index 00000000..1f81c761
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_165.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_166.png b/res/drawable-xhdpi/tv_5a_166.png
new file mode 100644
index 00000000..1bc5513e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_166.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_167.png b/res/drawable-xhdpi/tv_5a_167.png
new file mode 100644
index 00000000..95f60956
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_167.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_168.png b/res/drawable-xhdpi/tv_5a_168.png
new file mode 100644
index 00000000..d4647df7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_168.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_169.png b/res/drawable-xhdpi/tv_5a_169.png
new file mode 100644
index 00000000..98401ba8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_169.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_17.png b/res/drawable-xhdpi/tv_5a_17.png
new file mode 100644
index 00000000..1c6af939
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_17.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_170.png b/res/drawable-xhdpi/tv_5a_170.png
new file mode 100644
index 00000000..10dd5b06
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_170.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_171.png b/res/drawable-xhdpi/tv_5a_171.png
new file mode 100644
index 00000000..37a66d13
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_171.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_172.png b/res/drawable-xhdpi/tv_5a_172.png
new file mode 100644
index 00000000..8d492a15
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_172.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_173.png b/res/drawable-xhdpi/tv_5a_173.png
new file mode 100644
index 00000000..70af1a45
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_173.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_174.png b/res/drawable-xhdpi/tv_5a_174.png
new file mode 100644
index 00000000..8ddeca3a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_174.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_175.png b/res/drawable-xhdpi/tv_5a_175.png
new file mode 100644
index 00000000..e65e6bc2
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_175.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_176.png b/res/drawable-xhdpi/tv_5a_176.png
new file mode 100644
index 00000000..b40d9b3b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_176.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_177.png b/res/drawable-xhdpi/tv_5a_177.png
new file mode 100644
index 00000000..403234a6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_177.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_178.png b/res/drawable-xhdpi/tv_5a_178.png
new file mode 100644
index 00000000..2687abd8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_178.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_179.png b/res/drawable-xhdpi/tv_5a_179.png
new file mode 100644
index 00000000..137d697b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_179.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_18.png b/res/drawable-xhdpi/tv_5a_18.png
new file mode 100644
index 00000000..977bbe50
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_18.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_180.png b/res/drawable-xhdpi/tv_5a_180.png
new file mode 100644
index 00000000..d2fc5656
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_180.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_181.png b/res/drawable-xhdpi/tv_5a_181.png
new file mode 100644
index 00000000..145f92ec
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_181.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_182.png b/res/drawable-xhdpi/tv_5a_182.png
new file mode 100644
index 00000000..24b78db1
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_182.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_183.png b/res/drawable-xhdpi/tv_5a_183.png
new file mode 100644
index 00000000..36ab2cea
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_183.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_184.png b/res/drawable-xhdpi/tv_5a_184.png
new file mode 100644
index 00000000..bc6a5ea1
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_184.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_185.png b/res/drawable-xhdpi/tv_5a_185.png
new file mode 100644
index 00000000..926adde7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_185.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_186.png b/res/drawable-xhdpi/tv_5a_186.png
new file mode 100644
index 00000000..36418764
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_186.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_187.png b/res/drawable-xhdpi/tv_5a_187.png
new file mode 100644
index 00000000..ca07a19c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_187.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_188.png b/res/drawable-xhdpi/tv_5a_188.png
new file mode 100644
index 00000000..1c9ecdea
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_188.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_189.png b/res/drawable-xhdpi/tv_5a_189.png
new file mode 100644
index 00000000..1147f390
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_189.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_19.png b/res/drawable-xhdpi/tv_5a_19.png
new file mode 100644
index 00000000..7bfad09d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_19.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_190.png b/res/drawable-xhdpi/tv_5a_190.png
new file mode 100644
index 00000000..71b00ec1
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_190.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_191.png b/res/drawable-xhdpi/tv_5a_191.png
new file mode 100644
index 00000000..9c19b818
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_191.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_192.png b/res/drawable-xhdpi/tv_5a_192.png
new file mode 100644
index 00000000..0da98bf1
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_192.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_193.png b/res/drawable-xhdpi/tv_5a_193.png
new file mode 100644
index 00000000..030df5ab
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_193.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_194.png b/res/drawable-xhdpi/tv_5a_194.png
new file mode 100644
index 00000000..6e424508
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_194.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_195.png b/res/drawable-xhdpi/tv_5a_195.png
new file mode 100644
index 00000000..d2c5c3f0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_195.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_196.png b/res/drawable-xhdpi/tv_5a_196.png
new file mode 100644
index 00000000..8f273f36
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_196.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_197.png b/res/drawable-xhdpi/tv_5a_197.png
new file mode 100644
index 00000000..6408bffe
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_197.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_198.png b/res/drawable-xhdpi/tv_5a_198.png
new file mode 100644
index 00000000..ed5383a4
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_198.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_199.png b/res/drawable-xhdpi/tv_5a_199.png
new file mode 100644
index 00000000..80435ca4
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_199.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_2.png b/res/drawable-xhdpi/tv_5a_2.png
new file mode 100644
index 00000000..89da06ff
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_2.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_20.png b/res/drawable-xhdpi/tv_5a_20.png
new file mode 100644
index 00000000..198beeb2
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_20.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_200.png b/res/drawable-xhdpi/tv_5a_200.png
new file mode 100644
index 00000000..1f64389f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_200.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_201.png b/res/drawable-xhdpi/tv_5a_201.png
new file mode 100644
index 00000000..2e662da6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_201.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_202.png b/res/drawable-xhdpi/tv_5a_202.png
new file mode 100644
index 00000000..47bee69c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_202.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_203.png b/res/drawable-xhdpi/tv_5a_203.png
new file mode 100644
index 00000000..02ef3b46
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_203.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_204.png b/res/drawable-xhdpi/tv_5a_204.png
new file mode 100644
index 00000000..fc6bee1c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_204.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_205.png b/res/drawable-xhdpi/tv_5a_205.png
new file mode 100644
index 00000000..8b2830e2
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_205.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_206.png b/res/drawable-xhdpi/tv_5a_206.png
new file mode 100644
index 00000000..79092421
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_206.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_207.png b/res/drawable-xhdpi/tv_5a_207.png
new file mode 100644
index 00000000..8158112f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_207.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_208.png b/res/drawable-xhdpi/tv_5a_208.png
new file mode 100644
index 00000000..bb9cd2ef
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_208.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_209.png b/res/drawable-xhdpi/tv_5a_209.png
new file mode 100644
index 00000000..bc4895db
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_209.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_21.png b/res/drawable-xhdpi/tv_5a_21.png
new file mode 100644
index 00000000..90da19a6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_21.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_210.png b/res/drawable-xhdpi/tv_5a_210.png
new file mode 100644
index 00000000..b076fa0b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_210.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_211.png b/res/drawable-xhdpi/tv_5a_211.png
new file mode 100644
index 00000000..425b056a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_211.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_212.png b/res/drawable-xhdpi/tv_5a_212.png
new file mode 100644
index 00000000..7114ac8c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_212.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_213.png b/res/drawable-xhdpi/tv_5a_213.png
new file mode 100644
index 00000000..2fc84caf
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_213.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_214.png b/res/drawable-xhdpi/tv_5a_214.png
new file mode 100644
index 00000000..44d5bc01
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_214.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_215.png b/res/drawable-xhdpi/tv_5a_215.png
new file mode 100644
index 00000000..80c0edaf
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_215.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_216.png b/res/drawable-xhdpi/tv_5a_216.png
new file mode 100644
index 00000000..18c9228e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_216.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_217.png b/res/drawable-xhdpi/tv_5a_217.png
new file mode 100644
index 00000000..f6455864
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_217.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_218.png b/res/drawable-xhdpi/tv_5a_218.png
new file mode 100644
index 00000000..4efeb59d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_218.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_219.png b/res/drawable-xhdpi/tv_5a_219.png
new file mode 100644
index 00000000..b5bb59e2
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_219.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_22.png b/res/drawable-xhdpi/tv_5a_22.png
new file mode 100644
index 00000000..d825b30d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_22.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_220.png b/res/drawable-xhdpi/tv_5a_220.png
new file mode 100644
index 00000000..b6738f44
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_220.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_221.png b/res/drawable-xhdpi/tv_5a_221.png
new file mode 100644
index 00000000..f5707003
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_221.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_222.png b/res/drawable-xhdpi/tv_5a_222.png
new file mode 100644
index 00000000..148d0fc8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_222.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_223.png b/res/drawable-xhdpi/tv_5a_223.png
new file mode 100644
index 00000000..ca8a17c9
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_223.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_224.png b/res/drawable-xhdpi/tv_5a_224.png
new file mode 100644
index 00000000..ff478637
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_224.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_23.png b/res/drawable-xhdpi/tv_5a_23.png
new file mode 100644
index 00000000..229f0540
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_23.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_24.png b/res/drawable-xhdpi/tv_5a_24.png
new file mode 100644
index 00000000..3033d442
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_25.png b/res/drawable-xhdpi/tv_5a_25.png
new file mode 100644
index 00000000..cab95c71
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_25.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_26.png b/res/drawable-xhdpi/tv_5a_26.png
new file mode 100644
index 00000000..e773785d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_26.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_27.png b/res/drawable-xhdpi/tv_5a_27.png
new file mode 100644
index 00000000..64ebf81a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_27.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_28.png b/res/drawable-xhdpi/tv_5a_28.png
new file mode 100644
index 00000000..5e5c8e9c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_28.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_29.png b/res/drawable-xhdpi/tv_5a_29.png
new file mode 100644
index 00000000..8cfcdea3
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_29.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_3.png b/res/drawable-xhdpi/tv_5a_3.png
new file mode 100644
index 00000000..8fc7be9a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_3.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_30.png b/res/drawable-xhdpi/tv_5a_30.png
new file mode 100644
index 00000000..f7ce5616
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_30.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_31.png b/res/drawable-xhdpi/tv_5a_31.png
new file mode 100644
index 00000000..29810aea
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_31.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_32.png b/res/drawable-xhdpi/tv_5a_32.png
new file mode 100644
index 00000000..28e1abec
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_32.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_33.png b/res/drawable-xhdpi/tv_5a_33.png
new file mode 100644
index 00000000..5da41c32
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_33.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_34.png b/res/drawable-xhdpi/tv_5a_34.png
new file mode 100644
index 00000000..ac068b1e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_34.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_35.png b/res/drawable-xhdpi/tv_5a_35.png
new file mode 100644
index 00000000..6f0bf74b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_35.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_36.png b/res/drawable-xhdpi/tv_5a_36.png
new file mode 100644
index 00000000..8ef2bbe0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_36.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_37.png b/res/drawable-xhdpi/tv_5a_37.png
new file mode 100644
index 00000000..ba5ce380
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_37.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_38.png b/res/drawable-xhdpi/tv_5a_38.png
new file mode 100644
index 00000000..fd1fcbd8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_38.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_39.png b/res/drawable-xhdpi/tv_5a_39.png
new file mode 100644
index 00000000..08d591cd
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_39.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_4.png b/res/drawable-xhdpi/tv_5a_4.png
new file mode 100644
index 00000000..c64431ba
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_4.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_40.png b/res/drawable-xhdpi/tv_5a_40.png
new file mode 100644
index 00000000..266dc292
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_40.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_41.png b/res/drawable-xhdpi/tv_5a_41.png
new file mode 100644
index 00000000..5faefaff
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_41.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_42.png b/res/drawable-xhdpi/tv_5a_42.png
new file mode 100644
index 00000000..93aa1049
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_42.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_43.png b/res/drawable-xhdpi/tv_5a_43.png
new file mode 100644
index 00000000..e0bcfc79
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_43.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_44.png b/res/drawable-xhdpi/tv_5a_44.png
new file mode 100644
index 00000000..111a642a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_44.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_45.png b/res/drawable-xhdpi/tv_5a_45.png
new file mode 100644
index 00000000..535480fa
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_45.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_46.png b/res/drawable-xhdpi/tv_5a_46.png
new file mode 100644
index 00000000..60e13657
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_46.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_47.png b/res/drawable-xhdpi/tv_5a_47.png
new file mode 100644
index 00000000..f5e9789b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_47.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_48.png b/res/drawable-xhdpi/tv_5a_48.png
new file mode 100644
index 00000000..80b1049e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_48.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_49.png b/res/drawable-xhdpi/tv_5a_49.png
new file mode 100644
index 00000000..ecc35dd8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_49.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_5.png b/res/drawable-xhdpi/tv_5a_5.png
new file mode 100644
index 00000000..7e034db0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_5.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_50.png b/res/drawable-xhdpi/tv_5a_50.png
new file mode 100644
index 00000000..2fa70004
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_50.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_51.png b/res/drawable-xhdpi/tv_5a_51.png
new file mode 100644
index 00000000..352edda3
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_51.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_52.png b/res/drawable-xhdpi/tv_5a_52.png
new file mode 100644
index 00000000..c05beba5
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_52.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_53.png b/res/drawable-xhdpi/tv_5a_53.png
new file mode 100644
index 00000000..af91dfc9
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_53.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_54.png b/res/drawable-xhdpi/tv_5a_54.png
new file mode 100644
index 00000000..5c75f718
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_54.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_55.png b/res/drawable-xhdpi/tv_5a_55.png
new file mode 100644
index 00000000..6178c59f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_55.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_56.png b/res/drawable-xhdpi/tv_5a_56.png
new file mode 100644
index 00000000..f3d72c4d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_56.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_57.png b/res/drawable-xhdpi/tv_5a_57.png
new file mode 100644
index 00000000..f4df992c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_57.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_58.png b/res/drawable-xhdpi/tv_5a_58.png
new file mode 100644
index 00000000..2dd2f581
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_58.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_59.png b/res/drawable-xhdpi/tv_5a_59.png
new file mode 100644
index 00000000..158faadd
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_59.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_6.png b/res/drawable-xhdpi/tv_5a_6.png
new file mode 100644
index 00000000..f75b91e6
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_6.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_60.png b/res/drawable-xhdpi/tv_5a_60.png
new file mode 100644
index 00000000..215605a7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_60.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_61.png b/res/drawable-xhdpi/tv_5a_61.png
new file mode 100644
index 00000000..368e96e1
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_61.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_62.png b/res/drawable-xhdpi/tv_5a_62.png
new file mode 100644
index 00000000..a2d4abde
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_62.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_63.png b/res/drawable-xhdpi/tv_5a_63.png
new file mode 100644
index 00000000..f8049b44
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_63.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_64.png b/res/drawable-xhdpi/tv_5a_64.png
new file mode 100644
index 00000000..0bc47374
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_64.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_65.png b/res/drawable-xhdpi/tv_5a_65.png
new file mode 100644
index 00000000..ac9324f2
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_65.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_66.png b/res/drawable-xhdpi/tv_5a_66.png
new file mode 100644
index 00000000..c4417604
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_66.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_67.png b/res/drawable-xhdpi/tv_5a_67.png
new file mode 100644
index 00000000..0506e37e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_67.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_68.png b/res/drawable-xhdpi/tv_5a_68.png
new file mode 100644
index 00000000..17978c4f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_68.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_69.png b/res/drawable-xhdpi/tv_5a_69.png
new file mode 100644
index 00000000..4c47cb8a
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_69.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_7.png b/res/drawable-xhdpi/tv_5a_7.png
new file mode 100644
index 00000000..a013bdc5
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_7.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_70.png b/res/drawable-xhdpi/tv_5a_70.png
new file mode 100644
index 00000000..126e6a3d
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_70.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_71.png b/res/drawable-xhdpi/tv_5a_71.png
new file mode 100644
index 00000000..1af44e22
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_71.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_72.png b/res/drawable-xhdpi/tv_5a_72.png
new file mode 100644
index 00000000..23b19648
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_72.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_73.png b/res/drawable-xhdpi/tv_5a_73.png
new file mode 100644
index 00000000..873d43b3
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_73.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_74.png b/res/drawable-xhdpi/tv_5a_74.png
new file mode 100644
index 00000000..b81c61fa
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_74.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_75.png b/res/drawable-xhdpi/tv_5a_75.png
new file mode 100644
index 00000000..336d5e81
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_75.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_76.png b/res/drawable-xhdpi/tv_5a_76.png
new file mode 100644
index 00000000..3f9bd07f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_76.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_77.png b/res/drawable-xhdpi/tv_5a_77.png
new file mode 100644
index 00000000..4659b925
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_77.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_78.png b/res/drawable-xhdpi/tv_5a_78.png
new file mode 100644
index 00000000..5ca27e6e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_78.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_79.png b/res/drawable-xhdpi/tv_5a_79.png
new file mode 100644
index 00000000..a033cab0
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_79.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_8.png b/res/drawable-xhdpi/tv_5a_8.png
new file mode 100644
index 00000000..2d928940
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_8.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_80.png b/res/drawable-xhdpi/tv_5a_80.png
new file mode 100644
index 00000000..6c79d7a7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_80.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_81.png b/res/drawable-xhdpi/tv_5a_81.png
new file mode 100644
index 00000000..9095cd20
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_81.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_82.png b/res/drawable-xhdpi/tv_5a_82.png
new file mode 100644
index 00000000..43641c3b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_82.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_83.png b/res/drawable-xhdpi/tv_5a_83.png
new file mode 100644
index 00000000..72204d82
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_83.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_84.png b/res/drawable-xhdpi/tv_5a_84.png
new file mode 100644
index 00000000..450fb2ca
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_84.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_85.png b/res/drawable-xhdpi/tv_5a_85.png
new file mode 100644
index 00000000..4145ea47
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_85.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_86.png b/res/drawable-xhdpi/tv_5a_86.png
new file mode 100644
index 00000000..5459784e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_86.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_87.png b/res/drawable-xhdpi/tv_5a_87.png
new file mode 100644
index 00000000..9a36a9ae
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_87.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_88.png b/res/drawable-xhdpi/tv_5a_88.png
new file mode 100644
index 00000000..dc8fca0e
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_88.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_89.png b/res/drawable-xhdpi/tv_5a_89.png
new file mode 100644
index 00000000..42f54a05
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_89.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_9.png b/res/drawable-xhdpi/tv_5a_9.png
new file mode 100644
index 00000000..e502f31f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_90.png b/res/drawable-xhdpi/tv_5a_90.png
new file mode 100644
index 00000000..693b1509
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_90.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_91.png b/res/drawable-xhdpi/tv_5a_91.png
new file mode 100644
index 00000000..088cc56c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_91.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_92.png b/res/drawable-xhdpi/tv_5a_92.png
new file mode 100644
index 00000000..8875a7dd
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_92.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_93.png b/res/drawable-xhdpi/tv_5a_93.png
new file mode 100644
index 00000000..5107cac8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_93.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_94.png b/res/drawable-xhdpi/tv_5a_94.png
new file mode 100644
index 00000000..28184866
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_94.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_95.png b/res/drawable-xhdpi/tv_5a_95.png
new file mode 100644
index 00000000..3dfa26d7
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_95.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_96.png b/res/drawable-xhdpi/tv_5a_96.png
new file mode 100644
index 00000000..d10f3b9c
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_96.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_97.png b/res/drawable-xhdpi/tv_5a_97.png
new file mode 100644
index 00000000..eb0e246b
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_97.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_98.png b/res/drawable-xhdpi/tv_5a_98.png
new file mode 100644
index 00000000..9f8f54c8
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_98.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_5a_99.png b/res/drawable-xhdpi/tv_5a_99.png
new file mode 100644
index 00000000..a7b3ec2f
--- /dev/null
+++ b/res/drawable-xhdpi/tv_5a_99.png
Binary files differ
diff --git a/res/layout/dvr_main.xml b/res/layout/dvr_main.xml
new file mode 100644
index 00000000..bac1cc91
--- /dev/null
+++ b/res/layout/dvr_main.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/dvr_frame"
+ android:name="com.android.tv.dvr.ui.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
new file mode 100644
index 00000000..4df13686
--- /dev/null
+++ b/res/layout/dvr_play.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
+ -->
+
+<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/fragment_new_sources.xml b/res/layout/fragment_new_sources.xml
new file mode 100644
index 00000000..7a46dcdf
--- /dev/null
+++ b/res/layout/fragment_new_sources.xml
@@ -0,0 +1,83 @@
+<?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.
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:background="@color/common_tv_background"
+ android:paddingStart="40dp"
+ android:paddingEnd="56dp"
+ android:paddingTop="44dp"
+ android:paddingBottom="27dp">
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_marginTop="8dp"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"
+ android:scaleType="centerInside"
+ android:src="@drawable/ic_tvoption_channel_sources" />
+ <Button
+ android:id="@+id/setup"
+ style="@style/Widget.Setup.GuidedActionItemContainerStyle"
+ android:layout_width="306dp"
+ android:layout_height="45dp"
+ android:layout_marginTop="7dp"
+ android:layout_alignParentEnd="true"
+ android:layout_marginStart="56dp"
+ android:background="@null"
+ android:foreground="@drawable/setup_selector_background"
+ android:gravity="start"
+ android:text="@string/new_sources_action_setup"/>
+ <Button
+ android:id="@+id/skip"
+ style="@style/Widget.Setup.GuidedActionItemContainerStyle"
+ android:layout_width="306dp"
+ android:layout_height="45dp"
+ android:layout_alignParentEnd="true"
+ android:layout_below="@id/setup"
+ android:background="@null"
+ android:foreground="@drawable/setup_selector_background"
+ android:gravity="start"
+ android:text="@string/new_sources_action_skip"/>
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="11dp"
+ android:layout_marginBottom="18dp"
+ android:layout_toEndOf="@id/icon"
+ android:layout_toStartOf="@+id/setup"
+ android:fontFamily="@string/light_font"
+ android:textColor="#EEEEEE"
+ android:text="@string/new_sources_title"
+ android:textSize="34sp"/>
+ <TextView
+ android:id="@+id/description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_marginBottom="8dp"
+ android:layout_toEndOf="@id/icon"
+ android:layout_toStartOf="@id/setup"
+ android:fontFamily="@string/light_font"
+ android:text="@string/new_sources_description"
+ android:textColor="#ADEEEEEE"/>
+</RelativeLayout>
diff --git a/res/layout/fragment_welcome.xml b/res/layout/fragment_welcome.xml
deleted file mode 100644
index bf336665..00000000
--- a/res/layout/fragment_welcome.xml
+++ /dev/null
@@ -1,114 +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.
- -->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/welcome_fragment_root"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false">
-
- <FrameLayout
- android:id="@+id/page_container"
- android:layout_width="@dimen/onboarding_welcome_content_width"
- android:layout_height="100dp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="64dp"
- android:clipChildren="false"
- android:clipToPadding="false" />
-
- <FrameLayout
- android:id="@+id/tv_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/page_container"
- android:layout_marginTop="67dp"
- android:layout_centerHorizontal="true"
- android:transitionGroup="true">
- <ImageView
- android:layout_width="215dp"
- android:layout_height="128dp"
- android:layout_gravity="center"
- android:contentDescription="@null"
- android:src="@drawable/tv_bg" />
- <ImageView
- android:id="@+id/tv_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:contentDescription="@null"
- android:src="@drawable/tv_1a_01" />
- </FrameLayout>
-
- <ImageView
- android:id="@+id/shadow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/tv_container"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="16dp"
- android:src="@drawable/tv_shadow"
- android:contentDescription="@null" />
-
- <com.android.tv.onboarding.PagingIndicator
- android:id="@+id/page_indicator"
- android:layout_width="@dimen/onboarding_welcome_content_width"
- android:layout_height="36dp"
- android:layout_below="@id/shadow"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="50dp"
- android:focusable="true" />
-
- <ImageView
- android:id="@+id/cloud1"
- android:layout_width="182dp"
- android:layout_height="114dp"
- android:layout_marginTop="140dp"
- android:layout_marginStart="-47dp"
- android:layout_alignParentStart="true"
- android:src="@drawable/cloud01"
- android:contentDescription="@null" />
-
- <ImageView
- android:id="@+id/cloud2"
- android:layout_width="120dp"
- android:layout_height="74dp"
- android:layout_marginTop="100dp"
- android:layout_marginEnd="-40dp"
- android:layout_alignParentEnd="true"
- android:src="@drawable/cloud02"
- android:contentDescription="@null" />
-
- <ImageView
- android:id="@+id/arrow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="70dp"
- android:layout_alignBottom="@id/tv_container"
- android:layout_centerHorizontal="true"
- android:contentDescription="@null"
- android:visibility="gone" />
-
- <ImageView
- android:id="@+id/logo"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:src="@drawable/splash_logo"
- android:contentDescription="@null" />
-</RelativeLayout>
diff --git a/res/layout/fragment_welcome_page.xml b/res/layout/fragment_welcome_page.xml
deleted file mode 100644
index c60877ec..00000000
--- a/res/layout/fragment_welcome_page.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.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/welcome_page_fragment_root"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.5"
- android:layout_marginBottom="3dp"
- android:fontFamily="@string/light_font"
- android:gravity="center"
- android:textColor="#EEEEEE"
- android:textSize="34sp"
- android:lineSpacingExtra="14sp"/>
-
- <TextView
- android:id="@+id/description"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.5"
- android:layout_marginTop="3dp"
- android:fontFamily="@string/light_font"
- android:gravity="center"
- android:textColor="#B3EEEEEE"
- android:textSize="14sp"
- android:lineSpacingExtra="10sp" />
-
-</LinearLayout>
diff --git a/res/layout/menu_card_dvr.xml b/res/layout/menu_card_dvr.xml
new file mode 100644
index 00000000..4cc178f3
--- /dev/null
+++ b/res/layout/menu_card_dvr.xml
@@ -0,0 +1,52 @@
+<?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.
+ -->
+
+<com.android.tv.menu.SimpleCardView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/card_layout_width"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:elevation="@dimen/card_elevation_normal"
+ android:focusable="true"
+ android:clickable="true">
+
+ <FrameLayout
+ 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>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/card_meta_layout_height"
+ android:paddingStart="@dimen/card_meta_padding_start"
+ android:paddingEnd="@dimen/card_meta_padding_end"
+ android:paddingTop="@dimen/card_meta_padding_top"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:fontFamily="@string/condensed_font"
+ android:textColor="@color/card_meta_text_color"
+ android:background="@color/guide_card_meta_background"
+ android:text="@string/channels_item_dvr"
+ android:textSize="12sp" />
+
+</com.android.tv.menu.SimpleCardView>
diff --git a/res/layout/menu_card_guide.xml b/res/layout/menu_card_guide.xml
index dcc80931..6b724b12 100644
--- a/res/layout/menu_card_guide.xml
+++ b/res/layout/menu_card_guide.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
-<com.android.tv.menu.GuideCardView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.tv.menu.SimpleCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/card_layout_width"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -49,4 +49,4 @@
android:text="@string/channels_item_program_guide"
android:textSize="12sp" />
-</com.android.tv.menu.GuideCardView>
+</com.android.tv.menu.SimpleCardView>
diff --git a/res/layout/onboarding_welcome_background.xml b/res/layout/onboarding_welcome_background.xml
new file mode 100644
index 00000000..784127b4
--- /dev/null
+++ b/res/layout/onboarding_welcome_background.xml
@@ -0,0 +1,39 @@
+<?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:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/cloud1"
+ android:layout_width="182dp"
+ android:layout_height="114dp"
+ android:layout_marginTop="140dp"
+ android:layout_marginStart="-47dp"
+ android:layout_gravity="start"
+ android:src="@drawable/cloud01"
+ android:contentDescription="@null" />
+ <ImageView
+ android:id="@+id/cloud2"
+ android:layout_width="120dp"
+ android:layout_height="74dp"
+ android:layout_marginTop="100dp"
+ android:layout_marginEnd="-40dp"
+ android:layout_gravity="end"
+ android:src="@drawable/cloud02"
+ android:contentDescription="@null" />
+</FrameLayout>
diff --git a/res/layout/onboarding_welcome_content.xml b/res/layout/onboarding_welcome_content.xml
new file mode 100644
index 00000000..57954df3
--- /dev/null
+++ b/res/layout/onboarding_welcome_content.xml
@@ -0,0 +1,54 @@
+<?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:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/onboarding_welcome_content_margin_top"
+ android:layout_marginBottom="@dimen/onboarding_welcome_content_margin_bottom"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/tv_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:transitionGroup="true">
+ <ImageView
+ android:layout_width="215dp"
+ android:layout_height="128dp"
+ android:layout_gravity="center"
+ android:contentDescription="@null"
+ android:src="@drawable/tv_bg" />
+ <ImageView
+ android:id="@+id/tv_content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:contentDescription="@null"
+ android:src="@drawable/tv_1a_01" />
+ </FrameLayout>
+
+ <ImageView
+ android:id="@+id/shadow"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/onboarding_welcome_shadow_height"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="@dimen/onboarding_welcome_shadow_margin_top"
+ android:src="@drawable/tv_shadow"
+ android:contentDescription="@null" />
+</LinearLayout>
diff --git a/res/layout/setup_item_divider.xml b/res/layout/onboarding_welcome_foreground.xml
index 65430f49..ab742c7d 100644
--- a/res/layout/setup_item_divider.xml
+++ b/res/layout/onboarding_welcome_foreground.xml
@@ -15,13 +15,12 @@
~ limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+<!-- The bottom should be aligned to that of tv_container -->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/arrow"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="4dp"
- android:paddingBottom="4dp">
- <View
- android:layout_width="match_parent"
- android:layout_height="0.5dp"
- android:background="@color/setup_divider" />
-</FrameLayout>
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginBottom="@dimen/onboarding_welcome_arrow_margin_bottom"
+ android:contentDescription="@null"
+ android:visibility="gone" />
diff --git a/res/layout/option_item_simple.xml b/res/layout/option_item_simple.xml
deleted file mode 100644
index 5dc6b8cf..00000000
--- a/res/layout/option_item_simple.xml
+++ /dev/null
@@ -1,33 +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.
- -->
-
-<!-- Non focusable item -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/side_panel_padding_start"
- android:paddingEnd="@dimen/side_panel_padding_end"
- android:focusable="false"
- android:background="?android:attr/selectableItemBackground" >
-
- <include layout="@layout/option_item_common"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1" />
-
-</LinearLayout>
diff --git a/res/layout/overlay_root_view.xml b/res/layout/overlay_root_view.xml
index 1048e267..1fc8647f 100644
--- a/res/layout/overlay_root_view.xml
+++ b/res/layout/overlay_root_view.xml
@@ -16,6 +16,7 @@
-->
<com.android.tv.ui.OverlayRootView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/overlay_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
@@ -36,8 +37,7 @@
<include layout="@layout/menu" />
<include layout="@layout/option_container" />
<include layout="@layout/program_guide" />
- <FrameLayout android:id="@+id/search"
+ <FrameLayout android:id="@+id/fragment_container"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
-
</com.android.tv.ui.OverlayRootView>
diff --git a/res/layout/setup_dialog.xml b/res/layout/setup_dialog.xml
deleted file mode 100644
index ce3dc22f..00000000
--- a/res/layout/setup_dialog.xml
+++ /dev/null
@@ -1,71 +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.
- -->
-
-<com.android.tv.ui.SetupView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <View
- android:id="@+id/background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/setup_background" />
- <!-- clipChildren:false is given for item animations in input_list view. -->
- <LinearLayout
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:orientation="horizontal" >
- <LinearLayout
- android:id="@+id/setup_left"
- android:layout_width="592dp"
- android:layout_height="match_parent"
- android:paddingStart="56dp"
- android:paddingEnd="32dp"
- android:paddingTop="183dp"
- android:orientation="vertical">
- <TextView
- android:id="@+id/setup_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fontFamily="@string/light_font"
- android:textColor="@color/setup_title"
- android:textSize="34sp" />
- <TextView
- android:id="@+id/setup_description"
- android:layout_marginTop="8dp"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fontFamily="@string/font"
- android:textColor="@color/setup_description"
- android:textSize="14sp" />
- </LinearLayout>
- <android.support.v17.leanback.widget.VerticalGridView
- android:id="@+id/input_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingStart="24dp"
- android:paddingEnd="40dp"
- android:paddingTop="183dp"
- android:paddingBottom="48dp"
- android:clipToPadding="false"
- android:focusable="true"
- android:focusableInTouchMode="true" />
- </LinearLayout>
-</com.android.tv.ui.SetupView>
-
diff --git a/res/layout/setup_item_action.xml b/res/layout/setup_item_action.xml
deleted file mode 100644
index c39e4960..00000000
--- a/res/layout/setup_item_action.xml
+++ /dev/null
@@ -1,42 +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.
- -->
-
-<!-- TODO: define its own resources instead of using option_item_xxx, once UI spec is defined. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/option_item_height"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:paddingTop="@dimen/option_item_common_padding_top"
- android:paddingBottom="@dimen/option_item_common_padding_bottom"
- android:gravity="center_vertical"
- android:background="@drawable/setup_item_background"
- android:focusable="true" >
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fontFamily="@string/option_item_text_font"
- android:textSize="@dimen/option_item_text_size"
- android:textColor="@color/option_item_text_color"
- android:singleLine="true"
- android:focusable="false" />
-
-</LinearLayout>
diff --git a/res/layout/setup_item_input.xml b/res/layout/setup_item_input.xml
deleted file mode 100644
index 1bc7ccd4..00000000
--- a/res/layout/setup_item_input.xml
+++ /dev/null
@@ -1,51 +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.
- -->
-
-<!-- TODO: define its own resources instead of using option_item_xxx, once UI spec is defined. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/option_item_height"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:paddingTop="@dimen/option_item_common_padding_top"
- android:paddingBottom="@dimen/option_item_common_padding_bottom"
- android:gravity="center_vertical"
- android:background="@drawable/setup_item_background"
- android:focusable="true" >
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fontFamily="@string/option_item_text_font"
- android:textSize="@dimen/option_item_text_size"
- android:textColor="@color/option_item_text_color"
- android:singleLine="true"
- android:focusable="false" />
- <TextView
- android:id="@+id/description"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/option_item_text_margin_top"
- 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:focusable="false" />
-
-</LinearLayout>
diff --git a/res/values-af/arrays.xml b/res/values-af/arrays.xml
index 4a78c005..1f94e3ce 100644
--- a/res/values-af/arrays.xml
+++ b/res/values-af/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Beste"</item>
<item msgid="8215762047341133299">"Tegnologie/wetenskap"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Regstreekse Kanale"</item>
+ <item msgid="7307688057853449735">"\'n Eenvoudige manier om inhoud te ontdek"</item>
+ <item msgid="7566838222783641942">"Laai programme af; kry meer kanale"</item>
+ <item msgid="8646630833216197238">"Pasmaak jou kanaallys"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Kyk na inhoud uit jou programme nes jy kanale op TV kyk."</item>
+ <item msgid="1855708984677953238">"Blaai deur inhoud uit jou programme met \'n bekende gids en vriendelike koppelvlak \nnet soos kanale op TV."</item>
+ <item msgid="3420760668363283731">"Voeg meer kanale by deur programme te installeer wat regstreekse kanale bied. \nVind versoenbare programme in Google Play Winkel met die skakel op die TV-kieslys."</item>
+ <item msgid="8974157841656828507">"Stel die kanaalbronne wat jy nuut geïnstalleer het, op om jou kanaallys te pasmaak. \nBegin deur die kanaalbronne op die Instellings-kieslys te kies."</item>
+ </string-array>
</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 443d2459..64f3cf4a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanaalopstelling"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ouerkontroles"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Meer oor"</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>
@@ -84,21 +83,15 @@
<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">"Groepeer volgens"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanaalopstelling"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Hierdie program word geblokkeer"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanaalbronne"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nuwe kanale beskikbaar"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Pasmaak kanaallys"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Kies kanale vir jou programgids"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nie opgestel nie"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Kon nie die stelselwye voorkeure vir onderskrifte begin nie."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanaal bygevoeg"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanale bygevoeg"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanale is bygevoeg</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Voer nuwe PIN in"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Bevestig jou PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Voer jou huidige PIN in"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Jy het 5 keer die verkeerde PIN ingevoer.\nProbeer weer oor <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekonde."</item>
- <item quantity="other" msgid="8829550842387756054">"Jy het 5 keer die verkeerde PIN ingevoer.\nProbeer weer oor <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekondes."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Jy het 5 keer \'n verkeerde PIN ingevoer.\nProbeer oor <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekondes weer.</item>
+ <item quantity="one">Jy het 5 keer \'n verkeerde PIN ingevoer.\nProbeer oor <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekonde weer.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Meer oor"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Oopbronlisensies"</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_menu_licenses" msgid="1257646083838406103">"Oopbronlisensies"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Oopbronlisensies"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Weergawe"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Weergawe"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Ontwikkelaaropsies"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Aktiveer USB-TV-ontvanger"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Jou TV moet AC3-deurgang steun om USB-TV-ontvanger se klank te hoor."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Titelloos"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanaal is geblokkeer"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanaalbronne"</string>
- <string name="setup_description" msgid="8728423605912915099">"Stel regstreekse kanale op uit die beskikbare bronne. Dit kan verskeie minute duur, afhangend van die kanaalbron."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Klaar"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanaal is beskikbaar"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanale is beskikbaar"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nuut"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Bronne"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanale</item>
+ <item quantity="one">%1$d kanaal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Geen kanale is beskikbaar nie"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nuut"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nie opgestel nie"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Kry nog bronne"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Blaai deur programme wat regstreekse kanale bied"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nuwe kanaalbronne is beskikbaar"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Nuwe kanaalbronne kan kanale bied.\nStel hulle nou op of doen dit later in die kanaalbronne-instelling."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Stel nou op"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, het dit"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Druk KIES"</b>" om na die TV-kieslys te gaan."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"TERUG-sleutel is vir gekoppelde toestelle. Druk TUIS-knoppie om uit te gaan."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Regstreekse kanale word nie op hierdie toestel met Android Lollipop gesteun nie."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Regstreekse kanale het toestemming nodig om die TV-lysinskrywings te lees."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Stel jou bronne op"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Regstreekse kanale kombineer die ervaring van tradisionele TV-kanale met stroomkanale wat deur programme verskaf word. \n\nBegin deur die kanaalbronne op te stel wat reeds geïnstalleer is. Of blaai deur die Google Play Winkel vir meer programme wat regstreekse kanale bied."</string>
</resources>
diff --git a/res/values-am/arrays.xml b/res/values-am/arrays.xml
index 7764b210..bed9cdf7 100644
--- a/res/values-am/arrays.xml
+++ b/res/values-am/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ፕሪሚየር"</item>
<item msgid="8215762047341133299">"ቴክኖሎጂ/ሳይንስ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"የቀጥታ ስርጭት ሰርጦች"</item>
+ <item msgid="7307688057853449735">"ይዘት የሚገኝበት ቀላል መንገድ"</item>
+ <item msgid="7566838222783641942">"መተግበሪያዎችን ያውርዱ፣ ተጨማሪ ሰርጦችን ያግኙ"</item>
+ <item msgid="8646630833216197238">"የሰርጥ ዝርዝርዎን ያብጁት"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"እንደ ሰርጦችን በቴሌቪዥን ላይ መመልከት ያሉ ከእርስዎ መተግበሪያዎች ላይ ይዘትን ይመልከቱ።"</item>
+ <item msgid="1855708984677953238">"በሚታወቅ መመሪያ እና ተስማሚ በሆነ በይነገጽ ከእርስዎ መተግበሪያዎች የመጣ ይዘትን ያስሱ፣ \nልክ በቴሌቪዥን ላይ እንዳሉ ሰርጦች።"</item>
+ <item msgid="3420760668363283731">"የቀጥታ ስርጭት ሰርጦችን የሚያቀርቡ መተግበሪያዎችን በመጫን ተጨማሪ ሰርጦችን ያክሉ። \nበቴሌቪዥን ማሌው ውስጥ ያለውን አገናኝ በመጠቀም በGoogle Play መደብር ውስጥ ተኳዃኝ የሆኑ መተግበሪያዎችን ያግኙ።"</item>
+ <item msgid="8974157841656828507">"የእርስዎን የሰርጥ ዝርዝር ለማበጀት አዲስ የተጫኑ የሰርጥ ምንጮችን ያዋቅሩ። \nለመጀመር በቅንብሮች ምናሌው ውስጥ የሰርጥ ምንጮችን ይምረጡ።"</item>
+ </string-array>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index e25a1df4..00077915 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"የሰርጥ ቅንብር"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"የወላጅ መቆጣጠሪያዎች"</string>
- <string name="options_item_about" msgid="3023532413252052050">"ስለ"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"ኤችዲ"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"ኤስዲ"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"ሰብስብ በ"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"የሰርጥ ቅንብር"</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="channel_source_item_setup" msgid="1330441915487807542">"የሰርጥ ምንጮች"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"አዲስ ሰርጦች ይገኛሉ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"የሰርጥ ዝርዝር አብጅ"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"ለፕሮግራሙ መመሪያዎ ሰርጦችን ይምረጡ"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"አልተዋቀረም"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ሰርጥ ታክሏል"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ሰርጦች ታክለዋል"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"የተሳሳተ ፒን 5 ጊዜ ገብቷል።\nበ<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ሰከንድ ውስጥ እንደገና ይሞክሩ።"</item>
- <item quantity="other" msgid="8829550842387756054">"የተሳሳተ ፒን 5 ጊዜ ገብቷል።\nበ<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"ስለ"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"የክፍት ምንጭ ፍቃዶች"</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="about_menu_version" msgid="6303769835664868129">"ስሪት"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ስሪት"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"የገንቢ አማራጮች"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"የዩኤስቢ ቴሌቪዥን መቃኛን አንቃ"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"የዩኤስቢ ቴሌቪዥን መቃኛ ድምጽ ለመስማት የእርስዎ ቴሌቪዥን የAC3 ማሳለፊያን መደገፍ አለበት።"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ርእስ የለውም"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ሰርጥ ታግዷል"</string>
<string name="episode_format" msgid="4881195874563241096">"ምዕ <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>፦ ክፍል <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"የሰርጥ ምንጮች"</string>
- <string name="setup_description" msgid="8728423605912915099">"ከሚገኙ ምንጮች የቀጥታ ሰርጦችን ያዘጋጁ። እንደ የሰርጡ ምንጭ የሚወሰን ሆኖ የተወሰኑ ደቂቃዎች ሊወስድ ይችላል።"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"ተከናውኗል"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ሰርጥ ይገኛል"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ሰርጦች ይገኛል"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"ተጨማሪ ምንጮችን ያግኙ"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"የቀጥታ ስርጭት ሰርጦችን የሚያቀርቡ መተግበሪያዎችን ያስሱ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK ቁልፍ ለተገናኙ መሳሪያዎች። ለመውጣት HOME አዝራርን ይጫኑ።"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"ቀጥተኛ ሰርጦች እዚህ መሣሪያ ላይ በAndroid Lollipop አይደገፉም።"</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>
</resources>
diff --git a/res/values-ar/arrays.xml b/res/values-ar/arrays.xml
index 6b956da4..30874771 100644
--- a/res/values-ar/arrays.xml
+++ b/res/values-ar/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"العرض الأول"</item>
<item msgid="8215762047341133299">"تكنولوجيا/علوم"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"قنوات البث التلفزيوني المباشر"</item>
+ <item msgid="7307688057853449735">"وسيلة بسيطة لاستكشاف المحتوى"</item>
+ <item msgid="7566838222783641942">"تنزيل تطبيقات للحصول على مزيد من القنوات"</item>
+ <item msgid="8646630833216197238">"تخصيص قائمة قنواتك"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"‏يمكنك مشاهدة المحتوى من تطبيقاتك مثلما تشاهد القنوات عبر جهاز Android TV."</item>
+ <item msgid="1855708984677953238">"‏يمكنك تصفُّح المحتوى من تطبيقاتك من خلال دليل بسيط وواجهة يَسهُل التعامل معها، \nمثلما تتصفَّح القنوات على جهاز Android TV."</item>
+ <item msgid="3420760668363283731">"‏يمكنك إضافة المزيد من القنوات عن طريق تثبيت تطبيقات توفِّر قنوات بث تلفزيوني مباشر. \nيمكنك البحث عن التطبيقات المتوافقة في متجر Google Play من خلال استخدام الرابط داخل قائمة جهاز Android TV."</item>
+ <item msgid="8974157841656828507">"يمكنك إعداد مصادر القنوات التي تم تثبيتها مؤخرًا لتخصيص قائمة قنواتك. \nاختر مصادر القنوات داخل قائمة الإعدادات للبدء."</item>
+ </string-array>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 0b607877..5884cc5c 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"إعداد القناة"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"عناصر التحكم الأبوي"</string>
- <string name="options_item_about" msgid="3023532413252052050">"حول"</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>
@@ -84,21 +83,19 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"دقة عالية"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"دقة قياسية"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"تجميع بحسب"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"إعداد القناة"</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="channel_source_item_setup" msgid="1330441915487807542">"مصادر القنوات"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"تتوفر قنوات جديدة"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"تخصيص قائمة قنوات"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"اختر القنوات الخاصة بدليل البرامج"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"لم يتم الإعداد"</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">
- <item quantity="one" msgid="6074059986849579215">"‏تمت إضافة %1$d من القنوات"</item>
- <item quantity="other" msgid="1078861616751739285">"‏تمت إضافة %1$d من القنوات"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="zero">‏تمت إضافة %1$d قناة</item>
+ <item quantity="two">‏تمت إضافة قناتين (%1$d)</item>
+ <item quantity="few">‏تمت إضافة %1$d قنوات</item>
+ <item quantity="many">‏تمت إضافة %1$d قناة</item>
+ <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>
@@ -136,16 +133,25 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"لقد أدخلت رقم تعريف شخصي خاطئًا 5 مرات.\nأعد المحاولة بعد <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ثانية."</item>
- <item quantity="other" msgid="8829550842387756054">"لقد أدخلت رقم تعريف شخصي خاطئًا 5 مرات.\nأعد المحاولة بعد <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> من الثواني."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="zero">لقد أدخلت رقم التعريف الشخصي بشكل خاطئ 5 مرات.\nأعد المحاولة خلال <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ثانية.</item>
+ <item quantity="two">لقد أدخلت رقم التعريف الشخصي بشكل خاطئ 5 مرات.\nأعد المحاولة خلال ثانيتين (<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>).</item>
+ <item quantity="few">لقد أدخلت رقم التعريف الشخصي بشكل خاطئ 5 مرات.\nأعد المحاولة خلال <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ثوانٍ.</item>
+ <item quantity="many">لقد أدخلت رقم التعريف الشخصي بشكل خاطئ 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>
+ <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_about" msgid="4572960435017168299">"حول"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"تراخيص البرامج المفتوحة المصدر"</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="about_menu_version" msgid="6303769835664868129">"الإصدار"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"الإصدار"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"خيارات المطورين"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"‏تمكين موالف التلفزيون عبر USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"‏لسماع الصوت الصادر عن موالف التلفزيون عبر USB، يجب أن يكون تلفزيونك متوافقًا مع إمكانية العبور AC3."</string>
@@ -166,15 +172,25 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"بلا عنوان"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"تم حظر القناة"</string>
<string name="episode_format" msgid="4881195874563241096">"الموسم <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: الحلقة <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"مصادر القنوات"</string>
- <string name="setup_description" msgid="8728423605912915099">"يمكنك إعداد قنوات مباشرة من المصادر المتاحة. وقد يستغرق هذا بضع دقائق حسب مصدر القنوات."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"تمّ"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"‏عدد القنوات المتوفرة: %1$d"</item>
- <item quantity="other" msgid="2386588423841837714">"‏عدد القنوات المتوفرة: %1$d"</item>
- </plurals>
+ <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="zero">‏%1$d قناة</item>
+ <item quantity="two">‏قناتان (%1$d)</item>
+ <item quantity="few">‏%1$d قنوات</item>
+ <item quantity="many">‏%1$d قناة</item>
+ <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_play_store_action_title" msgid="859347291072224673">"الحصول على مزيد من المصادر"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"تصفح التطبيقات التي تقدم قنوات مباشرة"</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>" للوصول إلى قائمة TV."</string>
@@ -191,4 +207,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"زر الرجوع مخصص للجهاز المتصل. يمكنك الضغط على زر الصفحة الرئيسية للخروج."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"‏القنوات المباشرة غير متوافقة على هذا الجهاز مع Android Lollipop."</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>
</resources>
diff --git a/res/values-az-rAZ/arrays.xml b/res/values-az-rAZ/arrays.xml
new file mode 100644
index 00000000..7f891617
--- /dev/null
+++ b/res/values-az-rAZ/arrays.xml
@@ -0,0 +1,57 @@
+<?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-array name="display_mode_labels">
+ <item msgid="2259828487212953611">"Normal"</item>
+ <item msgid="2533030282864800794">"Tam"</item>
+ <item msgid="8568284598210500589">"Zoom"</item>
+ </string-array>
+ <string-array name="genre_labels">
+ <item msgid="3241959001790384341">"Bütün kanallar"</item>
+ <item msgid="928298872841713530">"Ailə/Uşaqlar"</item>
+ <item msgid="2751606947569857164">"İdman"</item>
+ <item msgid="7345749789651321496">"Şoppinq"</item>
+ <item msgid="167201149441442173">"Filmlər"</item>
+ <item msgid="525966731464264290">"Komediya"</item>
+ <item msgid="6096710741527327836">"Səyahət"</item>
+ <item msgid="2851882187117833883">"Dram"</item>
+ <item msgid="78492781188719038">"Təhsil"</item>
+ <item msgid="7221999662426308394">"Heyvan/Vəhşi təbiət"</item>
+ <item msgid="375300513250925001">"Xəbərlər"</item>
+ <item msgid="7746320336582330410">"Oyun"</item>
+ <item msgid="1255741860568329178">"İncəsənət"</item>
+ <item msgid="7603949681065702867">"Əyləncə"</item>
+ <item msgid="4453821994746804366">"Həyat tərzi"</item>
+ <item msgid="3488534597567932843">"Musiqi"</item>
+ <item msgid="7452153120614274095">"Premyera"</item>
+ <item msgid="8215762047341133299">"Texnologiya/Elm"</item>
+ </string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canlı Kanallar"</item>
+ <item msgid="7307688057853449735">"Məzmun kəşfi üçün sadə yol"</item>
+ <item msgid="7566838222783641942">"Tətbiqləri endirin, daha çox kanal əldə edin"</item>
+ <item msgid="8646630833216197238">"Kanallarınızın sıralamasını fərdiləşdirin"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV kanallarını izlədiyiniz kimi tətbiqlərinizdən məzmuna baxın."</item>
+ <item msgid="1855708984677953238">"Oxşar təlimat və səmimi interfeysi olan tətbiqlərinizdən məzmun axtarışı edin, \nelə TV kanallarındakı kimi."</item>
+ <item msgid="3420760668363283731">"Canlı kanallar təklif edən tətbiqləri yükləyərək daha çox kanal əlavə edin. \n Və ya TV menyusu olan linki istifadə edərək Google Play Store\'da müvafiq tətbiqi tapın."</item>
+ <item msgid="8974157841656828507">"Kanal siyahısını fərdiləşdirmək üçün yeni quraşdırılmış kanal mənbələrini ayarlayın. \n Başlamaq üçün Ayarlar menyusundan kanal mənbələrini seçin."</item>
+ </string-array>
+</resources>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..46b1d9c1
--- /dev/null
+++ b/res/values-az-rAZ/strings.xml
@@ -0,0 +1,202 @@
+<?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_no_app_link" msgid="1884830234777824408">"Əlçatan link yoxdur"</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_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="side_panel_title_developer" msgid="7287627759979090359">"Tərtibatçı seçimləri"</string>
+ <string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV kökləyicisini aktiv edin"</string>
+ <string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV kökləyicisindən səs eşitmək üçün, TV-niz AC3 ötürüçüsünü dəstəkləməlidir."</string>
+ <string name="developer_menu_ac3_support" msgid="8542930057443915670">"AC3 audio tutumu"</string>
+ <string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"TV-niz AC3 ötürücüsünü dəstəkləyir."</string>
+ <string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"TV-niz AC3 ötürücüsünü dəstəkləmir."</string>
+ <string name="about_menu_improve" msgid="3712578027009311401">"Canlı Kanalları inkişaf etdirməyə kömək edin"</string>
+ <string name="about_menu_improve_summary" msgid="7548489011760588571">"Anonim istifadə və diaqnostika datasını Google ilə paylaşın, beləcə Canlı Kanalları daha yaxşı edə və qırılma və donma problemlərinin qarşısını ala bilərik."</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="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="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</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_play_store_action_title" msgid="859347291072224673">"Əlavə mənbə əldə edin"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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_weak_signal" msgid="3935601939459171709">"Zəif video bağlantı ilə əlaqədar əlçatmazdır"</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_not_supported_device" msgid="4469404625040284722">"Canlı Kanallar Android Lollipop ilə bu cihazda dəstəklənmir"</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>
+</resources>
diff --git a/res/values-bg/arrays.xml b/res/values-bg/arrays.xml
index 7fef2d45..66313ab6 100644
--- a/res/values-bg/arrays.xml
+++ b/res/values-bg/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Премиери"</item>
<item msgid="8215762047341133299">"Наука и технологии"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Канали на живо"</item>
+ <item msgid="7307688057853449735">"Лесен начин за намиране на съдържание"</item>
+ <item msgid="7566838222783641942">"Изтеглете приложения, за да добавите още канали"</item>
+ <item msgid="8646630833216197238">"Персонализирайте подредбата на каналите си"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Гледайте съдържание от приложенията си, както гледате каналите на телевизора."</item>
+ <item msgid="1855708984677953238">"Разглеждайте съдържание от приложенията си с познат справочник и удобен интерфейс, \nточно както каналите на телевизора."</item>
+ <item msgid="3420760668363283731">"Добавете още канали, като инсталирате приложения, предлагащи канали на живо. \nНамерете съвместими приложения в Google Play Магазин, като използвате връзката в менюто на телевизора."</item>
+ <item msgid="8974157841656828507">"Настройте новоинсталираните си източници на канали, за да персонализирате съответния си списък. \nЗа да започнете, изберете източници от менюто „Настройки“."</item>
+ </string-array>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index adf161c8..95b4f488 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Канали: Настр."</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Родит. контроли"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Информация"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Висока детайлност"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Стандартна детайлност"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Групиране по"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Канали: Настройка"</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="channel_source_item_setup" msgid="1330441915487807542">"Канали: Източници"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Налице са нови канали"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Сп. с канали: Персон."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Изберете канали за справ. си с програми"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Не е настроено"</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">
- <item quantity="one" msgid="6074059986849579215">"Добавен е %1$d канал"</item>
- <item quantity="other" msgid="1078861616751739285">"Добавени са %1$d канала"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Въведохте грешен ПИН код 5 пъти.\nОпитайте отново след <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунда."</item>
- <item quantity="other" msgid="8829550842387756054">"Въведохте грешен ПИН код 5 пъти.\nОпитайте отново след <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунди."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Информация"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Лицензи за отворен код"</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="about_menu_version" msgid="6303769835664868129">"Версия"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Версия"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Опции за програмисти"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Активиране на телевизионния USB тунер"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"За да чувате звук от телевизионния USB тунер, телевизорът ви трябва да поддържа формата AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Без заглавие"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Каналът е блокиран"</string>
<string name="episode_format" msgid="4881195874563241096">"Сезон <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Еп. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> ˜– „<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>“"</string>
- <string name="setup_title" msgid="7268875010986705651">"Източници на канали"</string>
- <string name="setup_description" msgid="8728423605912915099">"Настройване на канали на живо от наличните източници. Това може да отнеме няколко минути в зависимост от източника."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Готово"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Налице е %1$d канал"</item>
- <item quantity="other" msgid="2386588423841837714">"Налице са %1$d канала"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Добавяне на още източници"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Разгледайте приложенията, предлагащи канали на живо"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Клавишът за връщане назад е за свързаното устройство. За изход натиснете бутона „Начало“."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Приложението Live TV не се поддържа на това устройство с Android Lollipop."</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>
</resources>
diff --git a/res/values-bn-rBD/arrays.xml b/res/values-bn-rBD/arrays.xml
index c2e47923..76a0792a 100644
--- a/res/values-bn-rBD/arrays.xml
+++ b/res/values-bn-rBD/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"প্রিমিয়ার"</item>
<item msgid="8215762047341133299">"প্রযুক্তি/বিজ্ঞান"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"লাইভ চ্যানেলগুলি"</item>
+ <item msgid="7307688057853449735">"সামগ্রী আবিষ্কার করার একটি সহজ উপায়"</item>
+ <item msgid="7566838222783641942">"অ্যাপ্লিকেশানগুলি ডাউনলোড করুন, আর আরো বেশি চ্যানেল পান"</item>
+ <item msgid="8646630833216197238">"আপনার চ্যানেল লাইন-আপ কাস্টমাইজ করুন"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"টিভিতে চ্যানেল দেখার মত আপনার অ্যাপ্লিকেশানগুলি থেকে সামগ্রী দেখুন৷"</item>
+ <item msgid="1855708984677953238">"টিভিতে চ্যানেলগুলি মত কোনো \nপরিচিত গাইড এবং সহজ ইন্টারফেসের মাধ্যমে আপনার অ্যাপ্লিকেশানগুলি থেকে সামগ্রী ব্রাউজ করুন৷"</item>
+ <item msgid="3420760668363283731">"লাইভ চ্যনেলগুলি অফার করে এমন অ্যাপ্লিকেশানগুলিকে ইনস্টল করার মাধ্যেমে আরো চ্যানেল যোগ করুন৷ \n টিভি মেনুর মধ্যে থাকা লিঙ্কটি ব্যবহার করে Google Play স্টোরে আরো উপযুক্ত অ্যাপ্লিকেশানগুলি খুঁজুন৷"</item>
+ <item msgid="8974157841656828507">"আপনার চ্যানেল তালিকা কাস্টমাইজ করতে আপনার নতুন ইনস্টল করা চ্যানেল উৎসগুলি সেট আপ করুন৷ \nশুরু করতে সেটিংস মেনুতে থাকা চ্যানেল উৎসগুলি চয়ন করুন৷"</item>
+ </string-array>
</resources>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index f533c9f9..a7708c15 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"চ্যানেল সেটআপ"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"অভিভাবকীয় নিয়ন্ত্রণগুলি"</string>
- <string name="options_item_about" msgid="3023532413252052050">"সম্পর্কে"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"চ্যানেল সেটআপ"</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="channel_source_item_setup" msgid="1330441915487807542">"চ্যানেলের উৎসগুলি"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"নতুন চ্যানেলগুলি উপলব্ধ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"চ্যানেল তালিকা কাস্টমাইজ করুন"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"আপনার প্রোগ্রাম গাইডের জন্য চ্যানেলগুলি নির্বাচন করুন"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"সেট আপ করা নেই"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$dটি চ্যানেল যোগ করা হয়েছে"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$dটি চ্যানেল যোগ করা হয়েছে"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"আপনি ৫ বার ভুল পিন লিখেছেন।\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</item>
- <item quantity="other" msgid="8829550842387756054">"আপনি ৫ বার ভুল পিন লিখেছেন।\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"সম্পর্কে"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"মুক্ত উৎস লাইসেন্সগুলি"</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="about_menu_version" msgid="6303769835664868129">"সংস্করণ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"সংস্করণ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"বিকাশকারীর বিকল্পগুলি"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB টিভি টিউনার সক্ষম করুন"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB টিভি টিউনারের শব্দ শুনতে, আপনার টিভিকে AC3 পাসথ্রু সমর্থন করতে হবে৷"</string>
@@ -153,7 +151,7 @@
<string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"আপনার টিভি AC3 পাসথ্রু সমর্থন করে৷"</string>
<string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"আপনার টিভি AC3 পাসথ্রু সমর্থন করে না৷"</string>
<string name="about_menu_improve" msgid="3712578027009311401">"লাইভ চ্যানেলগুলি উন্নত করতে সহায়তা করুন"</string>
- <string name="about_menu_improve_summary" msgid="7548489011760588571">"Google এর সাথে নামবিহীন ব্যবহার এবং ডায়াগনস্টিক ডেটা ভাগ করুন যাতে করে আমরা লাইভ চ্যানেলগুলিকে আরো উন্নত করতে এবং ক্র্যাশ ও ফ্রিজ হয়ে যাওয়ার মতো সমস্যাগুলিকে আটকাতে পারি৷"</string>
+ <string name="about_menu_improve_summary" msgid="7548489011760588571">"Google এর সাথে নামবিহীন ব্যবহার এবং ডায়াগনস্টিক ডেটা শেয়ার করুন যাতে করে আমরা লাইভ চ্যানেলগুলিকে আরো উন্নত করতে এবং ক্র্যাশ ও ফ্রিজ হয়ে যাওয়ার মতো সমস্যাগুলিকে আটকাতে পারি৷"</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>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"কোনো শিরোনাম নেই"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"চ্যানেল অবরুদ্ধ করা হয়েছে"</string>
<string name="episode_format" msgid="4881195874563241096">"সে<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: এপিঃ <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"চ্যানেলের উৎসগুলি"</string>
- <string name="setup_description" msgid="8728423605912915099">"উপলব্ধ উৎসগুলি থেকে লাইভ চ্যানেলগুলি সেট আপ করুন। আপনার চ্যানেলের উৎসগুলির উপর নির্ভর করে এতে কয়েক মিনিট সময় লাগতে পারে৷"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"সম্পন্ন"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$dটি চ্যানেল উপলব্ধ"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$dটি চ্যানেল উপলব্ধ"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"আরো উৎস পান"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"লাইভ চ্যানেলগুলি অফার করে এমন অ্যাপগুলি ব্রাউজ করুন"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"\'ব্যাক\' কীটি সংযুক্ত ডিভাইসের ক্ষেত্রে ব্যবহারের জন্য৷ প্রস্থান করতে হোম বোতামটি টিপুন৷"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"এই ডিভাইসটিতে Android Lollipop এর সাথে লাইভ চ্যানেলগুলি সমর্থিত নয়।"</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>
</resources>
diff --git a/res/values-ca/arrays.xml b/res/values-ca/arrays.xml
index 9b4c3e0e..d00927f6 100644
--- a/res/values-ca/arrays.xml
+++ b/res/values-ca/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Principal"</item>
<item msgid="8215762047341133299">"Ciència i tecnologia"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"TV en directe"</item>
+ <item msgid="7307688057853449735">"Una manera senzilla de descobrir contingut"</item>
+ <item msgid="7566838222783641942">"Baixa aplicacions i obtén més canals"</item>
+ <item msgid="8646630833216197238">"Personalitza la teva llista de canals"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Mira contingut de les teves aplicacions de la mateixa manera que mires els canals en un televisor."</item>
+ <item msgid="1855708984677953238">"Navega pel contingut de les teves aplicacions mitjançant una guia coneguda i una interfície senzilla, \nigual que ho fas amb els canals en un televisor."</item>
+ <item msgid="3420760668363283731">"Instal·la aplicacions que ofereixin TV en directe per afegir més canals. \nCerca aplicacions compatibles a Google Play Store utilitzant l\'enllaç que hi ha al menú de TV."</item>
+ <item msgid="8974157841656828507">"Configura les fonts de canals que acabes d\'instal·lar per personalitzar la llista de canals. \nPer començar, tria les fonts de canals al menú Configuració."</item>
+ </string-array>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 54c158f2..fc640d32 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Configur. canal"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Control dels pares"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informació"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Obtén 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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Alta definició"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Definició estàndard"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupa per"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Configurac. canals"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Aquest programa està bloquejat"</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="channel_source_item_setup" msgid="1330441915487807542">"Fonts de canals"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nous canals disponibles"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personalitza la llista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Tria canals per a la guia de programes."</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"No s\'ha configurat."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"L\'entrada no és compatible amb l\'exploració automàtica."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"No es pot iniciar l\'exploració automàtica de: <xliff:g id="TV_INPUT">%s</xliff:g>."</string>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"No es poden iniciar les preferències de subtítols del sistema."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"S\'ha afegit %1$d canal."</item>
- <item quantity="other" msgid="1078861616751739285">"S\'han afegit %1$d canals."</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">S\'han afegit %1$d canals</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introdueix el PIN nou"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmació del PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Introducció del PIN actual"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Has introduït un PIN incorrecte 5 vegades.\nTorna-ho a provar d\'aquí a <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segon."</item>
- <item quantity="other" msgid="8829550842387756054">"Has introduït un PIN incorrecte 5 vegades.\nTorna-ho a provar d\'aquí a <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segons."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Has introduït un PIN incorrecte cinc vegades.\nTorna-ho a provar d\'aquí a <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segons.</item>
+ <item quantity="one">Has introduït un PIN incorrecte cinc vegades.\nTorna-ho a provar d\'aquí a <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segon.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informació"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Llicències de programari lliure"</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_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="about_menu_version" msgid="6303769835664868129">"Versió"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versió"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opcions per a desenvolupadors"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Activa el sintonitzador de canals USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Per sentir el so del sintonitzador de canals USB, el teu televisor ha d\'admetre la connexió AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sense títol"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canal bloquejat"</string>
<string name="episode_format" msgid="4881195874563241096">"Temporada <xliff:g id="SEASON_NUMBER">%1$d</xliff:g> Capítol <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fonts de canals"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configura canals en directe a partir de les fonts disponibles. Això pot tardar uns quants minuts en funció de la font del canal."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Fet"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Hi ha %1$d canal disponible"</item>
- <item quantity="other" msgid="2386588423841837714">"Hi ha %1$d canals disponibles"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Noves"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Fonts"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d canals</item>
+ <item quantity="one">%1$d canal</item>
+ </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_play_store_action_title" msgid="859347291072224673">"Obtén més fonts"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configura ara"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"D\'acord"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Prem SELECCIONA"</b>" per accedir al menú de TV."</string>
@@ -190,5 +194,7 @@
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"El vídeo ha deixat d\'estar disponible de manera inesperada"</string>
<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_not_supported_device" msgid="4469404625040284722">"Canals en directe no s\'admet en aquest dispositiu amb Android Lollipop."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canals en directe necessita permís per consultar la llista de canals del televisor."</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>
</resources>
diff --git a/res/values-cs/arrays.xml b/res/values-cs/arrays.xml
index 6ac1a427..c116f645 100644
--- a/res/values-cs/arrays.xml
+++ b/res/values-cs/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Věda a technika"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Televize online"</item>
+ <item msgid="7307688057853449735">"Jednoduchý způsob vyhledávání obsahu"</item>
+ <item msgid="7566838222783641942">"Stažením aplikací získáte další kanály"</item>
+ <item msgid="8646630833216197238">"Přizpůsobte si seznam kanálů"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Sledujte obsah z aplikací stejně jako televizní kanály."</item>
+ <item msgid="1855708984677953238">"Obsah z aplikací můžete procházet v jednoduchém a uživatelsky přívětivém průvodci, \nstejně jako televizní kanály."</item>
+ <item msgid="3420760668363283731">"Další kanály přidáte nainstalováním aplikací, které nabízejí televizi online. \nKompatibilní aplikace naleznete v Obchodu Google Play pomocí odkazu v nabídce televize."</item>
+ <item msgid="8974157841656828507">"Nastavením nově nainstalovaných zdrojů kanálů si seznam kanálů můžete přizpůsobit. \nZačněte tím, že v nabídce Nastavení zvolíte Zdroje kanálů."</item>
+ </string-array>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 4eb88d7a..d9daf93b 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -39,9 +39,8 @@
<string name="options_item_pip_on" msgid="4647247480009077381">"Zapnuto"</string>
<string name="options_item_pip_off" msgid="8799500161592387451">"Vypnuto"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Vícekanál. zvuk"</string>
- <string name="options_item_channel_sources" msgid="2217574947817750560">"Nastavení kanálu"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Rodičovská ochrana"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informace"</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>
@@ -84,21 +83,17 @@
<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">"Seskupit podle"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Nastavení kanálu"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Tento program je blokován."</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="channel_source_item_setup" msgid="1330441915487807542">"Zdroje kanálů"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Jsou k dispozici nové kanály"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Upravit seznam kanálů"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Vyberte kanály pro programového průvodce"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Není nastaveno"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Celosystémové nastavení titulků nelze spustit."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Byl přidán %1$d kanál"</item>
- <item quantity="other" msgid="1078861616751739285">"Přidané kanály: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="few">Byly přidány %1$d kanály</item>
+ <item quantity="many">Bylo přidáno %1$d kanálu</item>
+ <item quantity="other">Bylo přidáno %1$d kanálů</item>
+ <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>
@@ -136,16 +131,23 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Zadejte nový PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Potvzení kódu PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Zadání aktuálního kódu PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Zadali jste nesprávný kód PIN pětkrát.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundu."</item>
- <item quantity="other" msgid="8829550842387756054">"Zadali jste nesprávný kód PIN pětkrát.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="few">Pětkrát jste zadali nesprávný kód PIN.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="many">Pětkrát jste zadali nesprávný kód PIN.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="other">Pětkrát jste zadali nesprávný kód PIN.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekund.</item>
+ <item quantity="one">Pětkrát jste zadali nesprávný kód PIN.\nZkuste to znovu za <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekundu.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informace"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licence open source"</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_menu_licenses" msgid="1257646083838406103">"Licence open source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licence open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Verze"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Verze"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Možnosti pro vývojáře"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Aktivovat televizní tuner USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Aby televizní tuner USB mohl přehrávat zvuk, vaše televize musí podporovat formát AC3."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Bez názvu"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanál byl zablokován"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Zdroje kanálů"</string>
- <string name="setup_description" msgid="8728423605912915099">"Nastavte aktivní kanály z dostupných zdrojů. V závislosti na zdroji kanálu to může trvat několik minut."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Hotovo"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Dostupné kanály: %1$d"</item>
- <item quantity="other" msgid="2386588423841837714">"Dostupné kanály: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nové"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Zdroje"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="few">%1$d kanály</item>
+ <item quantity="many">%1$d kanálu</item>
+ <item quantity="other">%1$d kanálů</item>
+ <item quantity="one">%1$d kanál</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nejsou k dispozici žádné kanály"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nový"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Není nastaveno"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Stáhnout další zdroje"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Procházejte aplikace, které nabízejí televizi online"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"K dispozici jsou nové zdroje kanálů"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"K dispozici jsou nové zdroje kanálů s dalšími kanály.\nMůžete je nastavit hned nebo později v nastavení zdrojů kanálů."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Nastavit"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, rozumím"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307">"Chcete-li získat přístup k nabídce TV, "<b>"stiskněte SELECT"</b>"."</string>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Tlačítko Zpět je určeno pro připojené zařízení. Ukončení provedete pomocí tlačítka Domů."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"V tomto zařízení se systémem Android Lollipop nejsou aktivní kanály podporovány."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Aktivní kanály potřebují oprávnění ke čtení televizních programů."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Nastavte zdroje"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Televize online spojuje klasické televizní kanály se streamovanými kanály z aplikací. \n\nChcete-li začít, nastavte zdroje kanálů, které již jsou nainstalovány. Případně můžete v Obchodu Google Play vyhledat další aplikace, které nabízí televizi online."</string>
</resources>
diff --git a/res/values-da/arrays.xml b/res/values-da/arrays.xml
index cd5bf655..9e0d84c6 100644
--- a/res/values-da/arrays.xml
+++ b/res/values-da/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiere"</item>
<item msgid="8215762047341133299">"Teknik/videnskab"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Tv-kanaler"</item>
+ <item msgid="7307688057853449735">"En enkel måde at finde indhold på"</item>
+ <item msgid="7566838222783641942">"Download apps, og få flere kanaler"</item>
+ <item msgid="8646630833216197238">"Tilpas dit udvalg af kanaler"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Se indhold fra dine apps, ligesom du ser kanaler på fjernsynet."</item>
+ <item msgid="1855708984677953238">"Gennemse indhold fra dine apps ved hjælp af en velkendt oversigt og en indbydende grænseflade, \npræcis ligesom kanaler på fjernsynet."</item>
+ <item msgid="3420760668363283731">"Tilføj flere kanaler ved at installere apps, der viser tv-kanaler. \nFind kompatible apps i Google Play Butik via linket i TV-menuen."</item>
+ <item msgid="8974157841656828507">"Konfigurer dine nyinstallerede kanalkilder for at tilpasse din kanalliste. \nVælg kanalkilderne i menuen Indstillinger for at komme godt i gang."</item>
+ </string-array>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index d329026b..32ab8b45 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -39,9 +39,8 @@
<string name="options_item_pip_on" msgid="4647247480009077381">"Til"</string>
<string name="options_item_pip_off" msgid="8799500161592387451">"Fra"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Flere lydspor"</string>
- <string name="options_item_channel_sources" msgid="2217574947817750560">"Kanalkonfig."</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Børnesikring"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Om"</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>
@@ -84,21 +83,15 @@
<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">"Gruppér efter"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanalkonfiguration"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dette program er blokeret"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalkilder"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Der er nye tilgængelige kanaler"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Tilpas kanallisten"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Vælg kanaler på din programoversigt"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Ikke konfigureret"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Præferencer for undertekster gældende for hele systemet kunne ikke startes."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanal blev tilføjet"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanaler tilføjet"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d kanal blev tilføjet</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Angiv ny pinkode"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Bekræft din pinkode"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Angiv din aktuelle pinkode"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Du har indtastet den forkerte pinkode 5 gange.\nPrøv igen om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekund."</item>
- <item quantity="other" msgid="8829550842387756054">"Du har indtastet den forkerte pinkode 5 gange.\nPrøv igen om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekunder."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Du har indtastet en forkert PIN-kode 5 gange.\nPrøv igen om <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekund.</item>
+ <item quantity="other">Du har indtastet en forkert PIN-kode 5 gange.\nPrøv igen om <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunder.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Om"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open source-licenser"</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_parental_controls" msgid="5449397921700749317">"Børnesikring"</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="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Indstillinger for udviklere"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Aktivér USB-tuner til fjernsynet"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Dit fjernsyn skal understøtte AC3-gennemførsel, for at du kan høre lyd fra USB-tuneren til fjernsynet."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Ingen titel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanalen er blokeret"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Afsnit <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g><xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalkilder"</string>
- <string name="setup_description" msgid="8728423605912915099">"Konfigurer tv-kanaler fra de tilgængelige kilder. Dette kan tage flere minutter afhængigt af kanalkilden."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Udfør"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d tilgængelig kanal"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d tilgængelige kanaler"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nye"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Kilder"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d kanal</item>
+ <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_setup_now" msgid="1772000402336958967">"Ikke konfigureret"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Få flere kilder"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Gennemse apps, der viser tv-kanaler"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Der er 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>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Tryk på VÆLG"</b>" for at få adgang til TV-menuen."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Knappen Tilbage er til den tilsluttede enhed. Tryk på knappen Hjem for at afslutte."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Tv-kanaler understøttes ikke på denne enhed med Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Tv-kanaler skal have tilladelse for at kunne læse tv-guiden."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Konfigurer dine kilder"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Tv-kanaler kombinerer oplevelsen af traditionelle fjernsynskanaler med streamingkanaler fra apps. \n\nKom godt i gang ved at konfigurere de kanalkilder, der allerede er installeret. Du kan også gå til Google Play Butik og finde flere apps med tv-kanaler."</string>
</resources>
diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml
index a8483d38..d7fad130 100644
--- a/res/values-de/arrays.xml
+++ b/res/values-de/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiere"</item>
<item msgid="8215762047341133299">"Technik/Wissenschaft"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live-TV"</item>
+ <item msgid="7307688057853449735">"Einfache Inhaltssuche"</item>
+ <item msgid="7566838222783641942">"Apps herunterladen und mehr Kanäle erhalten"</item>
+ <item msgid="8646630833216197238">"Kanalliste personalisieren"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Sie können sich Inhalte aus Ihren Apps genauso wie Fernsehsender ansehen."</item>
+ <item msgid="1855708984677953238">"Dank der bekannten Programmübersicht und einer benutzerfreundlichen Oberfläche können Sie in der App genauso nach Inhalten suchen,\nwie Sie auf Ihrem Fernseher nach Sendern suchen."</item>
+ <item msgid="3420760668363283731">"Sie können weitere Kanäle hinzufügen, indem Sie Apps installieren, die Live-TV anbieten.\nÜber den Link im TV-Menü können Sie im Google Play Store nach kompatiblen Apps suchen."</item>
+ <item msgid="8974157841656828507">"Richten Sie die neu installierten Kanalquellen ein, um Ihre Kanalliste zu personalisieren.\nWählen Sie dazu zuerst im Menü \"Einstellungen\" Ihre Kanalquellen aus."</item>
+ </string-array>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 189d809e..7c58d930 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanaleinrichtung"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Jugendschutz"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Info"</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>
@@ -84,21 +83,15 @@
<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">"Gruppieren nach"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanaleinrichtung"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Diese Sendung ist blockiert."</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalquellen"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Neue Kanäle verfügbar"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Kanalliste anpassen"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Kanäle für Programmübersicht auswählen"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nicht eingerichtet"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Systemweite Einstellungen für Untertitel können nicht aufgerufen werden."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d Kanal hinzugefügt"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d Kanäle hinzugefügt"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d Kanäle hinzugefügt</item>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Sie haben 5 Mal die falsche PIN eingegeben.\nVersuchen Sie es in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> Sekunde erneut."</item>
- <item quantity="other" msgid="8829550842387756054">"Sie haben 5 Mal die falsche PIN eingegeben.\nVersuchen Sie es in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> Sekunden erneut."</item>
- </plurals>
+ <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>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Info"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open-Source-Lizenzen"</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_menu_licenses" msgid="1257646083838406103">"Open-Source-Lizenzen"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Open-Source-Lizenzen"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Entwickleroptionen"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB-TV-Empfänger aktivieren"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Damit die Audioausgabe über den USB-TV-Empfänger funktioniert, muss Ihr Fernseher AC-3-Passthrough unterstützen."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Kein Titel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal blockiert"</string>
<string name="episode_format" msgid="4881195874563241096">"Staffel <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Folge <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalquellen"</string>
- <string name="setup_description" msgid="8728423605912915099">"Richten Sie Livekanäle aus den verfügbaren Quellen ein. Dies kann je nach Kanalquelle einige Minuten dauern."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Fertig"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d Kanal verfügbar"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d Kanäle verfügbar"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Neu"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Quellen"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d Kanäle</item>
+ <item quantity="one">%1$d Kanal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Keine Kanäle verfügbar"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Neu"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nicht eingerichtet"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Weitere Quellen suchen"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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_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>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Live TV wird auf diesem Gerät mit Android Lollipop nicht unterstützt."</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>
</resources>
diff --git a/res/values-el/arrays.xml b/res/values-el/arrays.xml
index cc8cc4ec..15114cc8 100644
--- a/res/values-el/arrays.xml
+++ b/res/values-el/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Πρεμιέρες"</item>
<item msgid="8215762047341133299">"Τεχνολογία/Επιστήμη"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Ζωντανά κανάλια"</item>
+ <item msgid="7307688057853449735">"Ένας απλός τρόπος για να ανακαλύψετε περιεχόμενο"</item>
+ <item msgid="7566838222783641942">"Κατεβάστε εφαρμογές, αποκτήστε περισσότερα κανάλια"</item>
+ <item msgid="8646630833216197238">"Προσαρμόστε το πρόγραμμα του καναλιού σας"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Παρακολουθήστε περιεχόμενο από τις εφαρμογές σας, όπως παρακολουθείτε κανάλια στην τηλεόραση."</item>
+ <item msgid="1855708984677953238">"Αναζητήστε περιεχόμενο από τις εφαρμογές σας με έναν οικείο οδηγό και φιλική διεπαφή, \nόπως με τα τηλεοπτικά κανάλια."</item>
+ <item msgid="3420760668363283731">"Προσθέστε περισσότερα κανάλια εγκαθιστώντας εφαρμογές που προσφέρουν ζωντανά κανάλια. \nΕντοπίστε συμβατές εφαρμογές στο Google Play Store χρησιμοποιώντας το σύνδεσμο που περιέχεται στο μενού της τηλεόρασης."</item>
+ <item msgid="8974157841656828507">"Ρυθμίστε τις νέες πηγές καναλιών που εγκαταστήσατε, για να προσαρμόσετε τη λίστα καναλιών σας. \nΕπιλέξτε τις Πηγές καναλιών από το μενού \"Ρυθμίσεις\" για να ξεκινήσετε."</item>
+ </string-array>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index af7f3d1b..9aab6c54 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Ρύθμ. καναλιού"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Γονικός έλεγχος"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Πληροφορίες"</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>
@@ -84,19 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Ρύθμιση καναλιού"</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="channel_source_item_setup" msgid="1330441915487807542">"Πηγές καναλιών"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Νέα κανάλια διαθέσιμα"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Προσ. λίστ. καναλ."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Επιλέξτε κανάλια για οδηγό προγράμματος"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Δεν ρυθμίστηκε"</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:one (6074059986849579215) -->
+ <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>
@@ -134,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Έχετε εισαγάγει λανθασμένα το PIN σας 5 φορές.\nΔοκιμάστε ξανά σε <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> δευτερόλεπτο."</item>
- <item quantity="other" msgid="8829550842387756054">"Έχετε εισαγάγει λανθασμένα τον κωδικό PIN 5 φορές. \n Δοκιμάστε ξανά σε <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> δευτερόλεπτα."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Πληροφορίες"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Άδειες λογισμικού ανοικτού κώδικα"</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="about_menu_version" msgid="6303769835664868129">"Έκδοση"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Έκδοση"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Επιλογές για προγραμματιστές"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Ενεργοποίηση δέκτη USB τηλεόρασης"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Για να ακούσετε ήχο από τον δέκτη USB τηλεόρασης, η τηλεόρασή σας θα πρέπει να υποστηρίζει διέλευση AC3."</string>
@@ -164,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Χωρίς τίτλο"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Το κανάλι αποκλείστηκε"</string>
<string name="episode_format" msgid="4881195874563241096">"Σεζ. <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Επ. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Πηγές καναλιών"</string>
- <string name="setup_description" msgid="8728423605912915099">"Ρυθμίστε ζωντανά κανάλια από τις διαθέσιμες πηγές. Αυτό μπορεί να διαρκέσει αρκετά λεπτά, ανάλογα με την πηγή καναλιού"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Τέλος"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d διαθέσιμο κανάλι"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d διαθέσιμα κανάλια"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Λήψη περισσότερων πηγών"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Περιήγηση σε εφαρμογές που προσφέρουν ζωντανά κανάλια"</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>
@@ -189,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Το πλήκτρο BACK αφορά τη συνδεδεμένη συσκευή. Πατήστε το πλήκτρο HOME για έξοδο."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Τα ζωντανά κανάλια δεν υποστηρίζονται σε αυτήν τη συσκευή με Android Lollipop."</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>
</resources>
diff --git a/res/values-en-rAU/arrays.xml b/res/values-en-rAU/arrays.xml
index 03b775c6..082a7de4 100644
--- a/res/values-en-rAU/arrays.xml
+++ b/res/values-en-rAU/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Tech/Science"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live TV"</item>
+ <item msgid="7307688057853449735">"A simple way to discover content"</item>
+ <item msgid="7566838222783641942">"Download apps, get more channels"</item>
+ <item msgid="8646630833216197238">"Customise your channel line-up"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Watch content from your apps such as watching channels on TV."</item>
+ <item msgid="1855708984677953238">"Browse content from your apps with a familiar guide and friendly interface, \njust like channels on TV."</item>
+ <item msgid="3420760668363283731">"Add more channels by installing apps that offer live channels. \nFind compatible apps in Google Play Store by using the link within the TV menu."</item>
+ <item msgid="8974157841656828507">"Set up your newly installed channel sources to customise your channel list. \nChoose the Channel sources within the Settings menu to get started."</item>
+ </string-array>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 31d8c457..512a7f1a 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Channel setup"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Parental controls"</string>
- <string name="options_item_about" msgid="3023532413252052050">"About"</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>
@@ -84,21 +83,15 @@
<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">"Group by"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Channel setup"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</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="channel_source_item_setup" msgid="1330441915487807542">"Channel sources"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"New channels available"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Customise channel list"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Choose channels for your programme guide"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Not set up"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Unable to start the system-wide preferences for closed captions."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d channel added"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d channels added"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d channels added</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirm your PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Enter your current PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> second."</item>
- <item quantity="other" msgid="8829550842387756054">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconds."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconds.</item>
+ <item quantity="one">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> second.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"About"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open source licences"</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_menu_licenses" msgid="1257646083838406103">"Open source licences"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Open source licences"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Developer options"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Enable USB TV tuner"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"To hear sound from the USB TV tuner, your TV should support AC3 passthrough."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"No title"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Channel blocked"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Channel sources"</string>
- <string name="setup_description" msgid="8728423605912915099">"Set up live channels from the available sources. This may take several minutes depending on the channel source."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Finished"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d channel available"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d channels available"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"N"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sources"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d channels</item>
+ <item quantity="one">%1$d channel</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No channels available"</string>
<string name="setup_input_new" msgid="3337725672277046798">"New"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Not set up"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Get more sources"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Browse apps that offer live channels"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"New channel sources available"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"New channel sources have channels to offer.\nSet them up now, or do this later in the channel sources setting."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Set up now"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, I\'ve got it"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK key is for connected device. Press HOME button to exit."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live TV is not supported on this device with Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV needs permission to read the TV listings."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Set up your sources"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"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>
</resources>
diff --git a/res/values-en-rGB/arrays.xml b/res/values-en-rGB/arrays.xml
index 03b775c6..082a7de4 100644
--- a/res/values-en-rGB/arrays.xml
+++ b/res/values-en-rGB/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Tech/Science"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live TV"</item>
+ <item msgid="7307688057853449735">"A simple way to discover content"</item>
+ <item msgid="7566838222783641942">"Download apps, get more channels"</item>
+ <item msgid="8646630833216197238">"Customise your channel line-up"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Watch content from your apps such as watching channels on TV."</item>
+ <item msgid="1855708984677953238">"Browse content from your apps with a familiar guide and friendly interface, \njust like channels on TV."</item>
+ <item msgid="3420760668363283731">"Add more channels by installing apps that offer live channels. \nFind compatible apps in Google Play Store by using the link within the TV menu."</item>
+ <item msgid="8974157841656828507">"Set up your newly installed channel sources to customise your channel list. \nChoose the Channel sources within the Settings menu to get started."</item>
+ </string-array>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 31d8c457..512a7f1a 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Channel setup"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Parental controls"</string>
- <string name="options_item_about" msgid="3023532413252052050">"About"</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>
@@ -84,21 +83,15 @@
<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">"Group by"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Channel setup"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</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="channel_source_item_setup" msgid="1330441915487807542">"Channel sources"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"New channels available"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Customise channel list"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Choose channels for your programme guide"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Not set up"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Unable to start the system-wide preferences for closed captions."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d channel added"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d channels added"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d channels added</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirm your PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Enter your current PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> second."</item>
- <item quantity="other" msgid="8829550842387756054">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconds."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconds.</item>
+ <item quantity="one">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> second.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"About"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open source licences"</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_menu_licenses" msgid="1257646083838406103">"Open source licences"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Open source licences"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Developer options"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Enable USB TV tuner"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"To hear sound from the USB TV tuner, your TV should support AC3 passthrough."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"No title"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Channel blocked"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Channel sources"</string>
- <string name="setup_description" msgid="8728423605912915099">"Set up live channels from the available sources. This may take several minutes depending on the channel source."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Finished"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d channel available"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d channels available"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"N"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sources"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d channels</item>
+ <item quantity="one">%1$d channel</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No channels available"</string>
<string name="setup_input_new" msgid="3337725672277046798">"New"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Not set up"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Get more sources"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Browse apps that offer live channels"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"New channel sources available"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"New channel sources have channels to offer.\nSet them up now, or do this later in the channel sources setting."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Set up now"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, I\'ve got it"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK key is for connected device. Press HOME button to exit."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live TV is not supported on this device with Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV needs permission to read the TV listings."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Set up your sources"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"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>
</resources>
diff --git a/res/values-en-rIN/arrays.xml b/res/values-en-rIN/arrays.xml
index 03b775c6..082a7de4 100644
--- a/res/values-en-rIN/arrays.xml
+++ b/res/values-en-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Tech/Science"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live TV"</item>
+ <item msgid="7307688057853449735">"A simple way to discover content"</item>
+ <item msgid="7566838222783641942">"Download apps, get more channels"</item>
+ <item msgid="8646630833216197238">"Customise your channel line-up"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Watch content from your apps such as watching channels on TV."</item>
+ <item msgid="1855708984677953238">"Browse content from your apps with a familiar guide and friendly interface, \njust like channels on TV."</item>
+ <item msgid="3420760668363283731">"Add more channels by installing apps that offer live channels. \nFind compatible apps in Google Play Store by using the link within the TV menu."</item>
+ <item msgid="8974157841656828507">"Set up your newly installed channel sources to customise your channel list. \nChoose the Channel sources within the Settings menu to get started."</item>
+ </string-array>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 31d8c457..512a7f1a 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Channel setup"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Parental controls"</string>
- <string name="options_item_about" msgid="3023532413252052050">"About"</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>
@@ -84,21 +83,15 @@
<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">"Group by"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Channel setup"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</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="channel_source_item_setup" msgid="1330441915487807542">"Channel sources"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"New channels available"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Customise channel list"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Choose channels for your programme guide"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Not set up"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Unable to start the system-wide preferences for closed captions."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d channel added"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d channels added"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d channels added</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirm your PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Enter your current PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> second."</item>
- <item quantity="other" msgid="8829550842387756054">"You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconds."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconds.</item>
+ <item quantity="one">You entered the wrong PIN 5 times.\nTry again in <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> second.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"About"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open source licences"</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_menu_licenses" msgid="1257646083838406103">"Open source licences"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Open source licences"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Developer options"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Enable USB TV tuner"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"To hear sound from the USB TV tuner, your TV should support AC3 passthrough."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"No title"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Channel blocked"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Channel sources"</string>
- <string name="setup_description" msgid="8728423605912915099">"Set up live channels from the available sources. This may take several minutes depending on the channel source."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Finished"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d channel available"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d channels available"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"N"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sources"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d channels</item>
+ <item quantity="one">%1$d channel</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No channels available"</string>
<string name="setup_input_new" msgid="3337725672277046798">"New"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Not set up"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Get more sources"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Browse apps that offer live channels"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"New channel sources available"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"New channel sources have channels to offer.\nSet them up now, or do this later in the channel sources setting."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Set up now"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, I\'ve got it"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK key is for connected device. Press HOME button to exit."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live TV is not supported on this device with Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV needs permission to read the TV listings."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Set up your sources"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"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>
</resources>
diff --git a/res/values-es-rUS/arrays.xml b/res/values-es-rUS/arrays.xml
index 8873f092..de5b7910 100644
--- a/res/values-es-rUS/arrays.xml
+++ b/res/values-es-rUS/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Estrenos"</item>
<item msgid="8215762047341133299">"Ciencia y tecnología"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canales en vivo"</item>
+ <item msgid="7307688057853449735">"Una manera simple de descubrir contenido"</item>
+ <item msgid="7566838222783641942">"Descarga apps y obtén más canales"</item>
+ <item msgid="8646630833216197238">"Personaliza tu listado de canales"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Mira contenido desde tus apps como si miraras canales en la TV."</item>
+ <item msgid="1855708984677953238">"Navega por el contenido de tus apps con una guía que ya conoces y una interfaz simple,\ncomo lo haces con los canales de TV."</item>
+ <item msgid="3420760668363283731">"Agrega más canales mediante la instalación de apps que ofrecen canales en vivo.\nEncuentra apps compatibles en Google Play Store con el vínculo que aparece en el menú de TV."</item>
+ <item msgid="8974157841656828507">"Configura tus fuentes de canales recién instaladas para personalizar la lista de canales.\nElige las fuentes de Canales en el menú Configuración para comenzar."</item>
+ </string-array>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 73081293..3397798b 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Configuración"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Cont parentales"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Información"</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>
@@ -84,21 +83,15 @@
<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">"Agrupar por"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Configuración"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado."</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="channel_source_item_setup" msgid="1330441915487807542">"Fuentes de canales"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nuevos canales disponibles"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personalizar lista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Seleccionar canales de guía de programas"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Sin configurar"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Error al iniciar las preferencias de los subtítulos del sistema"</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d canal agregado"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d canales agregados"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">Se agregaron %1$d canales</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ingresar nuevo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmar el PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Ingresa tu PIN actual"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Ingresaste un PIN incorrecto 5 veces.\nReintenta en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Ingresaste un PIN incorrecto 5 veces.\nReintenta en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundos."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Ingresaste el PIN incorrecto 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
+ <item quantity="one">Ingresaste el PIN incorrecto 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Información"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licencias de código abierto"</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_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="about_menu_version" msgid="6303769835664868129">"Versión"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opciones para programador"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Habilitar sintonizador de TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Para escuchar el sonido del sintonizador de TV USB, la TV debe ser compatible con el formato AC-3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sin título"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canal bloqueado"</string>
<string name="episode_format" msgid="4881195874563241096">"Temporada <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>. Episodio <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>."</string>
- <string name="setup_title" msgid="7268875010986705651">"Fuentes de canales"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configura canales en vivo desde las fuentes disponibles. Este proceso puede demorar unos minutos, según la fuente del canal."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Listo"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canal disponible"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canales disponibles"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nuevas"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Fuentes"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d canales</item>
+ <item quantity="one">%1$d canal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No hay canales disponibles."</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nueva"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Sin configurar"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Obtener más fuentes"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Explorar 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>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Entendido"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Presiona SELECCIONAR"</b>" para acceder al menú de la televisión."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"La tecla ATRÁS es para el dispositivo conectado. Presiona el botón INICIO para salir."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"\"Canales en vivo\" no es compatible con este dispositivo con Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"\"Canales en vivo\" necesita permiso para leer las listas de canales de televisión."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configura tus fuentes"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Canales en vivo combina la experiencia de los canales de TV tradicionales con la transmisión de canales que ofrecen las apps.\n\nPara comenzar, configura las fuentes de canales que ya están instaladas o explora Google Play Store para obtener más apps que ofrecen canales en vivo."</string>
</resources>
diff --git a/res/values-es/arrays.xml b/res/values-es/arrays.xml
index bd1b9512..20d54571 100644
--- a/res/values-es/arrays.xml
+++ b/res/values-es/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"De primera línea"</item>
<item msgid="8215762047341133299">"Ciencia y tecnología"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"TV en directo"</item>
+ <item msgid="7307688057853449735">"Una forma sencilla de descubrir contenido"</item>
+ <item msgid="7566838222783641942">"Descarga aplicaciones, obtén más canales"</item>
+ <item msgid="8646630833216197238">"Personaliza la lista de canales"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Ve el contenido de tus aplicaciones como si vieses canales en la TV."</item>
+ <item msgid="1855708984677953238">"Explora el contenido de las aplicaciones con una guía familiar y una interfaz intuitiva \nsimilar a los canales de la TV."</item>
+ <item msgid="3420760668363283731">"Instala aplicaciones que ofrezcan TV en directo para añadir más canales. \nUtiliza el enlace del menú de TV para encontrar aplicaciones compatibles en Google Play Store."</item>
+ <item msgid="8974157841656828507">"Configura las nuevas fuentes de canales para personalizar la lista de canales. \nPara empezar, selecciona las fuentes de canales en el menú Ajustes."</item>
+ </string-array>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f1098c0d..cb7bdcff 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Config. canal"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Cont. parentales"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Información"</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>
@@ -84,21 +83,15 @@
<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">"Agrupar por"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Config. canal"</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 se ha clasificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="channel_source_item_setup" msgid="1330441915487807542">"Fuentes de canales"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nuevos canales disponibles"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personalizar lista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Seleccionar canales de la guía de programas"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Sin configurar"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Error al iniciar las preferencias de los ajustes de subtítulos del sistema."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d canal añadido"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d canales añadidos"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d canales añadidos</item>
+ <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>
@@ -136,16 +129,21 @@
<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>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Has introducido el PIN incorrectamente 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Has introducido el PIN incorrectamente 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundos."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Has introducido un número PIN incorrecto 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
+ <item quantity="one">Has introducido un número PIN incorrecto 5 veces.\nVuelve a intentarlo en <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Información"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licencias software libre"</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_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="about_menu_version" msgid="6303769835664868129">"Versión"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opciones de desarrollo"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Habilitar sintonizador de canales USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Para escuchar el sonido del sintonizador de canales USB, tu TV debe admitir la conexión AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sin título"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canal bloqueado"</string>
<string name="episode_format" msgid="4881195874563241096">"Temporada <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: episodio <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> (<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>)"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fuentes de canales"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configura canales en directo a partir de las fuentes disponibles. Este proceso puede tardar unos minutos en función de la fuente del canal."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Listo"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canal disponible"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canales disponibles"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nuevas"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Fuentes"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d canales</item>
+ <item quantity="one">%1$d canal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No hay canales disponibles"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nuevas"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Sin configurar"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Obtener más fuentes"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Explorar aplicaciones que ofrecen 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>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Entendido"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Pulsa SELECCIONAR"</b>" para acceder al menú de la TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"La tecla VOLVER es para dispositivos conectados. Pulsa el botón de inicio para salir."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Canales en directo no se admite en este dispositivo con Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canales en directo necesita permiso para consultar las programaciones de TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configura las fuentes de canales"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"TV en directo combina la experiencia de los canales de TV tradicionales con los canales de reproducción en streaming que proporcionan las aplicaciones. \n\nPara empezar, configura las fuentes de canales que ya están instaladas. También puedes buscar más aplicaciones que ofrezcan TV en directo en Google Play Store."</string>
</resources>
diff --git a/res/values-et-rEE/arrays.xml b/res/values-et-rEE/arrays.xml
index eb64ab43..2d1d11fd 100644
--- a/res/values-et-rEE/arrays.xml
+++ b/res/values-et-rEE/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Esilinastus"</item>
<item msgid="8215762047341133299">"Tehnika/teadus"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Reaalajakanalid"</item>
+ <item msgid="7307688057853449735">"Lihtne viis sisu avastamiseks"</item>
+ <item msgid="7566838222783641942">"Rakenduste allalaadimine ja kanalite hankimine"</item>
+ <item msgid="8646630833216197238">"Kanalivaliku kohandamine"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Vaadake oma rakendustest sisu, nagu vaataksite telekanaleid."</item>
+ <item msgid="1855708984677953238">"Sirvige oma rakendustes sisu tuttava kava ja kasutajasõbraliku liidesega (\njust nagu telekanalite puhul)."</item>
+ <item msgid="3420760668363283731">"Lisage rohkem kanaleid, installides rakendusi, mis pakuvad reaalajakanaleid. \nLeidke ühilduvaid rakendusi Google Play poest, kasutades TV-menüüs olevat linki."</item>
+ <item msgid="8974157841656828507">"Seadistage kanaliloendi kohandamiseks oma äsja installitud kanaliallikad. \nAlustamiseks tehke menüüs Seaded valik Kanaliallikad."</item>
+ </string-array>
</resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 7029d309..f68c9e6d 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanali seadist."</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Järelevalve"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Teave"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanali seadistus"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanali allikad"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Saadaval on uued kanalid"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Kanaliloendi kohandam."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Kanalite valimine saatekava jaoks"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Pole seadistatud"</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">
- <item quantity="one" msgid="6074059986849579215">"Lisatud on %1$d kanal"</item>
- <item quantity="other" msgid="1078861616751739285">"Lisatud on %1$d kanalit"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Olete 5 korda sisestanud vale PIN-koodi.\nProovige uuesti <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundi pärast."</item>
- <item quantity="other" msgid="8829550842387756054">"Olete 5 korda sisestanud vale PIN-koodi.\nProovige uuesti <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundi pärast."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Teave"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Avatud lähtekoodi litsentsid"</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="about_menu_version" msgid="6303769835664868129">"Versioon"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versioon"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Arendaja valikud"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Luba USB-telerituuner"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB-telerituuneri heli kuulmiseks peab teie teler toetama AC3-ülekannet."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"Hooaeg <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: jagu <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanali allikad"</string>
- <string name="setup_description" msgid="8728423605912915099">"Seadistage saadaolevatest allikatest otseülekandes kanalid. Selleks võib olenevalt kanali allikast kuluda mitu minutit."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Valmis"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Sisendi %1$d kanal on saadaval"</item>
- <item quantity="other" msgid="2386588423841837714">"Sisendi %1$d kanalid on saadaval"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Hankige rohkem allikaid"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Reaalajas kanaleid selles seadmes operatsioonisüsteemiga Android Lollipop ei toetata."</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>
</resources>
diff --git a/res/values-eu-rES/arrays.xml b/res/values-eu-rES/arrays.xml
index e25f86bc..89b32135 100644
--- a/res/values-eu-rES/arrays.xml
+++ b/res/values-eu-rES/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Onenak"</item>
<item msgid="8215762047341133299">"Zientzia/Teknologia"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Telebista zuzenean"</item>
+ <item msgid="7307688057853449735">"Edukia ezagutzeko modu erraza"</item>
+ <item msgid="7566838222783641942">"Deskargatu aplikazioak eta lortu kanal gehiago"</item>
+ <item msgid="8646630833216197238">"Pertsonalizatu kanalen antolakuntza"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Ikusi aplikazioetako edukia, telebistan kanalak ikusten dituzun moduan."</item>
+ <item msgid="1855708984677953238">"Arakatu aplikazioetako edukia gida ezagun eta interfaze lagungarri batekin\n, telebistako kanalak bezala."</item>
+ <item msgid="3420760668363283731">"Kanalak gehitzeko, instalatu zuzeneko kanalak eskaintzen dituzten aplikazioak.\nBilatu aplikazio bateragarriak Google Play Store dendan, telebistako menuko estekaren bidez."</item>
+ <item msgid="8974157841656828507">"Konfiguratu instalatu berri dituzun kanal-iturburuak kanalen zerrenda pertsonalizatzeko.\nLehen urratsak emateko, aukeratu kanal-iturburuak Ezarpenak menuan."</item>
+ </string-array>
</resources>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 60d3f58a..065e764c 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Konfigurazioa"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Gurasoen ezarpenak"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Honi buruz"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Konfigurazioa"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalen iturburuak"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Kanal berriak daude"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Pertsonalizatu zerrenda"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Aukeratu telesaioen gidako kanalak"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Konfiguratu gabe"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanal gehitu da"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanal gehitu dira"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PIN kodea oker idatzi duzu bost aldiz.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo barru."</item>
- <item quantity="other" msgid="8829550842387756054">"PIN kodea oker idatzi duzu bost aldiz.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo barru."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Honi buruz"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Kode irekiko lizentziak"</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="about_menu_version" msgid="6303769835664868129">"Bertsioa"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Bertsioa"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Garatzaileen aukerak"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Gaitu USB bidezko sintonizadorea"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB bidezko sintonizadorearen soinua entzuteko, AC3 sarbide zuzenarekin bateragarria izan behar du telebistak."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>. denboraldia, <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>. atala (<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>)"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalen iturburuak"</string>
- <string name="setup_description" msgid="8728423605912915099">"Konfiguratu zuzenean ikus daitezkeen kanalak, erabilgarri dauden iturburuak erabilita. Hainbat minutu behar izan daitezke, kanalaren iturburuaren arabera."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Eginda"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanal dago erabilgarri"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanal daude erabilgarri"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Lortu iturburu gehiago"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Arakatu 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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Atzera tekla konektatutako gailuari dagokio. Irteteko, sakatu Hasiera botoia."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop duen gailu honetan ezin da erabili Zuzeneko kanalak aplikazioa."</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>
</resources>
diff --git a/res/values-fa/arrays.xml b/res/values-fa/arrays.xml
index b60cbf07..a9b956f5 100644
--- a/res/values-fa/arrays.xml
+++ b/res/values-fa/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"برتر"</item>
<item msgid="8215762047341133299">"فناوری/علم"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"کانال‌های زنده"</item>
+ <item msgid="7307688057853449735">"راهی ساده برای کاوش محتوا"</item>
+ <item msgid="7566838222783641942">"بارگیری برنامه‌ها و دسترسی به کانال‌های بیشتر"</item>
+ <item msgid="8646630833216197238">"سفارشی کردن ترتیب کانال‌ها"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"محتوای برنامه‌هایتان را مثل تماشای کانال‌های تلویزیونی تماشا کنید."</item>
+ <item msgid="1855708984677953238">"با راهنمای آشنا و واسط کاربرپسند، محتوای برنامه‌هایتان را مرور کنید، \nدرست مثل کانال‌های تلویزیونی."</item>
+ <item msgid="3420760668363283731">"‏با نصب برنامه‌هایی که کانال‌های زنده ارائه می‌کنند، کانال‌هایی بیشتری اضافه کنید. \nبا استفاده از پیوند موجود در منوی تلویزیون، برنامه‌های سازگار را در فروشگاه Google Play پیدا کنید."</item>
+ <item msgid="8974157841656828507">"برای سفارشی کردن فهرست کانال خود، منابع کانال جدیداً نصب‌شده را تنظیم کنید.\nبرای شروع، از منوی «تنظیمات»، منابع کانال را انتخاب کنید."</item>
+ </string-array>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 96c3ccce..01f2ff18 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -24,7 +24,7 @@
<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_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>
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"تنظیم کانال"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"کنترل‌های والدین"</string>
- <string name="options_item_about" msgid="3023532413252052050">"درباره"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"وضوح بالا"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"وضوح استاندارد"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"گروه‌بندی براساس"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"تنظیم کانال"</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="channel_source_item_setup" msgid="1330441915487807542">"منابع کانال"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"کانال‌های جدید در دسترس است"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"سفارشی کردن فهرست کانال‌ها"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"کانال‌ها را جهت راهنمای برنامه‌تان انتخاب کنید"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"تنظیم نشده است"</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">
- <item quantity="one" msgid="6074059986849579215">"‏%1$d کانال اضافه شد"</item>
- <item quantity="other" msgid="1078861616751739285">"‏%1$d کانال اضافه شدند"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"پین اشتباه را ۵ بار وارد کردید.\nبعد از <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ثانیه، دوباره امتحان کنید."</item>
- <item quantity="other" msgid="8829550842387756054">"پین اشتباه را ۵ بار وارد کردید.\n بعد از <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ثانیه، دوباره امتحان کنید."</item>
- </plurals>
+ <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">"این پین اشتباه بود. دوباره امتحان کنید."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"دوباره امتحان کنید، پین منطبق نیست"</string>
- <string name="side_panel_title_about" msgid="4572960435017168299">"درباره"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"مجوزهای منبع آزاد"</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="about_menu_version" msgid="6303769835664868129">"نسخه"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"نسخه"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"گزینه‌های برنامه‌نویس"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"‏فعال کردن تنظیم‌کننده تلویزیون USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"‏برای شنیدن صدای تنظیم‌کننده تلویزیون USB، تلویزیونتان باید از انتقال AC3 پشتیبانی کند."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"بدون عنوان"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"کانال مسدود شد"</string>
<string name="episode_format" msgid="4881195874563241096">"ف <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ق <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> ‏<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"منابع کانال"</string>
- <string name="setup_description" msgid="8728423605912915099">"تنظیم کانال‌های مستقیم از منابع در دسترس. بسته به منبع کانال، ممکن است چند دقیقه طول بکشد."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"تمام"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"‏%1$d کانال موجود"</item>
- <item quantity="other" msgid="2386588423841837714">"‏%1$d کانال موجود"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"دریافت منابع بیشتر"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"مرور برنامه‌هایی که کانال‌های زنده ارائه می‌کنند"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"کلید بازگشت برای دستگاه‌ متصل است. برای خروج دکمه صفحه اصلی را فشار دهید."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"‏کانال‌های مستقیم در این دستگاه دارای Android Lollipop پشتیبانی نمی‌شوند."</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>
</resources>
diff --git a/res/values-fi/arrays.xml b/res/values-fi/arrays.xml
index 055465ed..01266b27 100644
--- a/res/values-fi/arrays.xml
+++ b/res/values-fi/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Ensiesitys"</item>
<item msgid="8215762047341133299">"Tekniikka/tiede"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live-kanavat"</item>
+ <item msgid="7307688057853449735">"Löydä sisältöä helposti"</item>
+ <item msgid="7566838222783641942">"Lisää kanavia lataamalla sovelluksia"</item>
+ <item msgid="8646630833216197238">"Personoi kanavavalikoimasi"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Katso sisältöä sovelluksista, aivan kuin katsoisit TV-kanavia."</item>
+ <item msgid="1855708984677953238">"Selaa sovellusten sisältöä oppaan ja selkeän käyttöliittymän avulla, \naivan kuin katsoisit TV-kanavia."</item>
+ <item msgid="3420760668363283731">"Saat lisää kanavia asentamalla live-kanavia tarjoavia sovelluksia. \nHae yhteensopivia sovelluksia Google Play Kaupasta TV-valikon linkillä."</item>
+ <item msgid="8974157841656828507">"Luo personoitu kanavaluettelo määrittämällä asentamasi kanavalähteet. \nAloita valitsemalla kanavalähteet Asetukset-valikosta."</item>
+ </string-array>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 03b9a253..05c134ad 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanavien asetus"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Lapsilukko"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Tietoja"</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>
@@ -84,21 +83,15 @@
<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">"Ryhmittely:"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanavien asetus"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ohjelma on estetty."</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="channel_source_item_setup" msgid="1330441915487807542">"Kanavalähteet"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Uusia kanavia saatavilla."</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Oma kanavaluettelo"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Valitse kanavat ohjelmaoppaaseesi"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Ei määritetty"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Tekstitysten koko järjestelmää koskevien asetusten määritystä ei voi aloittaa."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanava lisätty"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanavaa lisätty"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanavaa lisätty</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Anna uusi PIN-koodi"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Vahvista PIN-koodi"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Anna nykyinen PIN-koodi"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Annoit väärän PIN-koodin 5 kertaa.\nYritä uudelleen <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekunnin kuluttua."</item>
- <item quantity="other" msgid="8829550842387756054">"Annoit väärän PIN-koodin 5 kertaa.\nYritä uudelleen <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekunnin kuluttua."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Olet antanut väärän PIN-koodin viisi kertaa.\nYritä uudestaan <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunnin päästä.</item>
+ <item quantity="one">Olet antanut väärän PIN-koodin viisi kertaa.\nYritä uudestaan <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekunnin päästä.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Tietoja"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Avoimen lähdekoodin käyttöluvat"</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_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="about_menu_version" msgid="6303769835664868129">"Versio"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versio"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Kehittäjäasetukset"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Ota käyttöön USB-TV-viritin"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Televisiosi on tuettava AC3-läpäisyä, jotta voit kuulla TV-virittimen äänet."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Ei nimeä"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanava estetty"</string>
<string name="episode_format" msgid="4881195874563241096">"Kausi <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: jakso <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanavalähteet"</string>
- <string name="setup_description" msgid="8728423605912915099">"Hae live-kanavia saatavilla olevista lähteistä. Kanavalähteestä riippuen tässä voi kestää useita minuutteja."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Valmis"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanavaa käytettävissä"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanavaa käytettävissä"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Uudet"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Lähteet"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanavaa</item>
+ <item quantity="one">%1$d kanava</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Ei käytettävissä olevia kanavia"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Uusi"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Ei määritetty"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Hae lisää lähteitä"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Selaa sovelluksia, jotka tarjoavat livekanavia."</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Uusia kanavalähteitä on saatavilla"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Tarjolla on kanavia uusista lähteistä.\nVoit määrittää kanavalähteet nyt tai tehdä sen myöhemmin kanavalähdeasetuksien kautta."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Määritä nyt"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Selvä"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307">"Avaa TV-valikko "<b>"painamalla VALITSE"</b>"."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"EDELLINEN-painike koskee liitettyä laitetta. Poistu painamalla ETUSIVU-painiketta."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live-kanavia ei tueta tällä Android Lollipop -laitteella."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live-kanavat tarvitsee luvan TV-ohjelmatietojen lukemiseen."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Määritä lähteesi"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Live-kanavat yhdistävät perinteisen TV-kanavakokemuksen suoratoistoon sovelluksilla. \n\nAloita määrittämällä asennetut kanavalähteet tai etsi livekanavia tarjoavia sovelluksia Google Play Kaupasta."</string>
</resources>
diff --git a/res/values-fr-rCA/arrays.xml b/res/values-fr-rCA/arrays.xml
index 75c1e38c..753019ee 100644
--- a/res/values-fr-rCA/arrays.xml
+++ b/res/values-fr-rCA/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Technologies et sciences"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Chaînes en direct"</item>
+ <item msgid="7307688057853449735">"Un moyen simple de découvrir du nouveau contenu"</item>
+ <item msgid="7566838222783641942">"Téléchargez des applications et découvrez de nouvelles chaînes"</item>
+ <item msgid="8646630833216197238">"Personnalisez votre répertoire de chaînes"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Regardez le contenu de vos applications comme s\'il s\'agissait des chaînes de votre téléviseur."</item>
+ <item msgid="1855708984677953238">"Parcourez le contenu de vos applications comme s\'il s\'agissait des chaînes de votre téléviseur, \nà l\'aide d\'un guide que vous connaissez déjà et dans une interface conviviale."</item>
+ <item msgid="3420760668363283731">"Ajoutez des chaînes en installant des applications qui proposent des chaînes en direct. \nRecherchez les applications compatibles dans la boutique Google Play Store à l\'aide du lien dans le menu du téléviseur."</item>
+ <item msgid="8974157841656828507">"Configurez les sources de chaînes que vous avez installées récemment pour personnaliser votre liste de chaînes. \nPour commencer, sélectionnez « Sources des chaînes » dans le menu « Paramètres »."</item>
+ </string-array>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 7a6b328a..347e9537 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Config. chaînes"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Contr. parental"</string>
- <string name="options_item_about" msgid="3023532413252052050">"À propos"</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>
@@ -84,21 +83,15 @@
<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">"Grouper par"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Config. chaînes"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ce programme est bloqué"</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="channel_source_item_setup" msgid="1330441915487807542">"Sources des chaînes"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nouvelles chaînes"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Person. liste chaîn."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Choisir des chaînes pour le guide des programmes"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Non configuré"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Impossible de démarrer les préférences de sous-titrage à l\'échelle du système."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d chaîne ajoutée"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d chaînes ajoutées"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d chaîne ajoutée</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Entrez le nouveau NIP"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmez votre NIP"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Entrez votre NIP actuel"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Vous avez saisi un NIP incorrect à cinq reprises.\nVeuillez réessayer dans <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconde."</item>
- <item quantity="other" msgid="8829550842387756054">"Vous avez entré un NIP erroné cinq fois. \nRéessayez dans <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> secondes."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Vous avez entré le mauvais NIP cinq fois.\nRéessayez dans <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconde.</item>
+ <item quantity="other">Vous avez entré le mauvais NIP cinq fois.\nRéessayez dans <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> secondes.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"À propos"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licences de logiciels libres"</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_menu_licenses" msgid="1257646083838406103">"Licences de logiciels libres"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licences de logiciels libres"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Options pour les développeurs"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Activer le syntoniseur télé USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Pour entendre le son du syntoniseur télé USB, votre téléviseur doit prendre en charge la conversion AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sans titre"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Chaîne bloquée"</string>
<string name="episode_format" msgid="4881195874563241096">"Saison <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>, épisode <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>, « <xliff:g id="EPISODE_TITLE">%3$s</xliff:g> »"</string>
- <string name="setup_title" msgid="7268875010986705651">"Sources des chaînes"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configurer des chaînes en direct à partir des sources disponibles. Cela peut prendre plusieurs minutes, en fonction de la source de la chaîne."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Terminé"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d chaîne disponible"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d chaînes disponibles"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nouveau"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sources"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d chaîne</item>
+ <item quantity="other">%1$d chaînes</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Aucune chaîne disponible"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nouveau"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Non configuré"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Trouver plus de sources"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Parcourir les applications qui offrent des chaînes en direct"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nouvelles sources de chaînes disponibles"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Découvrez des chaînes issues de nouvelles sources.\nConfigurez-les dès maintenant, ou plus tard, à l\'aide du paramètre « Sources des chaînes »."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configurer maintenant"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, j\'ai compris"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307">"Appuyez sur la touche "<b>"Sélectionner"</b>" pour accéder au menu Télévision."</string>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Les chaînes en direct ne sont pas prises en charge sur cet appareil avec Android Lollipop."</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_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>
</resources>
diff --git a/res/values-fr/arrays.xml b/res/values-fr/arrays.xml
index 46b9f692..c893079f 100644
--- a/res/values-fr/arrays.xml
+++ b/res/values-fr/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Haut de gamme"</item>
<item msgid="8215762047341133299">"Technologie/Science"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"TV en direct"</item>
+ <item msgid="7307688057853449735">"Découvrez de nouveaux contenus en toute simplicité"</item>
+ <item msgid="7566838222783641942">"Téléchargez des applications et découvrez de nouvelles chaînes"</item>
+ <item msgid="8646630833216197238">"Personnalisez votre bouquet de chaînes"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Regardez le contenu de vos applications comme s\'il s\'agissait des chaînes de votre téléviseur."</item>
+ <item msgid="1855708984677953238">"Parcourez le contenu de vos applications comme s\'il s\'agissait des chaînes de votre téléviseur, \nà l\'aide d\'un guide que vous connaissez déjà et dans une interface conviviale."</item>
+ <item msgid="3420760668363283731">"Ajoutez des chaînes en installant des applications qui proposent des chaînes en direct. \nRecherchez les applications compatibles sur le Google Play Store à l\'aide du lien dans le menu du téléviseur."</item>
+ <item msgid="8974157841656828507">"Configurez les sources de chaînes que vous avez installées récemment pour personnaliser votre liste de chaînes. \nPour commencer, sélectionnez \"Sources des chaînes\" dans le menu \"Paramètres\"."</item>
+ </string-array>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 3e42ad5c..4a21f5ab 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Configuration"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Contrôle parental"</string>
- <string name="options_item_about" msgid="3023532413252052050">"À propos"</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>
@@ -84,21 +83,15 @@
<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">"Grouper par"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Configuration chaîne"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ce programme est bloqué."</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="channel_source_item_setup" msgid="1330441915487807542">"Sources chaînes"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nouvelles chaînes disponibles"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personnaliser la liste des chaînes"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Choisir des chaînes pour le guide des programmes"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Non configuré"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Impossible de lancer les préférences de sous-titrage pour l\'ensemble du système."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d chaîne ajoutée."</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d chaînes ajoutées."</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d chaîne a bien été ajoutée.</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Saisir le nouveau code d\'accès"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmer votre code d\'accès"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Saisir votre code d\'accès actuel"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Vous avez saisi un code d\'accès incorrect à cinq reprises.\nVeuillez réessayer dans <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconde."</item>
- <item quantity="other" msgid="8829550842387756054">"Vous avez saisi un code d\'accès incorrect à cinq reprises.\nVeuillez réessayer dans <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> secondes."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Vous avez saisi un code incorrect à cinq reprises.\nVeuillez réessayer dans <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconde.</item>
+ <item quantity="other">Vous avez saisi un code incorrect à cinq reprises.\nVeuillez réessayer dans <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> secondes.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"À propos"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licences Open Source"</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_menu_licenses" msgid="1257646083838406103">"Licences Open Source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licences Open Source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Options pour les développeurs"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Activer le tuner TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Pour entendre le son du tuner TV USB, votre téléviseur doit être compatible avec la conversion AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sans titre"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Chaîne bloquée"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>, ép. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> : <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Sources des chaînes"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configurez des chaînes en direct à partir des sources disponibles. Cette opération peut prendre plusieurs minutes en fonction de la source de la chaîne."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"OK"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d chaîne disponible"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d chaînes disponibles"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nouvelle"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sources"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d chaîne</item>
+ <item quantity="other">%1$d chaînes</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Aucune chaîne disponible"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nouveau"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Non configurée"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Découvrir plus de sources"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Parcourir les applications qui proposent des chaînes en direct"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nouvelles sources de chaînes disponibles"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Découvrez des chaînes issues de nouvelles sources.\nConfigurez-les dès maintenant, ou plus tard, à l\'aide du paramètre \"Sources des chaînes\"."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configurer"</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>"Appuyez sur SÉLECTIONNER"</b>" pour accéder au menu de la télévision."</string>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"L\'application Chaînes en direct n\'est pas compatible avec les appareils équipés d\'Android Lollipop."</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_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>
</resources>
diff --git a/res/values-gl-rES/arrays.xml b/res/values-gl-rES/arrays.xml
index cd8c31f3..0bbc3853 100644
--- a/res/values-gl-rES/arrays.xml
+++ b/res/values-gl-rES/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Estrea"</item>
<item msgid="8215762047341133299">"Ciencia e tecnoloxía"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"TV en directo"</item>
+ <item msgid="7307688057853449735">"Unha forma sinxela de descubrir contido"</item>
+ <item msgid="7566838222783641942">"Descarga aplicacións e obtén máis canles"</item>
+ <item msgid="8646630833216197238">"Personaliza a túa lista de canles"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Visualiza contido das túas aplicacións igual que nas canles da televisión."</item>
+ <item msgid="1855708984677953238">"Examina o contido das túas aplicacións cunha guía familiar e unha interface intuitiva, \nigual que as canles da televisión."</item>
+ <item msgid="3420760668363283731">"Engade máis canles ao instalar aplicacións que proporcionan canles en directo. \nUtiliza a ligazón do menú da televisión para buscar aplicacións compatibles en Google Play Store."</item>
+ <item msgid="8974157841656828507">"Configura as fontes de canles instaladas recentemente para personalizar a túa lista de canles. \nPara comezar, selecciona Fontes de canles no menú Configuración."</item>
+ </string-array>
</resources>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 54b49f8c..63ebbcbc 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Config. canle"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Controis pais"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Acerca de"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Configuración canle"</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="channel_source_item_setup" msgid="1330441915487807542">"Fontes de canles"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Novas canles dispoñibles"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personalizar lista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Selecciona canles para a túa guía"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Sen configurar"</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">
- <item quantity="one" msgid="6074059986849579215">"Engadiuse %1$d canle"</item>
- <item quantity="other" msgid="1078861616751739285">"Engadíronse %1$d canles"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Introduciches o PIN incorrecto 5 veces.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Introduciches o PIN incorrecto 5 veces.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundos."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Acerca de"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licenzas de código aberto"</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="about_menu_version" msgid="6303769835664868129">"Versión"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opcións de programador"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Activar sintonizador de televisión USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Para escoitar o son do sintonizador de televisión USB, a túa televisión debe ser compatible coa conexión AC3."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"T<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fontes de canles"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configura as canles en directo a partir das fontes dispoñibles. Esta acción pode tardar varios minutos dependendo da fonte da canle."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Feito"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canle dispoñible"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canles dispoñibles"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Obter máis fontes"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Examinar 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>
@@ -190,5 +194,7 @@
<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_not_supported_device" msgid="4469404625040284722">"As canles en directo non son compatibles neste dispositivo con Android Lollipop."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"As canles en directo necesitan permiso para ler a lista de canles da televisión."</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>
</resources>
diff --git a/res/values-hi/arrays.xml b/res/values-hi/arrays.xml
index f9eea000..37e4222c 100644
--- a/res/values-hi/arrays.xml
+++ b/res/values-hi/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"प्रीमियर"</item>
<item msgid="8215762047341133299">"तकनीक/विज्ञान"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"लाइव चैनल"</item>
+ <item msgid="7307688057853449735">"सामग्री खोजने का एक आसान तरीका"</item>
+ <item msgid="7566838222783641942">"ऐप्स डाउनलोड करें, अधिक चैनल प्राप्त करें"</item>
+ <item msgid="8646630833216197238">"अपनी चैनल पंक्ति कस्टमाइज़ करना"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"अपने ऐप्स की सामग्री उसी तरह देखें जैसे आप टीवी पर चैनल देखते हैं."</item>
+ <item msgid="1855708984677953238">"परिचित मार्गदर्शिका और अनुकूल इंटरफ़ेस के साथ अपने ऐप्स की सामग्री ब्राउज़ करें, \nबिल्कुल टीवी पर चैनल एक्सेस करने की ही तरह."</item>
+ <item msgid="3420760668363283731">"लाइव चैनल प्रदान करने वाले ऐप्स इंस्टॉल करके अधिक चैनल जोड़ें. \nटीवी मेनू के भीतर स्थित लिंक का उपयोग करके Google Play स्टोर में संगत ऐप्स ढूंढ़ें."</item>
+ <item msgid="8974157841656828507">"अपनी चैनल सूची कस्टमाइज़ करने के लिए अपने नए इंस्टॉल किए गए चैनल स्रोत सेट करें. \nप्रारंभ करने के लिए सेटिंग मेनू के अंतर्गत चैनल स्रोत चुनें."</item>
+ </string-array>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index f9dd3614..53676212 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"चैनल सेटअप"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"अभिभावकीय नियंत्रण"</string>
- <string name="options_item_about" msgid="3023532413252052050">"संक्षिप्त विवरण"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"चैनल सेटअप"</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="channel_source_item_setup" msgid="1330441915487807542">"चैनल के स्रोत"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"नए चैनल उपलब्‍ध हैं"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"चैनल सूची कस्टमाइज़ करें"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"कार्यक्रम मार्गदर्शिका के लिए चैनल चुनें"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"सेट नहीं है"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d चैनल जोड़ा गया"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d चैनल जोड़े गए"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"आपने 5 बार गलत पिन डाला है.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकंड में पुनः प्रयास करें."</item>
- <item quantity="other" msgid="8829550842387756054">"आपने 5 बार गलत पिन डाला है.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकंड में पुनः प्रयास करें."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"संक्षिप्त विवरण"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ओपन सोर्स लाइसेंस"</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="about_menu_version" msgid="6303769835664868129">"वर्शन"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"वर्शन"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"डेवलपर विकल्प"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB टीवी ट्यूनर सक्षम करें"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB टीवी ट्यूनर की आवाज़ सुनने के लिए, आपके टीवी को AC3 पासथ्रू का समर्थन करना चाहिए."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"कोई शीर्षक नहीं"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"चैनल अवरोधित"</string>
<string name="episode_format" msgid="4881195874563241096">"क्रमांक<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"चैनल के स्रोत"</string>
- <string name="setup_description" msgid="8728423605912915099">"उपलब्ध स्रोतों से लाइव चैनल सेट अप करें. चैनल स्रोत के आधार पर इसमें कुछ मिनट लग सकते हैं."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"हो गया"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d चैनल उपलब्‍ध है"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d चैनल उपलब्‍ध हैं"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"अधिक स्रोत प्राप्‍त करें"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"ऐसे ऐप्‍स ब्राउज़ करें जो लाइव चैनल ऑफ़र करते हैं"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK कुंजी कनेक्ट किए गए डिवाइस के लिए है. बाहर निकलने के लिए HOME बटन दबाएं."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop वाले इस डिवाइस पर लाइव चैनल समर्थित नहीं है."</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>
</resources>
diff --git a/res/values-hr/arrays.xml b/res/values-hr/arrays.xml
index 93253b96..463686b8 100644
--- a/res/values-hr/arrays.xml
+++ b/res/values-hr/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premijere"</item>
<item msgid="8215762047341133299">"Tehnologija/znanost"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"TV kanali uživo"</item>
+ <item msgid="7307688057853449735">"Jednostavan način otkrivanja sadržaja"</item>
+ <item msgid="7566838222783641942">"Preuzmite aplikacije i gledajte više kanala"</item>
+ <item msgid="8646630833216197238">"Prilagodite svoj popis kanala"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Gledajte sadržaj iz aplikacija kao da gledate TV kanale."</item>
+ <item msgid="1855708984677953238">"Pregledavajte sadržaj iz aplikacija uz poznati vodič i ugodno sučelje, \nbaš kao kanale na televizoru."</item>
+ <item msgid="3420760668363283731">"Instalirajte aplikacije koje nude kanale uživo kako biste dodali više kanala. \nPronađite kompatibilne aplikacije u Trgovini Google Play putem veze na izborniku TV-a."</item>
+ <item msgid="8974157841656828507">"Postavite novoinstalirane izvore kanala da biste prilagodili popis kanala. \nOdaberite izvore kanala na izborniku Postavke da biste započeli."</item>
+ </string-array>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 4cf55e4c..196c79f6 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Postavljanje kanala"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Nadzor djece"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informacije"</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>
@@ -84,21 +83,16 @@
<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">"Grupiraj po"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Postavljanje kanala"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Program je blokiran"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="channel_source_item_setup" msgid="1330441915487807542">"Izvori kanala"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Dostupni su novi kanali"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Prilagodi popis"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Odaberite kanale za vodič kroz programe"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nije postavljen"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Postavke za titlove na razini sustava nisu pokrenute."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Dodan je %1$d kanal"</item>
- <item quantity="other" msgid="1078861616751739285">"Dodano je %1$d kanala"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Dodan je %1$d kanal</item>
+ <item quantity="few">Dodana su %1$d kanala</item>
+ <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>
@@ -136,16 +130,22 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Unesite novi PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Potvrdite PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Unesite trenutačni PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Unijeli ste pogrešan PIN 5 puta.\nPokušajte ponovo za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundu."</item>
- <item quantity="other" msgid="8829550842387756054">"Unijeli ste pogrešan PIN 5 puta.\nPokušajte ponovo za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Unijeli ste pogrešan PIN 5 puta.\nPokušajte ponovo za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundu.</item>
+ <item quantity="few">Unijeli ste pogrešan PIN 5 puta.\nPokušajte ponovo za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunde.</item>
+ <item quantity="other">Unijeli ste pogrešan PIN 5 puta.\nPokušajte ponovo za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundi.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informacije"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licence otvorenog izvornog koda"</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_menu_licenses" msgid="1257646083838406103">"Licence otvorenog izvornog koda"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licence otvorenog izvornog koda"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Verzija"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Verzija"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opcije za razvojne programere"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Omogući USB TV prijemnik"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Da biste mogli čuti zvuk USB TV prijemnika, vaš televizor mora podržavati AC3 prolaz."</string>
@@ -166,15 +166,22 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Bez naslova"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal blokiran"</string>
<string name="episode_format" msgid="4881195874563241096">"S. <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Izvori kanala"</string>
- <string name="setup_description" msgid="8728423605912915099">"Postavlja kanale uživo iz dostupnih izvora. To može potrajati nekoliko minuta ovisno o izvoru kanala."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Gotovo"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Dostupan je %1$d kanal"</item>
- <item quantity="other" msgid="2386588423841837714">"Broj dostupnih kanala: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Novi"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Izvori"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d kanal</item>
+ <item quantity="few">%1$d kanala</item>
+ <item quantity="other">%1$d kanala</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nema dostupnih kanala"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Novi"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nije postavljen"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Više izvora"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Pregledajte aplikacije koje nude kanale uživo"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Dostupni su novi izvori kanala"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Novi izvori kanala nude kanale.\nMožete ih postaviti odmah ili kasnije u postavkama izvora kanala."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Postavi sada"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Dobro, shvaćam"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Pritisnite ODABERITE"</b>" da biste pristupili izborniku TV-a."</string>
@@ -191,4 +198,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Tipka NATRAG namijenjena je za povezani uređaj. Pritisnite tipku POČETNA za izlaz."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Kanali uživo nisu podržani na ovom uređaju s Androidom Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Kanali uživo trebaju dopuštenje za čitanje TV unosa."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Postavite izvore"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"TV kanali uživo kombiniraju doživljaj tradicionalnih TV kanala sa strujanjem kanala koje nude aplikacije. \n\nDa biste započeli, postavite izvore kanala koji su već instalirani. U Trgovini Google Play možete potražiti još aplikacija koje nude kanale uživo."</string>
</resources>
diff --git a/res/values-hu/arrays.xml b/res/values-hu/arrays.xml
index cbc69895..3eba7e77 100644
--- a/res/values-hu/arrays.xml
+++ b/res/values-hu/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Technika/tudomány"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Élő csatornák"</item>
+ <item msgid="7307688057853449735">"Tartalomfelfedezés egyszerűen"</item>
+ <item msgid="7566838222783641942">"További csatornákért töltsön le alkalmazásokat"</item>
+ <item msgid="8646630833216197238">"Szabja személyre csatornalistáját"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Úgy nézhet tartalmakat alkalmazásaiból, mintha tévézne."</item>
+ <item msgid="1855708984677953238">"Ismerős műsorfüzet és barátságos felhasználói felület segítségével tallózhat az alkalmazástartalmak között, \nmintha csak a tévécsatornák között váltana."</item>
+ <item msgid="3420760668363283731">"Az élő csatornákat kínáló alkalmazások telepítésével új csatornákat adhat hozzá a kínálathoz. \nA tévé menüjében megjelenő link segítségével találhat kompatibilis alkalmazásokat a Google Play Áruházban."</item>
+ <item msgid="8974157841656828507">"A csatornalista személyre szabásához állítsa be az újonnan telepített csatornaforrásokat. \nA kezdéshez a Beállítások menüben válassza a Csatornaforrások lehetőséget."</item>
+ </string-array>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 4cd3f28b..da1e9520 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Csatornabeállítás"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Felügyelet"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Névjegy"</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>
@@ -84,21 +83,15 @@
<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">"Csoportosítás"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Csatornabeállítás"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"A műsor le van tiltva."</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="channel_source_item_setup" msgid="1330441915487807542">"Csatornaforrások"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Új rendelkezésre álló csatornák"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Listatestreszabás"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Válasszon csatornákat a műsorfüzetbe"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nincs beállítva"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Nem lehet elindítani a feliratok rendszerszintű beállításait."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d csatorna hozzáadva"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d csatorna hozzáadva"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d csatorna hozzáadva</item>
+ <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>
@@ -136,16 +129,21 @@
<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>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"5 alkalommal rosszul adta meg a PIN kódot.\nPróbálja újra <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> másodperc múlva."</item>
- <item quantity="other" msgid="8829550842387756054">"5 alkalommal rosszul adta meg a PIN kódot.\nPróbálja újra <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> másodperc múlva."</item>
- </plurals>
+ <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="side_panel_title_about" msgid="4572960435017168299">"Névjegy"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Nyílt forráskódú licencek"</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_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="about_menu_version" msgid="6303769835664868129">"Verzió"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Verzió"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Fejlesztői beállítások"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB-s tévétuner engedélyezése"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Ahhoz, hogy hallja az USB-s tévétuner hangját, a tévének támogatnia kell az AC3-átvitelt."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Nincs cím"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Csatorna letiltva"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>. évad, <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>. rész: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Csatornaforrások"</string>
- <string name="setup_description" msgid="8728423605912915099">"Élő csatornák beállítása az elérhető források alapján. Ez a csatornaforrástól függően néhány percig is eltarthat."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Kész"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d elérhető csatorna"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d elérhető csatorna"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Új"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Források"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d csatorna</item>
+ <item quantity="one">%1$d csatorna</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nincs elérhető csatorna"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Új"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nincs beállítva"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"További források"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Élő csatornákat szolgáltató alkalmazások tallózása"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Új csatornaforrások állnak rendelkezésre"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Új csatornaforrások új csatornákat kínálnak.\nBeállíthatja őket most, vagy később is megteheti a csatornaforrások beállításában."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Beállítás most"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Rendben, értem"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"A BACK gomb a csatlakoztatott eszközzel használható. A kilépéshez nyomja meg a HOME gombot."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Ezen az Android Lollipopot futtató eszközön nem támogatott az Élő csatornák alkalmazás."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Az Élő csatornák alkalmazásnak engedélyre van szüksége a tévéműsorok listázásának olvasásához."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Források beállítása"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Az Élő csatornák szolgáltatás a hagyományos tévézési élményt ötvözi az alkalmazások által kínált streamelhető csatornákkal. \n\nKezdésként állítsa be a már telepített csatornaforrásokat, vagy tallózzon a Google Play Áruházban az élő csatornákat kínáló alkalmazásokért."</string>
</resources>
diff --git a/res/values-hy-rAM/arrays.xml b/res/values-hy-rAM/arrays.xml
index 0c378758..5c6f0bfd 100644
--- a/res/values-hy-rAM/arrays.xml
+++ b/res/values-hy-rAM/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Նորույթներ"</item>
<item msgid="8215762047341133299">"Տեխնիկա/Գիտություն"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Ուղիղ եթեր"</item>
+ <item msgid="7307688057853449735">"Բովանդակության հայտնաբերման պարզ եղանակ"</item>
+ <item msgid="7566838222783641942">"Ներբեռնեք հավելվածներ, դիտեք էլ ավելի ալիքներ"</item>
+ <item msgid="8646630833216197238">"Անհատականացրեք ալիքների դասավորությունը"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Դիտեք բովանդակությունը հավելվածներից՝ ինչպես կդիտեիք հեռուստաալիքները հեռուստացույցի միջոցով:"</item>
+ <item msgid="1855708984677953238">"Հավելվածներից բովանդակությունը դիտեք հարմար ուղեցույցի և միջերեսի օգնությամբ՝ \nինչպես կդիտեիք հեռուստաալիքները հեռուստացույցի միջոցով:"</item>
+ <item msgid="3420760668363283731">"Ավելացրեք ալիքներ՝ ուղիղ եթեր առաջարկող հավելվածներ տեղադրելու միջոցով: \nGoogle Play Խանութում գտեք համատեղելի հավելվածներ հեռուստացույցի ընտրացանկում պարունակվող հղման օգնությամբ:"</item>
+ <item msgid="8974157841656828507">"Կարգավորեք նոր տեղադրած ալիքների աղբյուրները՝ ձեր ալիքների ցանկը անհատականացնելու համար: \nՍկսելու համար Կարգավորումների ընտրացանկում ընտրեք Ալիքների աղբյուրները:"</item>
+ </string-array>
</resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 064377cc..19d8a317 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Կարգավորում"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ծնողական հսկում"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Ընտրանքի մասին"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Կարգավորում"</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="channel_source_item_setup" msgid="1330441915487807542">"Ալիքի աղբյուրները"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Նոր ալիքներ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Հարմարեցնել ցանկը"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Ընտրեք կապուղիներ ձեր ուղեցույցի համար"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Կարգավորված չէ"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ալիք ավելացվեց"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ալիք ավելացվեց"</item>
- </plurals>
+ <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>
@@ -136,20 +129,25 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PIN կոդը 5 անգամ սխալ է մուտքագրվել:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> վայրկյանից:"</item>
- <item quantity="other" msgid="8829550842387756054">"PIN կոդը 5 անգամ սխալ է մուտքագրվել:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> վայրկյանից:"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Ընտրանքի մասին"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Բաց կոդով ծրագրաշարի լիցենզիաներ"</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="about_menu_version" msgid="6303769835664868129">"Տարբերակ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Տարբերակ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Մշակողի ընտրանքներ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Միացնել USB հեռուստակարգավորիչը"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB հեռուստակարգավորիչի ձայնը լսելու համար անհրաժեշտ է, որ ձեր հեռուստացույցն աջակցի AC3 տարանցումը:"</string>
- <string name="developer_menu_ac3_support" msgid="8542930057443915670">"AC3-ի աուդիո հնարավորությունները"</string>
+ <string name="developer_menu_ac3_support" msgid="8542930057443915670">"AC3 ձայնի աջակցում"</string>
<string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"Ձեր հեռուստացույցն աջակցում է AC3 տարանցումը:"</string>
<string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"Ձեր հեռուստացույցը չի աջակցում AC3 տարանցումը:"</string>
<string name="about_menu_improve" msgid="3712578027009311401">"Օգնել բարելավել «Ուղիղ եթերը»"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Անվերնագիր"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Ալիքն արգելափակված է"</string>
<string name="episode_format" msgid="4881195874563241096">"Ս<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Դրվ.՝ <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Ալիքների աղբյուրներ"</string>
- <string name="setup_description" msgid="8728423605912915099">"Ուղիղ եթերի ալիքների կարգավորում: Սա կարող է մի քանի րոպե տևել՝ կախված ալիքի աղբյուրից:"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Պատրաստ է"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ալիք"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ալիք"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Ավելացնել այլ աղբյուրներ"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Որոնեք ուղիղ եթեր առաջարկող հավելվածներ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"«Հետ» կոճակը միացված սարքի համար է: Դուս գալու համար սեղմեք «Գլխավոր» կոճակը:"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Ուղիղ եթերը չի աջակցվում Android Lollipop համակարգով սարքի վրա:"</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>
</resources>
diff --git a/res/values-in/arrays.xml b/res/values-in/arrays.xml
index 50fee494..1248c942 100644
--- a/res/values-in/arrays.xml
+++ b/res/values-in/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Tayang Perdana"</item>
<item msgid="8215762047341133299">"Teknologi/Sains"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Saluran TV Langsung"</item>
+ <item msgid="7307688057853449735">"Cara sederhana untuk menemukan konten"</item>
+ <item msgid="7566838222783641942">"Unduh aplikasi, dapatkan lebih banyak saluran"</item>
+ <item msgid="8646630833216197238">"Sesuaikan urutan saluran Anda"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Tonton konten dari aplikasi Anda seperti menonton saluran di TV."</item>
+ <item msgid="1855708984677953238">"Jelajahi konten dari aplikasi dengan panduan yang familier dan antarmuka yang ramah, \nseperti saluran di TV."</item>
+ <item msgid="3420760668363283731">"Tambahkan lebih banyak saluran dengan memasang aplikasi yang menawarkan saluran TV langsung. \nTemukan aplikasi yang kompatibel di Google Play Store dengan menggunakan tautan dalam menu TV."</item>
+ <item msgid="8974157841656828507">"Siapkan sumber saluran yang baru terpasang untuk menyesuaikan daftar saluran Anda. \nPilih sumber Saluran dalam menu Setelan untuk memulai."</item>
+ </string-array>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 4a504ccc..82fbd5c9 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Siapkan saluran"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Kontrol induk"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Tentang"</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>
@@ -84,21 +83,15 @@
<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">"Kelompokkan menurut"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Penyiapan saluran"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Program ini diblokir"</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="channel_source_item_setup" msgid="1330441915487807542">"Sumber saluran"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Tersedia saluran baru"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Sesuaikan daftar saluran"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Pilih saluran untuk panduan program"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Belum disiapkan"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Tidak dapat memulai preferensi seluruh sistem untuk teks."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d saluran ditambahkan"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d saluran ditambahkan"</item>
- </plurals>
+ <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">"Tidak ditambahkan saluran"</string>
<string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Kontrol induk"</string>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Masukkan PIN baru"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Konfirmasikan PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Masukkan PIN saat ini"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Anda salah memasukkan PIN sebanyak 5 kali.\nCoba lagi dalam <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> detik."</item>
- <item quantity="other" msgid="8829550842387756054">"Anda salah memasukkan PIN sebanyak 5 kali.\nCoba lagi dalam <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> detik."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Anda 5 kali salah memasukkan PIN.\nCoba lagi dalam <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> detik.</item>
+ <item quantity="one">Anda 5 kali salah memasukkan PIN.\nCoba lagi dalam <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> detik.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Tentang"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Lisensi sumber terbuka"</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="about_menu_version" msgid="6303769835664868129">"Versi"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versi"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opsi pengembang"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Aktifkan penala TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Untuk mendengar suara penala TV USB, TV Anda harus mendukung passthrough AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Tanpa judul"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Saluran diblokir"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Sumber saluran"</string>
- <string name="setup_description" msgid="8728423605912915099">"Menyiapkan saluran siaran langsung dari sumber yang tersedia. Proses ini mungkin perlu waktu beberapa menit bergantung pada sumber saluran."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Selesai"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Tersedia %1$d saluran"</item>
- <item quantity="other" msgid="2386588423841837714">"Tersedia %1$d saluran"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Baru"</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">"Tidak ada saluran yang tersedia"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Baru"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Belum disiapkan"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Dapatkan sumber lainnya"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Jelajahi aplikasi yang menawarkan saluran TV langsung"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Sumber saluran baru tersedia"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Sumber saluran baru menawarkan saluran.\nSiapkan sekarang atau nanti di setelan sumber saluran."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Siapkan sekarang"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Oke, mengerti"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Tekan PILIH"</b>" untuk mengakses menu TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Tombol KEMBALI adalah untuk perangkat yang tersambung. Tekan tombol UTAMA untuk keluar."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Saluran Langsung tidak didukung pada perangkat dengan Android Lollipop ini."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Saluran Langsung membutuhkan izin untuk membaca cantuman TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Siapkan sumber Anda"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Saluran TV langsung menggabungkan pengalaman saluran TV tradisional dengan saluran streaming yang disediakan aplikasi. \n\nMulailah dengan menyiapkan sumber saluran yang telah terpasang. Atau jelajahi Google Play Store untuk menemukan aplikasi lain yang menawarkan saluran TV langsung."</string>
</resources>
diff --git a/res/values-is-rIS/arrays.xml b/res/values-is-rIS/arrays.xml
index 3683481b..27cb8655 100644
--- a/res/values-is-rIS/arrays.xml
+++ b/res/values-is-rIS/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Úrvalsefni"</item>
<item msgid="8215762047341133299">"Tækni og vísindi"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Beinar útsendingar"</item>
+ <item msgid="7307688057853449735">"Einföld leið til að uppgötva nýtt efni"</item>
+ <item msgid="7566838222783641942">"Sæktu forrit, fáðu fleiri rásir"</item>
+ <item msgid="8646630833216197238">"Breyttu uppröðun rása eftir þínu höfði"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Horfðu á efni úr forritunum þínum eins og þú sért að horfa á sjónvarpið."</item>
+ <item msgid="1855708984677953238">"Flettu í gegnum efni úr forritunum þínum með þægilegri leiðsögn og vinalegu notandaviðmóti, \nalveg eins og þú sért að skipta milli sjónvarpsrása."</item>
+ <item msgid="3420760668363283731">"Bættu við fleiri rásum með því að setja upp forrit sem bjóða upp á beinar útsendingar. \nFinndu samhæfð forrit í Google Play Store með því að nota tengilinn í sjónvarpsvalmyndinni."</item>
+ <item msgid="8974157841656828507">"Settu upp nýlega sótt inntök rása til að raða rásalistanum eftir eigin höfði. \nVeldu Inntak rása í stillingavalmyndinni til að hefjast handa."</item>
+ </string-array>
</resources>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index ffd0d35b..e18a3139 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Uppsetning rása"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Foreldraeftirlit"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Um"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Uppsetning rása"</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="channel_source_item_setup" msgid="1330441915487807542">"Inntak rása"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nýjar rásir í boði"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Sérsníða rásalista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Veldu rásir fyrir dagskrárvísinn þinn"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Ekki uppsett"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d rás bætt við"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d rásum bætt við"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Þú slóst inn rangt PIN-númer fimm sinnum. \nReyndu aftur eftir <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekúndu."</item>
- <item quantity="other" msgid="8829550842387756054">"Þú slóst inn rangt PIN-númer fimm sinnum.\nReyndu aftur eftir <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekúndur."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Um"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Leyfi opins kóða"</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="about_menu_version" msgid="6303769835664868129">"Útgáfa"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Útgáfa"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Forritunarkostir"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Virkja USB-sjónvarpsmóttakara"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Til að það heyrist í USB-sjónvarpsmóttakaranum þarf sjónvarpið þitt að styðja AC3-tengingu."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Þ. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Inntak rása"</string>
- <string name="setup_description" msgid="8728423605912915099">"Setja upp rásir í beinni frá tiltæku inntaki. Þetta getur tekið nokkrar mínútur, allt eftir því hvaðan rásin er upprunnin."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Lokið"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d rás í boði"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d rásir í boði"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Sækja fleiri veitur"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Rásir í beinni eru ekki studdar í þessu tæki með Android Lollipop."</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>
</resources>
diff --git a/res/values-it/arrays.xml b/res/values-it/arrays.xml
index 21ac42c4..8dd12954 100644
--- a/res/values-it/arrays.xml
+++ b/res/values-it/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Il meglio"</item>
<item msgid="8215762047341133299">"Scienza/tecnica"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Dirette TV"</item>
+ <item msgid="7307688057853449735">"Un modo facile per trovare contenuti"</item>
+ <item msgid="7566838222783641942">"Scarica app e trova altri canali"</item>
+ <item msgid="8646630833216197238">"Personalizza il tuo elenco canali"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Guarda i contenuti dalle tue app nello stesso modo in cui guardi i programmi alla TV."</item>
+ <item msgid="1855708984677953238">"Consulta i contenuti delle tue app con una guida familiare e un\'interfaccia facile da utilizzare, \nproprio come i programmi alla TV."</item>
+ <item msgid="3420760668363283731">"Aggiungi altri canali installando app di dirette TV. \nTrova app compatibili nel Google Play Store utilizzando il link disponibile nel menu TV."</item>
+ <item msgid="8974157841656828507">"Configura le tue fonti di canali appena installate per personalizzare il tuo elenco di canali. \nInnanzitutto, scegli le fonti di canali nel menu Impostazioni."</item>
+ </string-array>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index c22a1bf4..3310209d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Impostaz. canale"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Controllo genitori"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informazioni"</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>
@@ -65,7 +64,7 @@
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canale bloccato"</string>
<string name="default_language" msgid="4122326459624337928">"Lingua sconosciuta"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sottotitoli"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Non attivi"</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="side_panel_title_display_mode" msgid="6346286034015991229">"Visualizzazione"</string>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Alta definizione"</string>
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Impostaz. canale"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Questo programma è bloccato"</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="channel_source_item_setup" msgid="1330441915487807542">"Fonti canali"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nuovi canali disponibili"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Personalizza canali"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Scegli canali per guida ai programmi"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Non configurato"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Impossibile avviare le preferenze su tutto il sistema per i sottotitoli."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d canale aggiunto"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d canali aggiunti"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d canali aggiunti</item>
+ <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>
@@ -138,16 +131,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Inserisci il nuovo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Conferma il PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Inserisci il PIN attuale"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Hai inserito cinque volte il PIN sbagliato.\nRiprova tra <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> secondo."</item>
- <item quantity="other" msgid="8829550842387756054">"Hai inserito cinque volte il PIN sbagliato.\nRiprova tra <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> secondi."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Hai inserito per cinque volte il PIN sbagliato.\nRiprova fra <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> secondi.</item>
+ <item quantity="one">Hai inserito per cinque volte il PIN sbagliato.\nRiprova fra <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> secondo.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informazioni"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licenze open source"</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_menu_licenses" msgid="1257646083838406103">"Licenze open source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licenze open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versione"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versione"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opzioni sviluppatore"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Attiva sintonizzatore TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Per ascoltare l\'audio del sintonizzatore TV USB, la TV deve supportare il passthrough AC3."</string>
@@ -168,15 +166,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Senza titolo"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canale bloccato"</string>
<string name="episode_format" msgid="4881195874563241096">"Stag. <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Punt. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fonti canale"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configura Live TV dalle fonti disponibili. L\'operazione potrebbe richiedere diversi minuti a seconda della fonte del canale."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Fine"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canale disponibile"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canali disponibili"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nuove"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Fonti"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d canali</item>
+ <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_setup_now" msgid="1772000402336958967">"Non configurato"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Trova altre fonti"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Trova app che offrono dirette TV"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nuove fonti di canali disponibili"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Nuove fonti con canali disponibili.\nConfigurale ora o più tardi nell\'impostazione Fonti canali."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configura ora"</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>"Premi SELEZIONA"</b>" per accedere al menu della TV."</string>
@@ -193,4 +197,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Live TV non è supportato su questo dispositivo con Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live 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>
</resources>
diff --git a/res/values-iw/arrays.xml b/res/values-iw/arrays.xml
index ea2ed7b6..17a73776 100644
--- a/res/values-iw/arrays.xml
+++ b/res/values-iw/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"עילית"</item>
<item msgid="8215762047341133299">"טכנולוגיה/מדע"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ערוצי שידורים חיים"</item>
+ <item msgid="7307688057853449735">"דרך פשוטה לגלות תוכן"</item>
+ <item msgid="7566838222783641942">"הורדת אפליקציות וקבלת ערוצים נוספים"</item>
+ <item msgid="8646630833216197238">"התאמה אישית של רשימת הערוצים"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"צפייה בתוכן מהאפליקציות כמו צפייה בערוצי טלוויזיה."</item>
+ <item msgid="1855708984677953238">"דפדוף בתוכן מהאפליקציות בעזרת מדריך מוכר וממשק ידידותי, \nבדיוק כמו בערוצי טלוויזיה."</item>
+ <item msgid="3420760668363283731">"‏הוספת ערוצים על ידי התקנת אפליקציות המציעות ערוצי שידורים חיים. \nתוכל למצוא אפליקציות תואמות בחנות Google Play על ידי לחיצה על הקישור שבתפריט הטלוויזיה."</item>
+ <item msgid="8974157841656828507">"הגדרה של מקורות הערוצים החדשים שהותקנו לצורך התאמה אישית של רשימת הערוצים. \nכדי להתחיל, בחר את מקורות הערוצים בתפריט ההגדרות."</item>
+ </string-array>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index e616b71a..7ef93abc 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"הגדרת ערוץ"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"בקרות הוריות"</string>
- <string name="options_item_about" msgid="3023532413252052050">"מידע כללי"</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>
@@ -84,21 +83,17 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"הגדרת ערוץ"</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="channel_source_item_setup" msgid="1330441915487807542">"מקורות של ערוצים"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"ערוצים חדשים זמינים"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"התאם רשימת ערוצים"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"בחר ערוצים עבור מדריך התכניות שלך"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"לא מוגדר"</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">
- <item quantity="one" msgid="6074059986849579215">"‏ערוץ %1$d נוסף"</item>
- <item quantity="other" msgid="1078861616751739285">"‏%1$d ערוצים נוספו"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="two">‏נוספו %1$d ערוצים</item>
+ <item quantity="many">‏נוספו %1$d ערוצים</item>
+ <item quantity="other">‏נוספו %1$d ערוצים</item>
+ <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>
@@ -136,17 +131,24 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"‏הזנת PIN שגוי חמש פעמים.\nנסה שוב בעוד שנייה <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- <item quantity="other" msgid="8829550842387756054">"‏הזנת PIN שגוי חמש פעמים.\nנסה שוב בעוד <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> שניות."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="two">‏הוזן קוד PIN שגוי חמש פעמים.\nנסה שוב בעוד <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> שניות.</item>
+ <item quantity="many">‏הוזן קוד PIN שגוי חמש פעמים.\nנסה שוב בעוד <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> שניות.</item>
+ <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">"נסה שוב, קוד האימות אינו תואם"</string>
- <string name="side_panel_title_about" msgid="4572960435017168299">"מידע כללי"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"רישיונות קוד פתוח"</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="about_menu_version" msgid="6303769835664868129">"גרסה"</string>
- <string name="side_panel_title_developer" msgid="7287627759979090359">"אפשרויות מפתח"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"גרסה"</string>
+ <string name="side_panel_title_developer" msgid="7287627759979090359">"אפשרויות למפתחים"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"‏הפעל את טיונר ה-USB שבטלוויזיה"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"‏כדי לשמוע צליל מטיונר ה-USB בטלוויזיה, יש צורך בתמיכה בחיבור AC3 בטלוויזיה."</string>
<string name="developer_menu_ac3_support" msgid="8542930057443915670">"‏יכולת אודיו מסוג AC3"</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ללא כותרת"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"הערוץ חסום"</string>
<string name="episode_format" msgid="4881195874563241096">"עונה <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: פרק <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"מקורות של ערוצים"</string>
- <string name="setup_description" msgid="8728423605912915099">"הגדרה של ערוצים בשידור חי מהמקורות הזמינים. התהליך עשוי לארוך מספר דקות, בהתאם למקור הערוץ."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"בוצע"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"‏יש ערוץ %1$d זמין"</item>
- <item quantity="other" msgid="2386588423841837714">"‏יש %1$d ערוצים זמינים"</item>
- </plurals>
+ <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="two">‏%1$d ערוצים</item>
+ <item quantity="many">‏%1$d ערוצים</item>
+ <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_play_store_action_title" msgid="859347291072224673">"קבל מקורות נוספים"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"עיין באפליקציות שמציעות ערוצי שידורים חיים"</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>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"מקש \'הקודם\' מיועד למכשירים מחוברים. לחץ על לחצן \'דף הבית\' כדי לצאת."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"‏Live TV אינו נתמך במכשיר זה עם Android Lollipop."</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>
</resources>
diff --git a/res/values-ja/arrays.xml b/res/values-ja/arrays.xml
index 6fe04daa..12d3b91a 100644
--- a/res/values-ja/arrays.xml
+++ b/res/values-ja/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"プレミア"</item>
<item msgid="8215762047341133299">"科学、技術"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ライブ チャンネル"</item>
+ <item msgid="7307688057853449735">"コンテンツを手軽に検索"</item>
+ <item msgid="7566838222783641942">"アプリのダウンロードでさらにチャンネルを追加"</item>
+ <item msgid="8646630833216197238">"チャンネルのラインアップをカスタマイズ可能"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"テレビでチャンネルを視聴するようにアプリからコンテンツを視聴できます。"</item>
+ <item msgid="1855708984677953238">"テレビでチャンネルを視聴するように、アプリから慣れ親しんだガイドやインターフェースを使って\nコンテンツを探せます。"</item>
+ <item msgid="3420760668363283731">"ライブ チャンネルを提供するアプリをインストールすると、さらにチャンネルを増やせます。\nテレビのメニューでリンクを使用して Google Play ストアにある対応アプリを探せます。"</item>
+ <item msgid="8974157841656828507">"新しくインストールしたチャンネル ソースをセットアップしてチャンネル リストをカスタマイズできます。\n使ってみるには [設定] メニューでチャンネル ソースを選択します。"</item>
+ </string-array>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index a764b912..626948fa 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"チャンネル設定"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"ペアレンタルコントロール"</string>
- <string name="options_item_about" msgid="3023532413252052050">"概要"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"チャンネル設定"</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="channel_source_item_setup" msgid="1330441915487807542">"チャンネルソース"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"利用できる新しいチャンネル"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"チャンネルリストをカスタマイズ"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"プログラムガイド用のチャンネルを選択"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"セットアップしていません"</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">
- <item quantity="one" msgid="6074059986849579215">"チャンネル%1$d件が追加済み"</item>
- <item quantity="other" msgid="1078861616751739285">"チャンネル%1$d件が追加済み"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PINの入力を5回間違えました。\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>秒後にもう一度お試しください。"</item>
- <item quantity="other" msgid="8829550842387756054">"PINの入力を5回間違えました。\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>秒後にもう一度お試しください。"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"概要"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"オープンソースライセンス"</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="about_menu_version" msgid="6303769835664868129">"バージョン"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"バージョン"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"開発者向けオプション"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB テレビ チューナーを有効にする"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB テレビ チューナーの音声を再生するには、お使いのテレビが AC3 パススルーに対応している必要があります。"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"タイトルなし"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"チャンネルをブロック"</string>
<string name="episode_format" msgid="4881195874563241096">"シーズン<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: エピソード<xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>「<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>」"</string>
- <string name="setup_title" msgid="7268875010986705651">"チャンネルソース"</string>
- <string name="setup_description" msgid="8728423605912915099">"有効なソースからライブチャンネルを設定します。チャンネルソースによっては数分かかる場合があります。"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"完了"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d件のチャンネルがあります"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d件のチャンネルがあります"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"その他のソース"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"ライブ チャンネルを利用できるアプリを探します"</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">"OK"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307">"テレビのメニューにアクセスするには"<b>"[SELECT]を押してください"</b>"。"</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"戻るキーは接続されたデバイス用です。終了するにはホームボタンを押してください。"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"ライブチャンネルは、Android Lollipopを搭載するこの端末では利用できません。"</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>
</resources>
diff --git a/res/values-ka-rGE/arrays.xml b/res/values-ka-rGE/arrays.xml
index 2e6ba0f8..1d6659a6 100644
--- a/res/values-ka-rGE/arrays.xml
+++ b/res/values-ka-rGE/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"პრემიერა"</item>
<item msgid="8215762047341133299">"ტექნოლოგიები/მეცნიერება"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"პირდაპირი არხები"</item>
+ <item msgid="7307688057853449735">"კონტენტის აღმოჩენის მარტივი ხერხი"</item>
+ <item msgid="7566838222783641942">"ჩამოტვირთეთ აპები და მიიღეთ მეტი არხი"</item>
+ <item msgid="8646630833216197238">"მოირგეთ არხების მიმდევრობა"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"უყურეთ კონტენტს თქვენი აპებიდან სატელევიზიო არხების მსგავსად."</item>
+ <item msgid="1855708984677953238">"დაათვალიერეთ კონტენტი თქვენი აპებიდან სატელევიზიო არხების მსგავსად, \nჩვეული მეგზურისა და მეგობრული ინტერფეისის მეშვეობით."</item>
+ <item msgid="3420760668363283731">"დაამატეთ მეტი არხი — დააინსტალირეთ აპები, რომლებიც პირდაპირ არხებს გთავაზობთ. \nთავსებადი აპების საპოვნელად გამოიყენეთ TV-ს მენიუში მოცემული ბმული, რომელიც Google Play Store-ზე გადაგიყვანთ."</item>
+ <item msgid="8974157841656828507">"არხების სიის მოსარგებად, დააყენეთ არხების ახლადდაინსტალირებული წყაროები. \nდასაწყებად, პარამეტრების მენიუში აირჩიეთ არხების წყაროები."</item>
+ </string-array>
</resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 76696729..5b58347b 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"არხის დაყენება"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"მშობელთა კონტრ."</string>
- <string name="options_item_about" msgid="3023532413252052050">"შესახებ"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"არხის დაყენება"</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="channel_source_item_setup" msgid="1330441915487807542">"არხების წყაროები"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"ხელმისაწვდომია ახალი არხები"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"არხ. სიის მორგება"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"აირჩიეთ არხები პროგრამის გზამკვლევისთვის"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"არ არის დაყენებული"</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">
- <item quantity="one" msgid="6074059986849579215">"დაემატა %1$d არხი"</item>
- <item quantity="other" msgid="1078861616751739285">"დაემატა %1$d არხი"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"თქვენ შეიყვანეთ არასწორი PIN ხუთჯერ.\nკიდევ სცადეთ <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> წამში."</item>
- <item quantity="other" msgid="8829550842387756054">"თქვენ შეიყვანეთ არასწორი PIN ხუთჯერ.\nკიდევ სცადეთ <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> წამში."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"შესახებ"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ღია კოდის ლიცენზიები"</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="about_menu_version" msgid="6303769835664868129">"ვერსია"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ვერსია"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"დეველოპერთა პარამეტრები"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV-ტუნერის ჩართვა"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV-ტუნერის ხმის მოსასმენად, თქვენი ტელევიზორის მიერ მხარდაჭერილი უნდა იყოს AC3 აუდიოს გატარება."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"უსათაურო"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"არხი დაბლოკილია"</string>
<string name="episode_format" msgid="4881195874563241096">"სეზ.<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ეპ. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"არხების წყაროები"</string>
- <string name="setup_description" msgid="8728423605912915099">"დააყენეთ პირდაპირი არხები ხელმისაწვდომი წყაროებიდან. ამას შეიძლება რამდენიმე წუთი დასჭირდეს, არხის წყაროს მიხედვით."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"დასრულდა"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"ხელმისაწვდომია %1$d არხი"</item>
- <item quantity="other" msgid="2386588423841837714">"ხელმისაწვდომია %1$d არხი"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"მეტი წყაროს მიღება"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"დაათვალიერეთ აპები, რომლებიც პირდაპირ არხებს გთავაზობთ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"ღილაკი „უკან“ დაკავშირებული მოწყობილობისთვისაა. გამოსასვლელად დააჭირეთ ღილაკს „მთავარი“."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"პირდაპირი არხები არ არის მხარდაჭერილი ამ მოწყობილობაზე Android Lollipop-ით."</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>
</resources>
diff --git a/res/values-kk-rKZ/arrays.xml b/res/values-kk-rKZ/arrays.xml
index f1f1a16e..bbb0282c 100644
--- a/res/values-kk-rKZ/arrays.xml
+++ b/res/values-kk-rKZ/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Премьера"</item>
<item msgid="8215762047341133299">"Технология/ғылым"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live арналары"</item>
+ <item msgid="7307688057853449735">"Мазмұнды табудың оңай жолы"</item>
+ <item msgid="7566838222783641942">"Қолданбаларды жүктеп, көбірек арналарды алу"</item>
+ <item msgid="8646630833216197238">"Арналар қатарын реттеу"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Бейнелерді қолданбадан теледидар арналарын көргендей тамашалаңыз."</item>
+ <item msgid="1855708984677953238">"Арналарды теледидардан көргендей, бейнелерді нұсқаулығы таныс әрі \nинтерфейсі ыңғайлы қолданбадан шолыңыз."</item>
+ <item msgid="3420760668363283731">"Тікелей эфир арналарын ұсынатын қолданбаларды орнату арқылы арналар санын арттырыңыз. \nТеледидар мәзіріндегі сілтемені пайдаланып Google Play Store дүкенінен үйлесімді қолданбаларды табыңыз."</item>
+ <item msgid="8974157841656828507">"Жаңадан орнатылған арна көздерінен тізім құрыңыз. \nОл үшін \"Параметрлер\" мәзірінен \"Арна көздері\" тармағын таңдаңыз."</item>
+ </string-array>
</resources>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 8218ade9..79833b29 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Арнаны реттеу"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ата-аналық бақылау"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Ақпарат"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Арнаны реттеу"</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="channel_source_item_setup" msgid="1330441915487807542">"Арна көздері"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Жаңа арналар қосылды"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Арналар тіз. тең."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Бағ-лар нұсқаулығы үшін арналарды таңдау"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Реттелмеген"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d арна қосылды"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d арна қосылды"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Қате PIN кодын 5 рет енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</item>
- <item quantity="other" msgid="8829550842387756054">"Қате PIN кодын 5 рет енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Ақпарат"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Ашық бастапқы код лицензиялары"</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="about_menu_version" msgid="6303769835664868129">"Нұсқа"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Нұсқа"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Әзірлеуші опциялары"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB ТД тюнерін қосу"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB ТД тюнерінің дауысын есіту үшін теледидар AC3 транзиттік өткізуді қолдауы тиіс."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Тақырыпсыз"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Арна бөгелген"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>-маусым: <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>-эпизод <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Арна көздері"</string>
- <string name="setup_description" msgid="8728423605912915099">"Қолжетімді көздерден тікелей эфирдегі арналарды реттеңіз. Арна көзіне байланысты бұған бірнеше минут кетуі мүмкін."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Орындалды"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d арна қолжетімді"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d арна қолжетімді"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Қосымша дереккөздерді алу"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Тікелей эфир арналарын ұсынатын қолданбаларды шолу"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"КЕРІ пернесі қосылған құрылғыға арналған. Шығу үшін НЕГІЗГІ пернесін басыңыз."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop жүйесі орнатылған құрылғыларда Live TV қолданбасына қолдау көрсетілмейді."</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>
</resources>
diff --git a/res/values-km-rKH/arrays.xml b/res/values-km-rKH/arrays.xml
index 9b2076e0..e46312b4 100644
--- a/res/values-km-rKH/arrays.xml
+++ b/res/values-km-rKH/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"បង្ហាញជូនលើដំបូង"</item>
<item msgid="8215762047341133299">"បច្ចេក/វិទ្យាសាស្ត្រ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់"</item>
+ <item msgid="7307688057853449735">"មធ្យោបាយសាមញ្ញក្នុងការស្វែងរកមាតិកា"</item>
+ <item msgid="7566838222783641942">"ដោនឡូតកម្មវិធីដើម្បីទទួលបានប៉ុស្តិ៍បន្ថែមទៀត"</item>
+ <item msgid="8646630833216197238">"កំណត់បណ្តុំប៉ុស្តិ៍របស់អ្នកតាមបំណង"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"មើលមាតិកាបានមកពីកម្មវិធីរបស់អ្នក ដូចជាការមើលប៉ុស្តិ៍នៅលើទូរទស្សន៍។"</item>
+ <item msgid="1855708984677953238">"រុករកមាតិកាបានមកពីកម្មវិធីរបស់អ្នកដែលមានការណែនាំដែលធ្លាប់ស្គាល់ និងចំណុចប្រទាក់ដែលស្រួលសម្រាប់អ្នកប្រើ \nដូចជាប៉ុស្តិ៍ទូរទស្សន៍ជាដើម។"</item>
+ <item msgid="3420760668363283731">"បន្ថែមប៉ុស្តិ៍ច្រើនទៀតដោយដំឡើងកម្មវិធីដែលផ្តល់ប៉ុស្តិ៍ផ្សាយផ្ទាល់។ \nស្វែងរកកម្មវិធីដែលត្រូវគ្នានៅក្នុងហាង Google Play ដោយប្រើតំណនៅក្នងម៉ឺនុយទូរទស្សន៍។"</item>
+ <item msgid="8974157841656828507">"កំណត់ប្រភពប៉ុស្តិ៍ដែលអ្នកទើបដំឡើងថ្មីៗដើម្បីកំណត់បញ្ជីប៉ុស្តិ៍របស់អ្នកជាលក្ខណៈផ្ទាល់ខ្លួន។ \nដើម្បីចាប់ផ្តើម សូមជ្រើសប្រភពប៉ុស្តិ៍ដែលមានក្នុងមឺុនុយការកំណត់។"</item>
+ </string-array>
</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 9c5ba787..e0ba7b53 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ការដំឡើងប៉ុស្តិ៍"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"ការពិនិត្យរបស់ឪពុកម្ដាយ"</string>
- <string name="options_item_about" msgid="3023532413252052050">"អំពី"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ការដំឡើងប៉ុស្តិ៍"</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="channel_source_item_setup" msgid="1330441915487807542">"ប្រភពប៉ុស្តិ៍"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"មានប៉ុស្តិ៍ថ្មី"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ប្ដូរបញ្ជីឆានែលតាមបំណង"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"ជ្រើស​ឆានែល​សម្រាប់​ការណែនាំ​កម្មវិធី"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"មិន​បាន​កំណត់"</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">
- <item quantity="one" msgid="6074059986849579215">"បាន​បន្ថែម​ឆានែល %1$d"</item>
- <item quantity="other" msgid="1078861616751739285">"បាន​បន្ថែម​ឆានែល %1$d"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"អ្នកបានបញ្ចូលកូដ PIN ខុស ៥ដង។\nព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> វិនាទីទៀត។"</item>
- <item quantity="other" msgid="8829550842387756054">"អ្នកបានបញ្ចូលកូដ PIN ខុស ៥ដង។\nព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> វិនាទីទៀត។"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"អំពី"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"អាជ្ញាប័ណ្ណប្រភពកូដចំហ"</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="about_menu_version" msgid="6303769835664868129">"កំណែ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"កំណែ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ជម្រើស​សម្រាប់​​អ្នក​អភិវឌ្ឍ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"បើកដំណើរការឧបករណ៍ចាប់ប៉ុស្តិ៍ទូរទស្សន៍ USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"ដើម្បីឮសំឡេងឧបករណ៍ចាប់ប៉ុស្តិ៍ទូរទស្សន៍ USB ទូរទស្សន៍របស់អ្នកគួរតែអាចគាំទ្ររន្ធដោត AC3។"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"គ្មាន​ចំណងជើង"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"បាន​ទប់​ស្កាត់​ឆានែល"</string>
<string name="episode_format" msgid="4881195874563241096">"រដូវកាល <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>៖ វគ្គ <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ប្រភពប៉ុស្តិ៍"</string>
- <string name="setup_description" msgid="8728423605912915099">"ដំឡើងប៉ុស្តិ៍ផ្សាយផ្ទាល់ចេញពីប្រភពដែលមានផ្តល់ជូន។ វាអាចចំណាយពេលប៉ុន្មាននាទីអាស្រ័យលើប្រភពរបស់ប៉ុស្តិ៍នោះ។"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"រួចរាល់"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"មានប៉ុស្តិ៍ %1$d"</item>
- <item quantity="other" msgid="2386588423841837714">"មានប៉ុស្តិ៍ %1$d"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"ទទួលយកប្រភពច្រើនទៀត"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"រុករកកម្មវិធីដែលមានផ្តល់ជូនប៉ុស្តិ៍ផ្សាយផ្ទាល់"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"ប៊ូតុង​ថយក្រោយ​សម្រាប់​ឧបករណ៍​ដែល​បាន​ភ្ជាប់។ ចុច​ប៊ូតុង​ដើម ដើម្បី​ចាកចេញ។"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់មិនត្រូវបានគាំទ្រលើឧបករណ៍ដែលដំណើរការដោយ Android Lollipop នេះទេ។"</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>
</resources>
diff --git a/res/values-kn-rIN/arrays.xml b/res/values-kn-rIN/arrays.xml
index 9e3fa48a..1b1c650f 100644
--- a/res/values-kn-rIN/arrays.xml
+++ b/res/values-kn-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ಪ್ರೀಮಿಯರ್"</item>
<item msgid="8215762047341133299">"ತಂತ್ರಜ್ಞಾನ/ವಿಜ್ಞಾನ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ಲೈವ್‌ ಚಾನಲ್‌ಗಳು"</item>
+ <item msgid="7307688057853449735">"ವಿಷಯವನ್ನು ಶೋಧಿಸಲು ಸರಳ ಮಾರ್ಗ"</item>
+ <item msgid="7566838222783641942">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ, ಹೆಚ್ಚು ಚಾನಲ್‌ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</item>
+ <item msgid="8646630833216197238">"ನಿಮ್ಮ ಚಾನಲ್‌ ಲೈನ್‌-ಅಪ್‌ ಕಸ್ಟಮೈಸ್‌ ಮಾಡಿ"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"ಟಿವಿಯಲ್ಲಿ ಚಾನಲ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸುವ ಹಾಗೆ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಂದ ವಿಷಯವನ್ನು ವೀಕ್ಷಿಸಿ."</item>
+ <item msgid="1855708984677953238">"ಪರಿಚಿತ ಮಾರ್ಗದರ್ಶಿ ಮತ್ತು ಸ್ನೇಹಿ ಇಂಟರ್ಫೇಸ್ ಹೊಂದಿರುವ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಂದ ವಿಷಯವನ್ನು ಬ್ರೌಸ್‌ ಮಾಡಿ, \nಟಿವಿಯಲ್ಲಿನ ಚಾನಲ್‌ಗಳಂತೆ."</item>
+ <item msgid="3420760668363283731">"ಲೈವ್‌ ಚಾನಲ್‌ಗಳನ್ನು ಆಫರ್ ಮಾಡುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಿ. \nಟಿವಿ ಮೆನುನಲ್ಲಿರುವ ಲಿಂಕ್‌ ಬಳಸಿಕೊಂಡು Google Play ಸ್ಟೋರ್‌ನಲ್ಲಿ ಹೊಂದಾಣಿಕೆಯಾಗಬಲ್ಲ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ."</item>
+ <item msgid="8974157841656828507">"ನಿಮ್ಮ ಚಾನಲ್‌ ಪಟ್ಟಿಯನ್ನು ಕಸ್ಟಮೈಸ್‌ ಮಾಡಲು ನಿಮ್ಮ ಹೊಸದಾಗಿ ಸ್ಥಾಪಿಸಲಾದ ಚಾನಲ್‌ ಮೂಲಗಳನ್ನು ಹೊಂದಿಸಿ. \nಪ್ರಾರಂಭಿಸಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮೆನುನಲ್ಲಿರುವ ಚಾನಲ್‌ ಮೂಲಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ."</item>
+ </string-array>
</resources>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index c7b90407..bc008aa9 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ಚಾನಲ್ ಸೆಟಪ್"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳು"</string>
- <string name="options_item_about" msgid="3023532413252052050">"ಕುರಿತು"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ಚಾನಲ್ ಸೆಟಪ್"</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="channel_source_item_setup" msgid="1330441915487807542">"ಚಾನಲ್ ಮೂಲಗಳು"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"ಹೊಸ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿದೆ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ಚಾನಲ್‌ಪಟ್ಟಿ ಕಸ್ಟಮೈಸ್‌"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"ನಿಮ್ಮ ಕಾರ್ಯಕ್ರಮ ಸೂಚಿಗಾಗಿ ಚಾನಲ್‌ಗಳನ್ನು ಆರಿಸಿ"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"ಇನ್ನೂ ಹೊಂದಿಸಿಲ್ಲ"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ಚಾನಲ್ ಸೇರಿಸಲಾಗಿದೆ"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"ನೀವು ತಪ್ಪಾದ ಪಿನ್ ಅನ್ನು 5 ಬಾರಿ ನಮೂದಿಸಿರುವಿರಿ.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡಿನಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</item>
- <item quantity="other" msgid="8829550842387756054">"ನೀವು ತಪ್ಪಾದ ಪಿನ್ ಅನ್ನು 5 ಬಾರಿ ನಮೂದಿಸಿರುವಿರಿ.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"ಕುರಿತು"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ಮುಕ್ತ ಮೂಲ ಪರವಾನಗಿಗಳು"</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="about_menu_version" msgid="6303769835664868129">"ಆವೃತ್ತಿ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ಆವೃತ್ತಿ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV ಟ್ಯೂನರ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV ಟ್ಯೂನರ್‌ನ ಧ್ವನಿ ಆಲಿಸಲು, ನಿಮ್ಮ TV ಯು AC3 ಪಾಸ್‌ಥ್ರೂ ಬೆಂಬಲಿಸಬೇಕು."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ಚಾನಲ್ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ಸಂ. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ಚಾನಲ್ ಮೂಲಗಳು"</string>
- <string name="setup_description" msgid="8728423605912915099">"ಲಭ್ಯವಿರುವ ಮೂಲಗಳಿಂದ ಲೈವ್ ಚಾನಲ್‌ಗಳನ್ನು ಹೊಂದಿಸಿ. ಚಾನಲ್ ಮೂಲಗಳನ್ನು ಅವಲಂಬಿಸಿ ಇದಕ್ಕೆ ಹಲವಾರು ನಿಮಿಷಗಳು ತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"ಮುಗಿದಿದೆ"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ಚಾನಲ್‌ ಲಭ್ಯವಿದೆ"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿವೆ"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"ಹೆಚ್ಚು ಮೂಲಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"ಲೈವ್ ಚಾನಲ್‌ಗಳನ್ನು ಒದಗಿಸುವಂತಹ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"ಸಂಪರ್ಕಪಡಿಸಲಾದ ಸಾಧನಕ್ಕಾಗಿ ಹಿಂದೆ ಕೀ. ನಿರ್ಗಮಿಸಲು ಮುಖಪುಟ ಬಟನ್ ಒತ್ತಿರಿ."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop ಹೊಂದಿರುವ ಈ ಸಾಧನದಲ್ಲಿ ಲೈವ್ ಚಾನಲ್‌ಗಳು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</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>
</resources>
diff --git a/res/values-ko/arrays.xml b/res/values-ko/arrays.xml
index 38618382..da945d72 100644
--- a/res/values-ko/arrays.xml
+++ b/res/values-ko/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"프리미엄"</item>
<item msgid="8215762047341133299">"기술/과학"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"실시간 채널"</item>
+ <item msgid="7307688057853449735">"콘텐츠를 찾는 간단한 방법"</item>
+ <item msgid="7566838222783641942">"앱을 다운로드하여 더 많은 채널 보기"</item>
+ <item msgid="8646630833216197238">"채널 구성 맞춤설정"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV에서 채널을 시청하는 것처럼 앱에서 콘텐츠를 시청합니다."</item>
+ <item msgid="1855708984677953238">"익숙한 가이드와 사용하기 쉬운 인터페이스로 앱에서 콘텐츠를 탐색합니다. \nTV에서 채널을 탐색하는 것과 같습니다."</item>
+ <item msgid="3420760668363283731">"실시간 채널을 제공하는 앱을 설치하여 더 많은 채널을 추가합니다. \nTV 메뉴에 있는 링크를 사용하여 Google Play 스토어에서 호환되는 앱을 찾습니다."</item>
+ <item msgid="8974157841656828507">"새로 설치한 채널 소스를 설정하여 채널 목록을 맞춤설정합니다. \n설정 메뉴에서 채널 소스를 선택하여 시작합니다."</item>
+ </string-array>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 57b0f246..75983308 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"채널 설정"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"자녀 보호 기능"</string>
- <string name="options_item_about" msgid="3023532413252052050">"정보"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"채널 설정"</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="channel_source_item_setup" msgid="1330441915487807542">"채널 소스"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"새 채널 사용 가능"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"채널 목록 맞춤설정"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"편성표를 표시할 채널을 선택합니다."</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"설정되지 않음"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d개 채널 추가됨"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d개 채널 추가됨"</item>
- </plurals>
+ <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>
@@ -138,16 +131,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PIN 입력이 5회 잘못되었습니다.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>초 후에 다시 시도하세요."</item>
- <item quantity="other" msgid="8829550842387756054">"PIN 입력이 5회 잘못되었습니다.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>초 후에 다시 시도하세요."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"정보"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"오픈소스 라이선스"</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="about_menu_version" msgid="6303769835664868129">"버전"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"버전"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"개발자 옵션"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV 튜너 사용"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV 튜너 소리를 들으려면 TV에서 AC3 패스 스루를 지원해야 합니다."</string>
@@ -168,15 +166,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"제목 없음"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"차단된 채널"</string>
<string name="episode_format" msgid="4881195874563241096">"시즌 <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: 에피소드 <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"채널 소스"</string>
- <string name="setup_description" msgid="8728423605912915099">"사용할 수 있는 소스로 라이브 채널을 설정하세요. 채널 소스에 따라 몇 분 정도 걸릴 수 있습니다."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"완료"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"채널 %1$d개를 이용할 수 있습니다."</item>
- <item quantity="other" msgid="2386588423841837714">"채널 %1$d개를 이용할 수 있습니다."</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"더 많은 소스 다운로드"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"실시간 채널을 제공하는 앱 탐색"</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>" TV 메뉴에 액세스합니다."</string>
@@ -193,4 +197,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"뒤로 키는 연결된 기기에 사용됩니다. 종료하려면 홈 버튼을 누르세요."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"실시간 채널은 이 Android Lollipop 기기에서 지원되지 않습니다."</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>
</resources>
diff --git a/res/values-ky-rKG/arrays.xml b/res/values-ky-rKG/arrays.xml
index 10b48161..835274e6 100644
--- a/res/values-ky-rKG/arrays.xml
+++ b/res/values-ky-rKG/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Бет ачар"</item>
<item msgid="8215762047341133299">"Тех/Илим"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Түз ободогу каналдар"</item>
+ <item msgid="7307688057853449735">"Видеолорду тез табасыз"</item>
+ <item msgid="7566838222783641942">"Колдонмолорду жүктөп алып, көбүрөөк каналга ээ болуңуз"</item>
+ <item msgid="8646630833216197238">"Каналдарыңыздын жеке тизмеси"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Колдонмолоруңуздан видеону сыналгыдагы каналдардай эле көрүңүз."</item>
+ <item msgid="1855708984677953238">"Колдонмолоруңуздагы видеону сыналгыдагы каналдардай которуңуз.\n"</item>
+ <item msgid="3420760668363283731">"Түз ободогу каналдарды сунуштаган колдонмолорду орнотуп, жаңы каналдарды кошуңуз. \nМындай колдонмолорду сыналгынын менюсундагы Google Play Store\'дон таба аласыз."</item>
+ <item msgid="8974157841656828507">"Каналдарыңыздын жеке тизмесин түзүү үчүн \nЖөндөөлөр менюсунан Каналдар булактарын тандаңыз."</item>
+ </string-array>
</resources>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 646376de..7fc4e56f 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Каналды жөндөө"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ата-эне көзөмөл"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Ушул жөнүндө"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Каналды жөндөө"</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="channel_source_item_setup" msgid="1330441915487807542">"Канал булактары"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Жаңы каналдар бар"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Канл тизмсн өзгөчл"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Программа көрсөтмөңүз үчүн канал тандоо"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Орнотулган жок"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d канал кошулду"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d канал кошулду"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PIN кодду 5 жолу туура эмес киргиздиңиз.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунддан кийин кайра аракет кылып көрүңүз."</item>
- <item quantity="other" msgid="8829550842387756054">"PIN кодду 5 жолу туура эмес киргиздиңиз.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунддан кийин кайра аракет кылып көрүңүз."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Ушул жөнүндө"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Ачык программа уруксаттамалары"</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="about_menu_version" msgid="6303769835664868129">"Версиясы"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Версиясы"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Иштеп чыгуучунун параметрлери"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB сыналгы күүлөгүчүн иштетүү"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB сыналгы күүлөгүчүнүн добушун угуу үчүн, сыналгыңыз AC3 өткөрмөсүн колдоого алышы керек."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Аталышы жок"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал бөгөттөлдү"</string>
<string name="episode_format" msgid="4881195874563241096">"Мезгил<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Эпизод <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Канал булактары"</string>
- <string name="setup_description" msgid="8728423605912915099">"Жеткиликтүү булактардан түз обо каналдарын жөндөңүз. Каналдын булагына жараша бир нече мүнөткө созулушу мүмкүн."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Бүттү"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d канал жеткиликтүү"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d канал жеткиликтүү"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Дагы булактарды алуу"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Түз ободогу каналдарды сунуштаган колдонмолорду серептөө"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"АРТКА баскычы – туташкан түзмөккө. Чыгуу үчүн БАШКЫ баскычты басыңыз."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Бул Android Lollipop орнотулган түзмөктө Түз ободогу каналдар колдоого алынбайт."</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>
</resources>
diff --git a/res/values-lo-rLA/arrays.xml b/res/values-lo-rLA/arrays.xml
index 7845f241..5e1c1e0c 100644
--- a/res/values-lo-rLA/arrays.xml
+++ b/res/values-lo-rLA/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ການ​ສະ​ແດງ"</item>
<item msgid="8215762047341133299">"ເຕັກ​ໂນ​ໂລ​ຊີ/ວິ​ທະ​ຍາ​ສາດ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ຊ່ອງ​ອອກອາກາດສົດ"</item>
+ <item msgid="7307688057853449735">"ວິທີງ່າຍດາຍໃນການຄົ້ນພົບເນື້ອຫາ"</item>
+ <item msgid="7566838222783641942">"ດາວໂຫຼດແອັບ, ເອົາຊ່ອງເພີ່ມເຕີມ"</item>
+ <item msgid="8646630833216197238">"ປັບແຕ່ງການຈັດວາງຊ່ອງຂອງທ່ານ"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"ເບິ່ງເນື້ອຫາຈາກແອັບຕ່າງໆ ເຊັ່ນວ່າ ການຮັບຊົມຊ່ອງຕ່າງໆໃນໂທລະພາບ."</item>
+ <item msgid="1855708984677953238">"ຊອກເບິ່ງເນື້ອຫາຈາກແອັບຕ່າງໆດ້ວຍຄຳແນະນຳທີ່ຄຸ້ນເຄີຍ ແລະ ສ່ວນຕໍ່ປະສານທີ່ໃຊ້ງ່າຍ, \nຄືກັນກັບຊ່ອງຕ່າງໆໃນໂທລະພາບ."</item>
+ <item msgid="3420760668363283731">"ເພີ່ມຊ່ອງເພີ່ມເຕີມ ໂດຍການຕິດຕັ້ງແອັບຕ່າງໆທີ່ໃຫ້ຊ່ອງອອກອາກາດສົດ. \nຊອກຫາແອັບທີ່ເຂົ້າກັນໄດ້ໃນ Google Play Store ໂດຍການໃຊ້ລິ້ງຢູ່ພາຍໃນເມນູໂທລະພາບ."</item>
+ <item msgid="8974157841656828507">"ຕັ້ງຄ່າແຫຼ່ງຊ່ອງທີ່ຕິດຕັ້ງໃໝ່ຂອງທ່ານເພື່ອປັບແຕ່ງລາຍການຊ່ອງຂອງທ່ານ. \nເລືອກແຫຼ່ງຊ່ອງຢູ່ພາຍໃນເມນູການຕັ້ງຄ່າເພື່ອເລີ່ມຕົ້ນນຳໃຊ້."</item>
+ </string-array>
</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index e23ac45e..0101d73c 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ຕັ້ງ​ຊ່ອງ"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"ການ​ຄວບຄຸມ​ຂອງ​ຜູ່​ປົກ​ຄອງ"</string>
- <string name="options_item_about" msgid="3023532413252052050">"ກ່ຽວກັບ"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ຕັ້ງ​ຊ່ອງ"</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="channel_source_item_setup" msgid="1330441915487807542">"ທີ່ມາ​ຂອງ​ຊ່ອງ"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"ມີ​ຊ່ອງ​ໃໝ່​ໃຫ້​ຢູ່"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ປັບແຕ່ງລາຍ​ຊື່​ຊ່ອງ"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"ເລືອກ​ຊ່ອງ​ສຳລັບ​ແນະນຳ​ລາຍການ​ຂອງ​ທ່ານ"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"ບໍ່ໄດ້​ຕິດ​ຕັ້ງ"</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">
- <item quantity="one" msgid="6074059986849579215">"ເພີ່ມ​ %1$d ​ຊ່ອງແລ້ວ"</item>
- <item quantity="other" msgid="1078861616751739285">"​ເພີ່ມ %1$d ຊ່ອງ​ແລ້ວ"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"ທ່ານ​ໄດ້​ປ້ອນ​ລະ​ຫັດ PIN ຜິດ 5 ຄັ້ງ.\nລອງ​ໃໝ່​ອີກ​ໃນ <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ວິ​ນາ​ທີ."</item>
- <item quantity="other" msgid="8829550842387756054">"ທ່ານ​ໄດ້​ປ້ອນ​ລະ​ຫັດ PIN ຜິດ 5 ຄັ້ງ.\nລອງ​ໃໝ່​ອີກ​ໃນ <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> ວິ​ນາ​ທີ."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"ກ່ຽວກັບ"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"​ໃບ​ອະ​ນຸ​ຍາດ​ແຫຼ່ງ​ເປີດ"</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="about_menu_version" msgid="6303769835664868129">"ເວີຊັນ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ເວີຊັນ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ຕົວ​ເລືອກ​ນັກພັດທະນາ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"​ເປີດ​ໃຊ້ຕົວ​ຮັບ​ສັນຍານ​ໂທລະພາບ​ແບບ USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"​ເພື່ອ​ຟັງສຽງ​ຂອງ​ຕົວ​ຮັບ​ສັນຍານ​ໂທລະພາບ​ແບບ USB, ​ໂທລະພາບ​ຂອງ​ທ່ານ​ຄວນ​ຮອງ​ຮັບ​ການ​ສົ່ງ​ຜ່ານ AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ບໍ່ມີຫົວຂໍ້"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"​ຊ່ອງ​ຖືກບລັອກ"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ຕອນ <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ທີ່ມາ​ຂອງ​ຊ່ອງ"</string>
- <string name="setup_description" msgid="8728423605912915099">"ຕັ້ງ​ຊ່ອງ​ສົດ​ຈາກ​ແຫຼ່ງ​ທີ່​ມີ​ຢູ່. ອັນ​ນີ້​ອາດ​ຈະໃຊ້​ເວ​ລາ​ຫຼາຍ​ນາ​ທີ ຂຶ້ນ​ກັບ​ແຫຼ່ງ​ທີ່​ມາ​ຂອງ​ຊ່ອງ."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"ແລ້ວໆ"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ຊ່ອງ​ພ້ອມ​ໃຊ້​ງານ​ໄດ້"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ຊ່ອງ​ພ້ອມ​ໃຊ້​ງານ​ໄດ້"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"ເອົາແຫຼ່ງທີ່ມາຂອງຊ່ອງເພີ່ມເຕີມ"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"ທ່ອງເບິ່ງແອັບທີ່ໃຫ້ຊ່ອງຖ່າຍທອດສົດ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"ປຸ່ມ Back ແມ່ນ​ສຳ​ລັບ​ອຸ​ປະ​ກອນ​ທີ່​ເຊື່ອມ​ຕໍ່​ແລ້ວ. ໃຫ້​ກົດ​ປຸ່ມ Home ເພື່ອອອກ."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"ຊ່ອງ​ສົດ​ບໍ່​ຖືກ​ຮອງ​ຮັບ​ຢູ່​ໃນ​ອຸ​ປະ​ກອນ​ນີ້​ດ້ວຍ Android Lollipop."</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>
</resources>
diff --git a/res/values-lt/arrays.xml b/res/values-lt/arrays.xml
index 877c6d6c..e1512c7b 100644
--- a/res/values-lt/arrays.xml
+++ b/res/values-lt/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premjera"</item>
<item msgid="8215762047341133299">"Technol. / mokslas"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Tiesioginiai kanalai"</item>
+ <item msgid="7307688057853449735">"Paprastas būdas atrasti turinį"</item>
+ <item msgid="7566838222783641942">"Atsisiųskite programų, gaukite daugiau kanalų"</item>
+ <item msgid="8646630833216197238">"Tinkinkite kanalų išdėstymą"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Žiūrėkite programų turinį kaip televizoriaus kanalus."</item>
+ <item msgid="1855708984677953238">"Naršykite programų turinį naudodami panašų vadovą ir jums pritaikytą sąsają, \nkaip naršote televizoriaus kanalus."</item>
+ <item msgid="3420760668363283731">"Pridėkite daugiau kanalų įdiegdami tiesioginius kanalus teikiančių programų. \nSuraskite suderinamų programų „Google Play“ parduotuvėje, naudodami TV meniu pateiktą nuorodą."</item>
+ <item msgid="8974157841656828507">"Nustatykite įdiegtus naujus kanalų šaltinius ir tinkinkite kanalų sąrašą. \nKad pradėtumėte, pasirinkite kanalų šaltinius „Nustatymų“ meniu."</item>
+ </string-array>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 40c87a11..a66d6451 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanalų sąranka"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Tėvų kontrolė"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Apie"</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>
@@ -84,21 +83,17 @@
<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">"Grupuoti pagal"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanalų sąranka"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ši programa yra užblokuota"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalų šaltiniai"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Galimi nauji kanalai"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Tinkinti kan. sąr."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Pasirinkite programų vadovo kanalus"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nenustatyta"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Nepavyksta paleisti visos sistemos subtitrų nuostatų."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Pridėta kanalų: %1$d"</item>
- <item quantity="other" msgid="1078861616751739285">"Pridėta kanalų: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Pridėtas %1$d kanalas</item>
+ <item quantity="few">Pridėti %1$d kanalai</item>
+ <item quantity="many">Pridėta %1$d kanalo</item>
+ <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>
@@ -136,16 +131,23 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Įveskite naują PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Patvirtinkite PIN kodą"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Įveskite dabartinį PIN kodą"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"5 kartus įvedėte ne tą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sek."</item>
- <item quantity="other" msgid="8829550842387756054">"5 kartus įvedėte ne tą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sek."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">5 kartus įvedėte netinkamą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundės.</item>
+ <item quantity="few">5 kartus įvedėte netinkamą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundžių.</item>
+ <item quantity="many">5 kartus įvedėte netinkamą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundės.</item>
+ <item quantity="other">5 kartus įvedėte netinkamą PIN kodą.\nBandykite dar kartą po <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundžių.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Apie"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Atvirojo šaltinio licencijos"</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_menu_licenses" msgid="1257646083838406103">"Atvirojo šaltinio licencijos"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Atvirojo šaltinio licencijos"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versija"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versija"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Kūrėjo parinktys"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Įgalinti USB TV imtuvą"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Kad galėtumėte girdėti USB TV imtuvo garsą, jūsų TV turi būti palaikomas AC3 perdavimas."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Nėra pavadinimo"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanalas užblokuotas"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g> sezonas: <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> serija „<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>“"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalų šaltiniai"</string>
- <string name="setup_description" msgid="8728423605912915099">"Nustatykite tiesioginius kanalus iš pasiekiamų šaltinių. Tai gali užtrukti kelias minutes, atsižvelgiant į kanalo šaltinį."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Atlikta"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Pasiekiama kanalų: %1$d"</item>
- <item quantity="other" msgid="2386588423841837714">"Pasiekiama kanalų: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nauji"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Šaltiniai"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d kanalas</item>
+ <item quantity="few">%1$d kanalai</item>
+ <item quantity="many">%1$d kanalo</item>
+ <item quantity="other">%1$d kanalų</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nėra pasiekiamų kanalų"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Naujos"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nenustatyta"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Gauti daugiau šaltinių"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Naršyti programas, kuriose siūlomi tiesioginiai kanalai"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Pasiekiami nauji kanalų šaltiniai"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Naujuose kanalų šaltiniuose siūloma kanalų.\nNustatykite juos dabar arba atlikite tai vėliau kanalų šaltinių nustatymo skiltyje."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Nustatyti dabar"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Gerai, supratau"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Paspauskite PASIRINKTI,"</b>" kad pasiektumėte TV meniu."</string>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"GRĮŽIMO klavišas skirtas prijungtam įrenginiui. Paspauskite PAGRINDINIO PUSLAPIO mygtuką, kad išeitumėte."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Programa „Live TV“ nepalaikoma šiame įrenginyje, nes jame veikia „Lollipop“ versijos „Android“."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Programai „Live TV“ reikalingas leidimas skaityti TV įrašus."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Nustatykite šaltinius"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Tiesioginiuose kanaluose derinamos tradicinių TV kanalų ir programų srautu perduodamų kanalų funkcijos. \n\nPradėkite nustatydami jau įdiegtų kanalų šaltinius. Arba naršykite „Google Play“ parduotuvę, kur rasite daugiau tiesioginius kanalus teikiančių programų."</string>
</resources>
diff --git a/res/values-lv/arrays.xml b/res/values-lv/arrays.xml
index 56969edd..4e074e39 100644
--- a/res/values-lv/arrays.xml
+++ b/res/values-lv/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Svarīgākais"</item>
<item msgid="8215762047341133299">"Tehnoloģijas/zinātne"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Dzīvie kanāli"</item>
+ <item msgid="7307688057853449735">"Vienkāršs veids, kā atklāt jaunu saturu"</item>
+ <item msgid="7566838222783641942">"Lejupielādējiet lietotnes, iegūstiet vairāk kanālu"</item>
+ <item msgid="8646630833216197238">"Pielāgojiet savu kanālu sarakstu"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Skatieties saturu no lietotnēm tāpat kā kanālus televizorā."</item>
+ <item msgid="1855708984677953238">"Pārlūkojiet lietotņu saturu, izmantojot pierastu ceļvedi un vienkāršu saskarni, —\ngluži kā skatoties televīzijas kanālus."</item>
+ <item msgid="3420760668363283731">"Pievienojiet kanālus, instalējot lietotnes, kas piedāvā dzīvos kanālus. \nAtrodiet saderīgas lietotnes Google Play veikalā, izmantojot televizora izvēlnē pieejamo saiti."</item>
+ <item msgid="8974157841656828507">"Iestatiet instalētos kanālu avotus, lai pielāgotu kanālu sarakstu.\nLai sāktu, izvēlieties kanālu avotus izvēlnē Iestatījumi."</item>
+ </string-array>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7d293b89..2d610e24 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanāla izveide"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Vecāku kontrole"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Par"</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>
@@ -84,21 +83,16 @@
<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">"Grupēt pēc:"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanāla izveide"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Šī programma ir bloķēta."</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="channel_source_item_setup" msgid="1330441915487807542">"Kanālu avoti"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Pieejami jauni kanāli"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Pielāgot kanālu sar."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Izvēlieties kanālus programmu ceļvedim."</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nav iestatīts"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Nevar palaist slēgto parakstu sistēmas preferences."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Tika pievienots %1$d kanāls."</item>
- <item quantity="other" msgid="1078861616751739285">"Tika pievienoti %1$d kanāli."</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="zero">Tika pievienoti %1$d kanāli.</item>
+ <item quantity="one">Tika pievienots %1$d kanāls.</item>
+ <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>
@@ -136,16 +130,22 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ievadiet jauno PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Apstipriniet PIN kodu"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Ievadiet pašreizējo PIN kodu"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Jūs 5 reizes ievadījāt nepareizu PIN.\nMēģiniet vēlreiz pēc <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundes."</item>
- <item quantity="other" msgid="8829550842387756054">"Jūs 5 reizes ievadījāt nepareizu PIN.\nMēģiniet vēlreiz pēc <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundēm."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="zero">Jūs 5 reizes ievadījāt nepareizu PIN kodu.\nMēģiniet vēlreiz pēc <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundēm.</item>
+ <item quantity="one">Jūs 5 reizes ievadījāt nepareizu PIN kodu.\nMēģiniet vēlreiz pēc <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundes.</item>
+ <item quantity="other">Jūs 5 reizes ievadījāt nepareizu PIN kodu.\nMēģiniet vēlreiz pēc <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundēm.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Par"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Atklātā pirmkoda licences"</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_menu_licenses" msgid="1257646083838406103">"Atklātā pirmkoda licences"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Atklātā pirmkoda licences"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versija"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versija"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Izstrādātājiem paredzētās opcijas"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Iespējot USB TV kanālu meklētāju"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Jūsu TV ir jābūt atbalstītai AC3 tālāknodošanai, lai varētu dzirdēt USB TV kanālu meklētāja skaņu."</string>
@@ -166,15 +166,22 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Nav nosaukuma"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanāls bloķēts"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>. sezona, <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>. sērija “<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>”"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanālu avoti"</string>
- <string name="setup_description" msgid="8728423605912915099">"Izveidojiet tiešraides kanālus no pieejamajiem avotiem. Atkarībā no kanāla avota tas var ilgt vairākas minūtes."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Gatavs"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Pieejams %1$d kanāls"</item>
- <item quantity="other" msgid="2386588423841837714">"Pieejami %1$d kanāli"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Jauni"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Avoti"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="zero">%1$d kanālu</item>
+ <item quantity="one">%1$d kanāls</item>
+ <item quantity="other">%1$d kanāli</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nav pieejams neviens kanāls"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Jauna"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nav iestatīts"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Iegūt vairāk avotu"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Pārlūkojiet lietotnes, kas piedāvā tiešraides kanālus"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Pieejami jauni kanālu avoti"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Jaunajos kanālu avotos ir pieejami kanāli.\nIestatiet tos tūlīt vai vēlāk — izmantojot kanālu avotu iestatījumu."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Iestatīt tūlīt"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Labi"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Nospiediet ATLASĪT"</b>", lai piekļūtu TV izvēlnei."</string>
@@ -191,4 +198,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Poga ATPAKAĻ ir paredzēta pievienotajai ierīcei. Lai izietu, nospiediet pogu SĀKUMS."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Šajā ierīcē, kurā instalēta operētājsistēma Android Lollipop, netiek atbalstīta lietotne Tiešraides kanāli."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Lietotnei Tiešraides kanāli ir nepieciešama atļauja lasīt TV sarakstus."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Iestatiet avotus"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Lietotnē Dzīvie kanāli varat skatīties tradicionālos TV kanālus, kā arī straumēt kanālus no citām lietotnēm. \n\nLai sāktu, iestatiet jau instalētos kanālu avotus. Vai pārlūkojiet Google Play veikalu, kurā pieejamas citas dzīvo kanālu lietotnes."</string>
</resources>
diff --git a/res/values-mk-rMK/arrays.xml b/res/values-mk-rMK/arrays.xml
index 3a405966..b1ae7467 100644
--- a/res/values-mk-rMK/arrays.xml
+++ b/res/values-mk-rMK/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Главно"</item>
<item msgid="8215762047341133299">"Техника/наука"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ТВ канали во живо"</item>
+ <item msgid="7307688057853449735">"Едноставен начин да се откријат содржини"</item>
+ <item msgid="7566838222783641942">"Преземете апликации, добијте повеќе канали"</item>
+ <item msgid="8646630833216197238">"Приспособете го редоследот на каналите"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Гледајте ги содржините од апликациите како што ги гледате каналите на телевизорот."</item>
+ <item msgid="1855708984677953238">"Прелистувајте содржини од апликациите со познат водич и пријателски интерфејс, \nисто како каналите на телевизорот."</item>
+ <item msgid="3420760668363283731">"Додајте повеќе канали со инсталирање апликации што нудат канали во живо. \nНајдете компатибилни апликации во Google Play Store преку врската во менито на телевизорот."</item>
+ <item msgid="8974157841656828507">"Поставете ги ново инсталираните извори на канали за да ја приспособите листата со канали. \nИзберете ги изворите на канали во менито Поставки за да започнете."</item>
+ </string-array>
</resources>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 0282ed3f..4a4550c9 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Пост. канали"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Родит. контрола"</string>
- <string name="options_item_about" msgid="3023532413252052050">"За"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Поставување канали"</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="channel_source_item_setup" msgid="1330441915487807542">"Извори на канал"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Достапни се нови канали"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Присп.листа канали"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Изберете канали за програмскиот водич"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Не е поставен"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d канал е додаден"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d канали се додадени"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Внесовте погрешен ПИН пет пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунда."</item>
- <item quantity="other" msgid="8829550842387756054">"Внесовте погрешен ПИН пет пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунди."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"За"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Лиценци за отворен код"</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="about_menu_version" msgid="6303769835664868129">"Верзија"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Верзија"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Опции за програмери"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Овозможете TV приемник преку УСБ"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"За да го слушате звукот на TV приемникот преку УСБ, вашиот TV треба да поддржува премин AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Без наслов"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Каналот е блокиран"</string>
<string name="episode_format" msgid="4881195874563241096">"С<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Еп. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Извори на канал"</string>
- <string name="setup_description" msgid="8728423605912915099">"Поставете канали во живо од достапните извори. Ова може да потрае неколку минути, во зависност од изворот на каналот."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Готово"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d канал е достапен"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d канали се достапни"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Земете повеќе извори"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Прелистувајте апликации што нудат канали во живо"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Копчето НАЗАД е за поврзаниот уред. Притиснете на копчето ПОЧЕТНА СТРАНИЦА за да излезете."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Каналите во живо не се поддржани на уредов со Android Lollipop."</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>
</resources>
diff --git a/res/values-ml-rIN/arrays.xml b/res/values-ml-rIN/arrays.xml
index 1bf34cee..383837e7 100644
--- a/res/values-ml-rIN/arrays.xml
+++ b/res/values-ml-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"പ്രീമിയർ"</item>
<item msgid="8215762047341133299">"സാങ്കേതികവിദ്യ/ശാസ്‌ത്രം"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"തത്സമയ ചാനലുകൾ"</item>
+ <item msgid="7307688057853449735">"ഉള്ളടക്കം കണ്ടെത്താനുള്ള ലളിതമായ മാർഗ്ഗം"</item>
+ <item msgid="7566838222783641942">"ആപ്‌സ് ഡൗൺലോഡ് ചെയ്യുക, കൂടുതൽ ചാനലുകൾ സ്വീകരിക്കുക"</item>
+ <item msgid="8646630833216197238">"നിങ്ങളുടെ ചാനൽ ലൈൻ-അപ്പ് ഇഷ്ടാനുസൃതമാക്കുക"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"ടിവിയിൽ ചാനലുകൾ കാണുന്നത് പോലെ നിങ്ങളുടെ ആപ്‌സിൽ ഉള്ളടക്കം കാണുക."</item>
+ <item msgid="1855708984677953238">"പരിചിത ഗൈഡും ഉപയോഗലാളിത്യമുള്ള ഇന്റർഫേസും ഉപയോഗിച്ച് നിങ്ങളുടെ ആപ്‌സിൽ നിന്ന് ഉള്ളടക്കം ബ്രൗസുചെയ്യുക, \nടിവിയിൽ ചാനലുകൾ കാണുന്നത് പോലെ തന്നെയാണിത്."</item>
+ <item msgid="3420760668363283731">"തത്സമയ ചാനലുകൾ നൽകുന്ന ആപ്‌സ് ഇൻസ്റ്റാൾ ചെയ്തുകൊണ്ട് കൂടുതൽ ചാനലുകൾ ചേർക്കുക. \nടിവി മെനുവിനുള്ളിലെ ലിങ്ക് ഉപയോഗിച്ചുകൊണ്ട് Google Play സ്റ്റോറിൽ അനുയോജ്യമായ ആപ്‌സ് കണ്ടെത്തുക."</item>
+ <item msgid="8974157841656828507">"നിങ്ങളുടെ ചാനൽ ലിസ്റ്റ് ഇഷ്ടാനുസൃതമാക്കുന്നതിന് നിങ്ങൾ പുതിയതായി ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ചാനൽ ഉറവിടങ്ങൾ സജ്ജമാക്കുക. \nആരംഭിക്കുന്നതിന്, ക്രമീകരണത്തിനുള്ളിൽ ചാനൽ ഉറവിടങ്ങൾ തിരഞ്ഞെടുക്കുക."</item>
+ </string-array>
</resources>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index d52018de..b23fe17e 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ചാനൽ സെറ്റപ്പ്"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ"</string>
- <string name="options_item_about" msgid="3023532413252052050">"വിവരം"</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>
@@ -84,21 +83,13 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ചാനൽ സെറ്റപ്പ്"</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="channel_source_item_setup" msgid="1330441915487807542">"ചാനൽ ഉറവിടങ്ങൾ"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"പുതിയ ചാനലുകൾ ലഭ്യമാണ്"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ചാനൽ ലിസ്റ്റ് ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"നിങ്ങളുടെ പ്രോഗ്രാം ഗൈഡിനായി ചാനലുകൾ തിരഞ്ഞെടുക്കുക"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"സജ്ജീകരിച്ചിട്ടില്ല"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ചാനൽ ചേർത്തു"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ചാനലുകൾ ചേർത്തു"</item>
- </plurals>
+ <!-- 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>
@@ -136,16 +127,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"നിങ്ങൾ പിൻ അഞ്ചുതവണ തെറ്റായി നൽകി.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> നിമിഷത്തിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</item>
- <item quantity="other" msgid="8829550842387756054">"നിങ്ങൾ പിൻ അഞ്ചുതവണ തെറ്റായി നൽകി.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> നിമിഷങ്ങൾക്കുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"വിവരം"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ഓപ്പൺ സോഴ്‌സ് ലൈസൻസുകൾ"</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="about_menu_version" msgid="6303769835664868129">"പതിപ്പ്"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"പതിപ്പ്"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ഡെവലപ്പര്‍ ഓ‌പ്ഷനുകൾ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB ടിവി ട്യൂണർ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB ടിവി ട്യൂണറിന്റെ ശബ്ദം കേൾക്കുന്നതിന്, AC3 പാസ്‌ത്രൂവിനെ നിങ്ങളുടെ ടിവി പിന്തുണയ്ക്കേണ്ടതുണ്ട്."</string>
@@ -166,15 +162,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ശീർഷകമൊന്നുമില്ല"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ചാനൽ തടഞ്ഞിരിക്കുന്നു"</string>
<string name="episode_format" msgid="4881195874563241096">"സീസൺ<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ഭാഗം. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ചാനൽ ഉറവിടങ്ങൾ"</string>
- <string name="setup_description" msgid="8728423605912915099">"ലഭ്യമായ ഉറവിടങ്ങളിൽ നിന്ന് തൽസമയ ചാനലുകൾ സജ്ജമാക്കുക. ചാനൽ ഉറവിടത്തെ ആശ്രയിച്ച് ഇതിന് ധാരാളം സമയം എടുത്തേക്കാം."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"പൂർത്തിയായി"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ചാനൽ ലഭ്യമാണ്"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ചാനലുകൾ ലഭ്യമാണ്"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"കൂടുതൽ ഉറവിടങ്ങൾ സ്വീകരിക്കുക"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"തത്സമയ ചാനലുകൾ നൽകുന്ന ആപ്‌സ് ബ്രൗസുചെയ്യുക"</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>
@@ -191,4 +193,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"കണക്‌റ്റു‌ചെയ്‌തിരിക്കുന്ന ഉപകരണത്തിനുള്ളതാണ് മടങ്ങുക എന്ന കീ. പുറത്തുകടക്കാൻ ഹോം ബട്ടൺ അമർത്തുക."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop ഉള്ള ഈ ഉപകരണത്തിൽ തത്സമയ ചാനലുകൾക്ക് പിന്തുണയില്ല."</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>
</resources>
diff --git a/res/values-mn-rMN/arrays.xml b/res/values-mn-rMN/arrays.xml
index 0985c64b..3d0b16ba 100644
--- a/res/values-mn-rMN/arrays.xml
+++ b/res/values-mn-rMN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Эхний"</item>
<item msgid="8215762047341133299">"Технологи/ШУ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Шууд суваг"</item>
+ <item msgid="7307688057853449735">"Агуулга хайх энгийн арга"</item>
+ <item msgid="7566838222783641942">"Апп татаж, илүү олон суваг авах"</item>
+ <item msgid="8646630833216197238">"Сувгийнхаа дэс дарааллыг өөрчлөх"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV-дээ суваг үздэг шиг апп-с агуулга үзээрэй."</item>
+ <item msgid="1855708984677953238">"TV суваг шиг \nТанил гарын авлага, боломжит харагдах байдлын тусламжтайгаар апп-аасаа агуулга хайгаарай."</item>
+ <item msgid="3420760668363283731">"Шууд суваг үзэж болох апп суулгаж, илүү олон суваг нэмээрэй. \nGoogle Play Store-с тохирох апп олохын тулд TV цэсний холбоосыг ашиглаарай."</item>
+ <item msgid="8974157841656828507">"Сувгийн жагсаалтаа өөрчлөхийн тулд шинээр суулгасан сувгийн эх сурвалжаа тохируулаарай. \nЭхлүүлэхийн тулд тохиргооны цэснээс сувгийн эх сурвалжийг сонгоорой."</item>
+ </string-array>
</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index d2d15510..8b636963 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Сувгийн тохиргоо"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Эцэг эх хяналт"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Талаар"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Сувгийн тохиргоо"</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="channel_source_item_setup" msgid="1330441915487807542">"Сувгийн эх сурвалж"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Шинэ суваг нээлттэй байна"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Сувгийн жагсаалтыг тохируулах"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Өөрийн хөтөлбөрт оруулах сувгуудыг сонгоно уу"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Тохируулаагүй"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d суваг нэмэгдсэн"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d суваг нэмэгдсэн"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Та ПИН-ээ 5 удуу буруу орууллаа.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>секундын дараа дахин оролдоно уу."</item>
- <item quantity="other" msgid="8829550842387756054">"Та ПИН-ээ 5 удаа буруу орууллаа.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секундын дараа дахин оролдоно уу."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Талаар"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Нээлттэй эхийн лиценз"</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="about_menu_version" msgid="6303769835664868129">"Хувилбар"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Хувилбар"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Хөгжүүлэгчийн тохиргоо"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV тохируулагчийг идэвхжүүлэх"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB ТV тохируулагчийн дууг сонсохын тулд таны ТV AC3 дамжуулалтыг дэмжих хэрэгтэй."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Гарчиггүй"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Сувгийг хориглосон"</string>
<string name="episode_format" msgid="4881195874563241096">"Бүлэг<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Анги. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Сувгийн эх сурвалж"</string>
- <string name="setup_description" msgid="8728423605912915099">"Бэлэн эх үүсвэрээс шууд сувгийг тохируулна уу.Сувгийн эх үүсвэрээс шалтгаалан хэдэн минут болж магадгүй."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Үйлдлийг гүйцэтгэсэн байна"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d суваг нээлттэй"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d суваг нээллтэй"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Бусад сурвалж авах"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Шууд сувгийн апп хайх"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Буцах товчийг холбогдсон төхөөрөмжүүдэд ашиглана. Гарахын тулд Нүүр товчийг дарна уу."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop-той төхөөрөмжид шууд сувгийг дэмжихгүй."</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>
</resources>
diff --git a/res/values-mr-rIN/arrays.xml b/res/values-mr-rIN/arrays.xml
index a1b369a8..a91434f4 100644
--- a/res/values-mr-rIN/arrays.xml
+++ b/res/values-mr-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"प्रमुख"</item>
<item msgid="8215762047341133299">"तंत्रज्ञान/विज्ञान"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"थेट चॅनेल"</item>
+ <item msgid="7307688057853449735">"सामग्री शोधण्याचा एक सोपा मार्ग"</item>
+ <item msgid="7566838222783641942">"अॅप्स डाउनलोड करा, आणखी चॅनेल मिळवा"</item>
+ <item msgid="8646630833216197238">"आपल्या चॅनेलची रांग सानुकूल करा"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV वर चॅनेल पाहता त्याप्रमाणे आपल्या अॅप्समधून सामग्री पहा."</item>
+ <item msgid="1855708984677953238">"परिचित मार्गदर्शक आणि अनुकूल असलेल्या इंटरफेससह\n TV वरील चॅनेलप्रमाणे, आपल्या अॅप्समधून सामग्री ब्राउझ करा."</item>
+ <item msgid="3420760668363283731">"थेट चॅनेल प्रदान करणारे अॅप्स स्थापित करून आणखी चॅनेल जोडा. \n TV मेनू मधील दुव्याचा वापर करून Google Play स्टोअर मध्ये सुसंगत अॅप्स शोधा."</item>
+ <item msgid="8974157841656828507">"आपली चॅनेल सूची सानुकूल करण्यासाठी आपले नव्याने स्थापित केलेले चॅनेल स्रोत सेट करा. \nप्रारंभ करण्यासाठी सेटिंग्ज मेनूमधील चॅनेल स्रोत निवडा."</item>
+ </string-array>
</resources>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index c3c8dc7b..e804990e 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"चॅनेल सेटअप"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"पालक नियंत्रणे"</string>
- <string name="options_item_about" msgid="3023532413252052050">"विषयी"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"चॅनेल सेटअप"</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="channel_source_item_setup" msgid="1330441915487807542">"चॅनेल स्त्रोत"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"उपलब्ध नवीन चॅनेल"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"चॅनेल सूची सानुकूल करा"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"आपल्या कार्यक्रम मार्गदर्शकासाठी चॅनेल निवडा"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"सेट केलेले नाही"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d चॅनेल जोडले"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d चॅनेल जोडले"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"आपण चुकीचा पिन 5 वेळा प्रविष्ट केला.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</item>
- <item quantity="other" msgid="8829550842387756054">"आपण चुकीचा पिन 5 वेळा प्रविष्ट केला.\n <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"विषयी"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"मुक्त स्त्रोत परवाने"</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="about_menu_version" msgid="6303769835664868129">"आवृत्ती"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"आवृत्ती"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"विकासक पर्याय"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB टीव्ही ट्यूनर सक्षम करा"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB टीव्‍ही ट्यूनरचा ध्वनी ऐकण्‍यासाठी, आपल्या टीव्हीने AC3 पासथ्रूला समर्थन द्यावे."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक नाही"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"चॅनेल अवरोधित केले"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: भाग. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"चॅनेल स्त्रोत"</string>
- <string name="setup_description" msgid="8728423605912915099">"उपलब्ध स्त्रोतांवरून थेट चॅनेल सेट करा. चॅनेल स्त्रोताच्या आधारावर यास कित्येक मिनिटे लागू शकतात."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"पूर्ण झाले"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d चॅनेल उपलब्ध"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d चॅनेल उपलब्ध"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"अधिक स्रोत मिळवा"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"थेट चॅनेल प्रदान करणारे अॅप्स ब्राउझ करा"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"बॅक की कनेक्ट केलेल्या डिव्हाइससाठी आहे. बाहेर पडण्यासाठी मुख्यपृष्ठ बटण दाबा."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop सह थेट चॅनेल या डिव्हाइसवर समर्थित नाहीत."</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>
</resources>
diff --git a/res/values-ms-rMY/arrays.xml b/res/values-ms-rMY/arrays.xml
index 6c795d51..16ccce64 100644
--- a/res/values-ms-rMY/arrays.xml
+++ b/res/values-ms-rMY/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Perdana"</item>
<item msgid="8215762047341133299">"Teknikal/Sains"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Saluran Langsung"</item>
+ <item msgid="7307688057853449735">"Cara mudah untuk menemui kandungan"</item>
+ <item msgid="7566838222783641942">"Muat turun apl, dapatkan lebih banyak saluran"</item>
+ <item msgid="8646630833216197238">"Sesuaikan barisan saluran anda"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Tonton kandungan daripada apl anda seperti menonton saluran pada TV."</item>
+ <item msgid="1855708984677953238">"Semak imbas kandungan daripada apl anda dengan menggunakan panduan biasa dan antara muka yang mesra, \n sama seperti saluran pada TV."</item>
+ <item msgid="3420760668363283731">"Tambahkan lagi saluran dengan memasang apl yang menawarkan saluran langsung. \nCari apl yang serasi di Gedung Google Play dengan menggunakan pautan dalam menu TV."</item>
+ <item msgid="8974157841656828507">"Sediakan sumber saluran yang baru dipasang untuk menyesuaikan senarai saluran anda. \nPilih sumber Saluran dalam menu Tetapan untuk memulakan."</item>
+ </string-array>
</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index b73ffe88..a21da27e 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Psdiaan saluran"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Kawalan ibu bapa"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Perihal"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Persediaan saluran"</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="channel_source_item_setup" msgid="1330441915487807542">"Sumber saluran"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Saluran baharu tersedia"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Sesuaikan saluran"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Pilih saluran utk panduan rancangan anda"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Tidak disediakan"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d saluran ditambahkan"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d saluran ditambahkan"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Anda telah memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> saat."</item>
- <item quantity="other" msgid="8829550842387756054">"Anda memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> saat."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Perihal"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Lesen sumber terbuka"</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="about_menu_version" msgid="6303769835664868129">"Versi"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versi"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Pilihan pembangun"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Dayakan penala TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"TV anda harus menyokong laluan AC3 untuk mendengar bunyi penala TV USB."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"M<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Sumber saluran"</string>
- <string name="setup_description" msgid="8728423605912915099">"Sediakan saluran langsung daripada sumber yang tersedia. Ini mungkin mengambil masa beberapa minit bergantung pada sumber saluran itu."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Selesai"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d saluran tersedia"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d saluran tersedia"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Dapatkan lebih banyak sumber"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Kekunci BACK adalah untuk peranti yang tersambung. Tekan butang HOME untuk keluar."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Saluran Langsung tidak disokong pada peranti ini dengan Android Lollipop."</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>
</resources>
diff --git a/res/values-my-rMM/arrays.xml b/res/values-my-rMM/arrays.xml
index 249b20a2..384243da 100644
--- a/res/values-my-rMM/arrays.xml
+++ b/res/values-my-rMM/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ပွဲဦး"</item>
<item msgid="8215762047341133299">"စက်မှု/သိပ္ပံ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"တိုက်ရိုက်လွှင့် ချန်နယ်များ"</item>
+ <item msgid="7307688057853449735">"အကြောင်းအရာများကို စူးစမ်းရှာဖွေရန် ရိုးရှင်းသည့်နည်းလမ်းတစ်ခု"</item>
+ <item msgid="7566838222783641942">"အက်ပ်ကိုဒေါင်းလုဒ်လုပ်ပြီး၊ နောက်ထပ်ချန်နယ်များ ရယူလိုက်ပါ"</item>
+ <item msgid="8646630833216197238">"သင့်ချန်နယ် ထားသိုမှုကိုစိတ်ကြိုက်ပြုပြင်ပါ"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV ချန်နယ်များကြည့်သလို သင့်အက်ပ်များအတွင်း အကြောင်းအရာများကို ကြည့်ပါ။"</item>
+ <item msgid="1855708984677953238">\n"TV ချန်နယ်များကဲ့သို့ပင်၊ အကျွမ်းတဝင်ရှိသည့်လမ်းညွှန်နှင့် ရင်းနှီးမှုရှိသည့် အင်တာဖေ့စ်ဖြင့် အက်ပ်များမှ အကြောင်းအရာများကိုကြည့်ပါ။"</item>
+ <item msgid="3420760668363283731">"တိုက်ရိုက်လွှင့်သည့် ချန်နယ်များပါဝင်သည့် အက်ပ်များကို ထည့်သွင်းခြင်းအားဖြင့် နောက်ထပ်ချန်နယ်များ ထည့်ပါ။ \nTV မန်နယူးရှိလင့်ခ်ကိုအသုံးပြု၍ Google Play Store အတွင်း ကိုက်ညီမှုရှိသည့်အက်ပ်များကို ရှာပါ။"</item>
+ <item msgid="8974157841656828507">"သင့်ချန်နယ်စာရင်းကို စိတ်ကြိုက်ပြုပြင်ရန် အသစ်ထည့်သွင်းထားသည့် ချန်နယ်အရင်းမြစ်များကို တပ်ဆင်ပါ။ \nစတင်ရန် ဆက်တင်များ မန်နယူးတွင် ချန်နယ်အရင်းမြစ်များကို ရွေးပါ။"</item>
+ </string-array>
</resources>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index ca521087..a07bb709 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ချန်နယ်ချိန်ညှိစနစ်"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"မိဘ ထိန်းချုပ်မှု"</string>
- <string name="options_item_about" msgid="3023532413252052050">"အကြောင်း"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ချန်နယ်တပ်ဆင်စနစ်"</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="channel_source_item_setup" msgid="1330441915487807542">"ချန်နယ်ရင်းမြစ်များ"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"ရရှိနိုင်သည့် ချန်နယ်အသစ်များ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ချာနယ်စာရင်း စိတ်တိုင်းကျ လုပ်"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"အစီအစဉ်လမ်းညွှန်အတွက် ချာနယ်များရွေးရန်"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"စဖွင့်မသတ်မှတ်ရသေးပါ"</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">
- <item quantity="one" msgid="6074059986849579215">"ချာနယ် %1$d ထည့်ပြီး"</item>
- <item quantity="other" msgid="1078861616751739285">"ချာနယ် %1$d ထည့်ပြီး"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"PIN အမှား ၅ ကြိမ် သင်ရိုက်ထည့်ခဲ့၏။\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</item>
- <item quantity="other" msgid="8829550842387756054">"PIN အမှား ၅ ကြိမ် သင်ရိုက်ထည့်ခဲ့သည်။\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"အကြောင်း"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"အခမဲ့ ရင်းမြစ် လိုင်စင်များ"</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="about_menu_version" msgid="6303769835664868129">"ဗားရှင်း"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ဗားရှင်း"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"တီထွင်သူများရွေးစရာ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV ချိန်ညှိကိရိယာကို ဖွင့်ပါ"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV ချိန်ညှိကိရိယာ၏ အသံကြားရန်၊ သင့် TV သည် AC3 passthrough ကိုထောက်ပံ့ရပါမည်။"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ခေါင်းစဉ် မပါ"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ချာနယ် ပိတ်ဆို့ထား"</string>
<string name="episode_format" msgid="4881195874563241096">"ရာသီ<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: အပိုင်း − <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ချန်နယ်ရင်းမြစ်များ"</string>
- <string name="setup_description" msgid="8728423605912915099">"ရရှိနိုင်သည့်ရင်းမြစ်များမှတိုက်ရိုက်လွင့်သောချန်နယ်များသတ်မှတ်ပါ။ချန်နယ်ရင်းမြစ်အပေါ် မူတည်၍မိနစ်အနည်းငယ်ကြာနိုင်ပါသည်။"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"လုပ်ပြီး၏"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d လိုင်းရှိပါသည်"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d လိုင်းများရှိပါသည်"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"အရင်းအမြစ်များကို ပိုမိုရယူပါ"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"တိုက်ရိုက်လွှင့်နေသော ချန်နယ်များကို ကမ်းလှမ်းသည့် အက်ပ်များကို ရှာကြည့်ပါ"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK ကီးသည် ချိတ်ဆက် စက်ကိရိယာ အတွက်ဖြစ်၏။ ထွက်ရန် HOME ခလုတ်ကို နှိပ်ပါ။"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop ဗားရှင်းဖြင့်လည်ပတ်သော ဤကိရိယာတွင် တိုက်ရိုက်ထုတ်လွှင့်သောချန်နယ်လိုင်းများအား အသုံးမပြုနိင်ပါ။"</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>
</resources>
diff --git a/res/values-nb/arrays.xml b/res/values-nb/arrays.xml
index 823aade1..145dd560 100644
--- a/res/values-nb/arrays.xml
+++ b/res/values-nb/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiere"</item>
<item msgid="8215762047341133299">"Teknologi/vitenskap"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Direkte-TV"</item>
+ <item msgid="7307688057853449735">"En enkel måte å oppdage innhold på"</item>
+ <item msgid="7566838222783641942">"Last ned apper – få flere kanaler"</item>
+ <item msgid="8646630833216197238">"Tilpass rekkefølgen på kanalene dine"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Se innhold fra appene dine – akkurat som når du ser på TV-kanaler."</item>
+ <item msgid="1855708984677953238">"Bla gjennom innhold fra appene dine med en gjenkjennelig TV-programoversikt og et brukervennlig grensesnitt, \nakkurat som med kanaler på TV."</item>
+ <item msgid="3420760668363283731">"Legg til flere kanaler ved å installere apper som tilbyr direkte-TV. \nFinn kompatible apper i Google Play Butikk ved å følge linken i TV-menyen."</item>
+ <item msgid="8974157841656828507">"Konfigurer de nylig installerte kanalkildene for å spesialtilpasse kanallisten din. \nVelg alternativet for kanalkilder i innstillingsmenyen for å komme i gang."</item>
+ </string-array>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index f560d6ed..dd6123d1 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanalkonfig."</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Foreldrekontroll"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Info"</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>
@@ -84,21 +83,15 @@
<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">"Gruppér etter"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanalkonfigurasjon"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dette programmet er blokkert."</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalkilder"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nye kanaler er tilgjengelig"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Tilpass kanallisten"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Velg kanaler for programoversikten din"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Ikke konfigurert"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Kunne ikke starte systeminnstillingene for teksting."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanal er lagt til"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanaler er lagt til"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanaler er lagt til</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Skriv inn en ny PIN-kode"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Bekreft PIN-koden din"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Skriv inn den gjeldende PIN-koden din"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Du skrev inn feil PIN-kode 5 ganger.\nPrøv på nytt om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekund."</item>
- <item quantity="other" msgid="8829550842387756054">"Du skrev inn feil PIN-kode 5 ganger.\nPrøv på nytt om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekunder."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Du har skrevet inn feil PIN-kode fem ganger.\nPrøv på nytt om <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunder.</item>
+ <item quantity="one">Du har skrevet inn feil PIN-kode fem ganger.\nPrøv på nytt om <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekund.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Info"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Åpen kildekode-lisenser"</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_menu_licenses" msgid="1257646083838406103">"Lisenser for åpen kildekode"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Åpen kildekode-lisenser"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versjon"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versjon"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Utvikleralternativer"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Slå på USB-tuneren for TV"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"For å høre lyd via USB-tuneren for TV må TV-en din støtte AC3-gjennomgang."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Ingen tittel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanalen er blokkert"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalkilder"</string>
- <string name="setup_description" msgid="8728423605912915099">"Konfigurer live-kanaler fra de tilgjengelige kildene. Dette kan ta opptil flere minutter, avhengig av kanalkilden."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Ferdig"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanal er tilgjengelig"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanaler er tilgengelig"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nye"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Kilder"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanaler</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Ingen kanaler er tilgjengelig"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Ny"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Ikke konfigurert"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Få flere kilder"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Bla gjennom apper som tilbyr kanaler for direkte-TV"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nye kanalkilder er tilgjengelig"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Med de nye kanalkildene får du flere kanaler.\nKonfigurer dem nå, eller gjør det senere i innstillingene for kanalkilder."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Konfigurer nå"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, greit"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Trykk på «SELECT» (VELG)"</b>" for å åpne TV-menyen."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"TILBAKE-tasten er for den tilkoblede enheten. Trykk på STARTSIDE-knappen for å avslutte."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live TV støttes ikke på denne enheten med Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV trenger tillatelse til å lese TV-programoversikten."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Konfigurer kanalkildene dine"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Med direkte-TV får du både den tradisjonelle TV-opplevelsen og strømming av kanaler via apper. \n\nKom i gang ved å konfigurere de kanalkildene som allerede er installert. Eventuelt kan du bla gjennom Google Play Butikk for å finne flere apper som tilbyr direkte-TV."</string>
</resources>
diff --git a/res/values-ne-rNP/arrays.xml b/res/values-ne-rNP/arrays.xml
index b75c407e..a6dc0066 100644
--- a/res/values-ne-rNP/arrays.xml
+++ b/res/values-ne-rNP/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"प्रिमियर"</item>
<item msgid="8215762047341133299">"प्रविधि/विज्ञान"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"लाइभ च्यानलहरू"</item>
+ <item msgid="7307688057853449735">"सामग्री पत्ता लगाउने सरल तरिका"</item>
+ <item msgid="7566838222783641942">"अनुप्रयोगहरू डाउनलोड गर्नुहोस्, अझ बढी च्यानलहरू प्राप्त गर्नुहोस्"</item>
+ <item msgid="8646630833216197238">"तपाईंको च्यानलको लाइन-अपलाई अनुकूलन गर्नुहोस्"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV.मा च्यानलहरू हेर्ने जस्ता सामग्री तपाईंका अनुप्रयोगहरूबाट हेर्नुहोस्।"</item>
+ <item msgid="1855708984677953238">\n"TV का व्यानलहरू जस्तै, परिचित निर्देशिका र साथी अनुकूल इन्टरफेससँगै तपाईंका अनुप्रयोगहरूमा सामग्री ब्राउज गर्नुहोस्।"</item>
+ <item msgid="3420760668363283731">"लाइभ च्यानलहरूको प्रस्ताव गर्ने अनुप्रयोगहरूको स्थापना गरी अझ बढी च्यानलहरू थप्नुहोस्। \nTV मेनुका लिंक प्रयोग गरी Google Play स्टोरमा मिल्दाजुल्दा अनुप्रयोगहरू फेला पार्नुहोस्।"</item>
+ <item msgid="8974157841656828507">"तपाईंको च्यानल सूचीलाई अनुकूलन गर्न तपाईंका नयाँ स्थापित च्यानल स्रोतहरू सेटअप गर्नुहोस्। \nसुरु गर्नका लागि सेटिङ मेनुभित्रको च्यानल स्रोतहरू रोज्नुहोस्।"</item>
+ </string-array>
</resources>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 8b4985bf..8e997ba2 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"च्यानल सेटअप"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"मुख्य नियन्त्रणहरू"</string>
- <string name="options_item_about" msgid="3023532413252052050">"बारेमा"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"च्यानल सेटअप"</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="channel_source_item_setup" msgid="1330441915487807542">"च्यानल स्रोतहरू"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"नयाँ च्यानलहरू उपलब्ध छन्"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"च्यानल सूची अनुकूलन गर्नुहोस्"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"आफ्नो कार्यक्रम गाइडका लागि च्यानलहरू छनौट गर्नुहोस्"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"सेटअप छैन"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d च्यानल थपियो"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d च्यानल थपियो"</item>
- </plurals>
+ <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>
@@ -136,19 +129,24 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"तपाईँले गलत PIN ५ पटक प्रविष्टि गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।"</item>
- <item quantity="other" msgid="8829550842387756054">"तपाईँले गलत PIN ५ पटक प्रविष्टि गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"बारेमा"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"खुला स्रोत इजाजतपत्रहरू"</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="about_menu_version" msgid="6303769835664868129">"संस्करण"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"संस्करण"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"विकासकर्ता विकल्पहरू"</string>
- <string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV tuner सक्रिय गर्नुहोस्"</string>
- <string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV tuner को ध्वनि सुन्‍न, तपाईँको TV ले AC3 passthrough समर्थन हुनुपर्छ।"</string>
+ <string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV ट्युनर सक्रिय गर्नुहोस्"</string>
+ <string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV ट्युनर को ध्वनि सुन्‍न, तपाईँको TV ले AC3 passthrough समर्थन हुनुपर्छ।"</string>
<string name="developer_menu_ac3_support" msgid="8542930057443915670">"AC3 अडियो क्षमता"</string>
<string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"तपाईँको TV ले AC3 passthrough समर्थन गर्छ।"</string>
<string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"तपाईँको TV ले AC3 passthrough समर्थन गर्दैन।"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक छैन"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"च्यानल अवरुद्ध"</string>
<string name="episode_format" msgid="4881195874563241096">"संस्करण <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: भाग <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"च्यानल स्रोतहरू"</string>
- <string name="setup_description" msgid="8728423605912915099">"उपलब्ध स्रोतहरूबाट लाइभ च्यानलहरू सेट अप गर्नुहोस्। च्यानल स्रोत अनुसार केहि मिनेट लाग्‍न सक्छ।"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"सम्पन्न भयो"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d च्यानल उपलब्ध"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d च्यानलहरू उपलब्ध"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"थप स्रोतहरु प्राप्त गर्नुहोस्"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"प्रत्यक्ष च्यानलहरूको प्रस्ताव गर्ने अनुप्रयोगहरू ब्राउज गर्नुहोस्"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK कुञ्जी जडान भएका उपकरणका लागि हो। बाहिर निस्कनका लागि गृह बटन थिच्नुहोस्।"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"लाइभ च्यानलहरु Android Lollipop भएको यस यन्त्रमा समर्थित छैन।"</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>
</resources>
diff --git a/res/values-nl/arrays.xml b/res/values-nl/arrays.xml
index 0cc63ed4..c2cd937e 100644
--- a/res/values-nl/arrays.xml
+++ b/res/values-nl/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Techniek/wetenschap"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Live tv"</item>
+ <item msgid="7307688057853449735">"Een eenvoudige manier om content te vinden"</item>
+ <item msgid="7566838222783641942">"Apps downloaden, meer kanalen krijgen"</item>
+ <item msgid="8646630833216197238">"Je kanaalprogrammering aanpassen"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Bekijk content uit je apps op dezelfde manier als je kanalen op tv bekijkt."</item>
+ <item msgid="1855708984677953238">"Browse door content uit je apps met een bekende gids en gebruikersvriendelijke interface, \nop dezelfde manier als kanalen op tv."</item>
+ <item msgid="3420760668363283731">"Voeg meer kanalen toe door apps te installeren die live tv aanbieden. \nZoek compatibele apps in de Google Play Store via de link in het tv-menu."</item>
+ <item msgid="8974157841656828507">"Configureer je net geïnstalleerde kanaalbronnen om je kanaallijst aan te passen. \nKies de kanaalbronnen in het menu Instellingen om aan de slag te gaan."</item>
+ </string-array>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 5603d492..81a4facc 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanaalconfiguratie"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ouderlijk toezicht"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Over"</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>
@@ -84,21 +83,15 @@
<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">"Groeperen op"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanaalconfiguratie"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dit programma is geblokkeerd"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanaalbronnen"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Nieuwe kanalen beschikbaar"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Kanaallijst aanp."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Kanalen kiezen voor je programmagids"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Niet ingesteld"</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 automatische scan voor \'<xliff:g id="TV_INPUT">%s</xliff:g>\' niet starten"</string>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Kan de ondertitelingsvoorkeuren voor het hele systeem niet starten."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanaal toegevoegd"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanalen toegevoegd"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanalen toegevoegd</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Nieuwe pincode opgeven"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Je pincode bevestigen"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Je huidige pincode opgeven"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Je hebt vijf keer een verkeerde pincode ingevoerd.\nProbeer het over <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconde opnieuw."</item>
- <item quantity="other" msgid="8829550842387756054">"Je hebt vijf keer een verkeerde pincode ingevoerd.\nProbeer het over <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> seconden opnieuw."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Je hebt vijf keer een onjuiste pincode opgegeven.\nProbeer het over <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> seconden opnieuw.</item>
+ <item quantity="one">Je hebt vijf keer een onjuiste pincode opgegeven.\nProbeer het over <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> seconde opnieuw.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Over"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Open-sourcelicenties"</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_menu_licenses" msgid="1257646083838406103">"Open-sourcelicenties"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Open-sourcelicenties"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versie"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versie"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opties voor ontwikkelaars"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB-tv-tuner inschakelen"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Als je het geluid van je USB-tv-tuner wilt horen, moet je tv ondersteuning bieden voor AC3-doorvoer."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Geen titel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanaal geblokkeerd"</string>
<string name="episode_format" msgid="4881195874563241096">"S. <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: afl. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanaalbronnen"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configureer live kanalen van de beschikbare bronnen. Dit kan enkele minuten duren afhankelijk van de kanaalbron."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Gereed"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanaal beschikbaar"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanalen beschikbaar"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nieuw"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Bronnen"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanalen</item>
+ <item quantity="one">%1$d kanaal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Geen kanalen beschikbaar"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nieuw"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Niet ingesteld"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Meer bronnen ophalen"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Browsen door apps die live kanalen aanbieden"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nieuwe kanaalbronnen beschikbaar"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Er zijn nieuwe kanaalbronnen die kanalen aanbieden.\nStel ze nu in of doe dit later via de instelling voor kanaalbronnen."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Nu instellen"</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>"Druk op SELECTEREN"</b>" voor toegang tot het tv-menu."</string>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"De app \'Live kanalen\' wordt niet ondersteund op dit apparaat met Android Lollipop."</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="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>
</resources>
diff --git a/res/values-pl/arrays.xml b/res/values-pl/arrays.xml
index d7e052c9..4dc517b9 100644
--- a/res/values-pl/arrays.xml
+++ b/res/values-pl/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Specjalne"</item>
<item msgid="8215762047341133299">"Nauka i technika"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Telewizja online"</item>
+ <item msgid="7307688057853449735">"Prosty sposób okrywania nowych treści"</item>
+ <item msgid="7566838222783641942">"Pobierz aplikacje, by dodać nowe kanały"</item>
+ <item msgid="8646630833216197238">"Dostosuj ofertę programową"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Oglądaj treści z aplikacji jak kanały na telewizorze."</item>
+ <item msgid="1855708984677953238">"Przeglądaj treści z aplikacji, korzystając ze znanego Ci przewodnika i interfejsu,\nzupełnie jak kanały na telewizorze."</item>
+ <item msgid="3420760668363283731">"Dodaj kanały, instalując aplikacje z telewizją online.\nZnajdź zgodne aplikacje w Sklepie Google Play, korzystając z linku w menu TV."</item>
+ <item msgid="8974157841656828507">"Skonfiguruj nowo zainstalowane źródła kanałów, by dostosować listę kanałów.\nAby rozpocząć, wybierz Kanał z menu Ustawienia."</item>
+ </string-array>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index ce5df400..95f00248 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Konfiguracja kanału"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Kontr. rodzic."</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informacje"</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>
@@ -84,21 +83,17 @@
<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">"Grupuj według"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Konfiguracja kanału"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ten program jest zablokowany"</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="channel_source_item_setup" msgid="1330441915487807542">"Źródła kanałów"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Dostępne są nowe kanały"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Dostosuj listę"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Wybierz kanały do przewodnika TV"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nieskonfigurowany"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Nie można otworzyć systemowych ustawień napisów."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanał został dodany"</item>
- <item quantity="other" msgid="1078861616751739285">"Dodane kanały: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="few">Dodano %1$d kanały</item>
+ <item quantity="many">Dodano %1$d kanałów</item>
+ <item quantity="other">Dodano %1$d kanału</item>
+ <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>
@@ -136,16 +131,23 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Wpisz nowy PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Potwierdź kod PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Wpisz bieżący kod PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Wpisałeś nieprawidłowy kod PIN 5 razy.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- <item quantity="other" msgid="8829550842387756054">"Wpisałeś nieprawidłowy kod PIN 5 razy.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="few">Pięć razy wpisałeś nieprawidłowy kod PIN.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="many">Pięć razy wpisałeś nieprawidłowy kod PIN.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekund.</item>
+ <item quantity="other">Pięć razy wpisałeś nieprawidłowy kod PIN.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="one">Pięć razy wpisałeś nieprawidłowy kod PIN.\nSpróbuj ponownie za <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekundę.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informacje"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licencje open source"</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_menu_licenses" msgid="1257646083838406103">"Licencje open source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licencje open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Wersja"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Wersja"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opcje programisty"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Włącz tuner TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Aby dźwięk z tunera TV USB był słyszalny, telewizor powinien obsługiwać przelotowe przesyłanie sygnału AC3."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Bez tytułu"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanał zablokowany"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>E<xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Źródła kanałów"</string>
- <string name="setup_description" msgid="8728423605912915099">"Skonfiguruj kanały na żywo, korzystając z dostępnych źródeł. Może to potrwać kilka minut w zależności od źródła kanału."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Gotowe"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Dostępny jest %1$d kanał"</item>
- <item quantity="other" msgid="2386588423841837714">"Dostępne kanały: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nowe"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Źródła"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="few">%1$d kanały</item>
+ <item quantity="many">%1$d kanałów</item>
+ <item quantity="other">%1$d kanału</item>
+ <item quantity="one">%1$d kanał</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Brak dostępnych kanałów"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nowe"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nieskonfigurowany"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Poznaj inne źródła"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Przejrzyj aplikacje, które oferują telewizję online"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Dostępne są nowe źródła kanałów"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Dostępne są kanały oferowane przez nowe źródła kanałów.\nSkonfiguruj je teraz lub zrób to później w ustawieniu źródeł kanałów."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Skonfiguruj"</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>"Naciśnij SELECT"</b>", by otworzyć menu TV."</string>
@@ -191,4 +201,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Telewizja online nie jest obsługiwana na tym urządzeniu z Androidem Lollipop."</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>
</resources>
diff --git a/res/values-pt-rPT/arrays.xml b/res/values-pt-rPT/arrays.xml
index 27324526..d2249a07 100644
--- a/res/values-pt-rPT/arrays.xml
+++ b/res/values-pt-rPT/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Estreia"</item>
<item msgid="8215762047341133299">"Tecnologia/ciência"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canais em direto"</item>
+ <item msgid="7307688057853449735">"Uma forma mais simples de descobrir conteúdo"</item>
+ <item msgid="7566838222783641942">"Transferir aplicações, obter mais canais"</item>
+ <item msgid="8646630833216197238">"Personalizar a grelha de canais"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Veja o conteúdo das suas aplicações como se estivesse a ver canais de TV."</item>
+ <item msgid="1855708984677953238">"Procure o conteúdo das suas aplicações com um guia familiar e uma interface prática, \ntal como nos canais de TV."</item>
+ <item msgid="3420760668363283731">"Adicione mais canais ao instalar aplicações que ofereçam canais em direto. \nEncontre aplicações compatíveis na Google Play Store através do link no menu de TV."</item>
+ <item msgid="8974157841656828507">"Configure as novas fontes de canais instaladas para personalizar a lista de canais. \nEscolha as fontes de canais no menu Definições para começar."</item>
+ </string-array>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 8326985d..0ff8cf01 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Config. canais"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Contr. Parental"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Acerca de"</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>
@@ -84,21 +83,15 @@
<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">"Agrupar por"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Config. canais"</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 tem a classificação <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="channel_source_item_setup" msgid="1330441915487807542">"Fontes dos canais"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Novos canais disponíveis"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Person. lista de canais"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Escolher canais para guia de programação"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Não configurado"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d canal adicionado"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d canais adicionados"</item>
- </plurals>
+ <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>
+ </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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Introduziu o PIN incorreto 5 vezes.\nTente novamente daqui a <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Introduziu o PIN incorreto 5 vezes.\nTente novamente daqui a <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundos."</item>
- </plurals>
+ <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>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Acerca de"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licenças de código aberto"</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_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="about_menu_version" msgid="6303769835664868129">"Versão"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versão"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opções de programador"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Ativar sintonizador de TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Para ouvir som do sintonizador de TV USB, a TV deve ser compatível com a passagem AC3."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"T<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fontes dos canais"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configure canais em direto a partir das fontes disponíveis. Esta ação pode demorar vários minutos consoante a fonte do canal."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Concluído"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canal disponível"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canais disponíveis"</item>
- </plurals>
+ <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>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nenhum canal disponível"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nova"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Não configurada"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Obter mais fontes"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Procurar aplicações que oferecem canais em direto"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Novas fontes de canais disponíveis"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Existem novas fontes de canais com canais disponíveis.\nConfigure-as agora ou efetue essa operação mais tarde na definição de fontes de canais."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configurar agora"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, compreendi"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Prima SELECT"</b>" para aceder ao menu da TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"A tecla RETROCEDER destina-se ao dispositivo ligado. Prima o botão INÍCIO para sair."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"A aplicação Canais em direto não é compatível com este dispositivo com o Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"A aplicação Canais em direto necessita de autorização para ler as listagens de programas de TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configurar fontes"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Os canais em direto combinam a experiência dos canais de TV tradicionais com os canais de transmissão em fluxo contínuo fornecidos pelas aplicações. \n\nComece por configurar as fontes de canais já instaladas. Em alternativa, procure mais aplicações que ofereçam canais em direto na Google Play Store."</string>
</resources>
diff --git a/res/values-pt/arrays.xml b/res/values-pt/arrays.xml
index 8b3a7693..7aa5b446 100644
--- a/res/values-pt/arrays.xml
+++ b/res/values-pt/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Alto nível"</item>
<item msgid="8215762047341133299">"Tecnologia/ciência"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canais ao vivo"</item>
+ <item msgid="7307688057853449735">"Uma forma simples de descobrir conteúdos"</item>
+ <item msgid="7566838222783641942">"Fazer o download de apps, adquirir mais canais"</item>
+ <item msgid="8646630833216197238">"Personalizar a disposição dos canais"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Assista conteúdo dos seus apps da mesma forma que você assiste canais de TV."</item>
+ <item msgid="1855708984677953238">"Navegue pelo conteúdo dos seus apps com um guia familiar e uma interface simples, \nassim como os canais de TV."</item>
+ <item msgid="3420760668363283731">"Adicione mais canais instalando apps que oferecem canais ao vivo. \nEncontre apps compatíveis na Google Play Store usando o link no menu da TV."</item>
+ <item msgid="8974157841656828507">"Configure as fontes de canais recém-instaladas para personalizar sua lista de canais. \nEscolha as fontes de canais no menu \"Config.\" para começar."</item>
+ </string-array>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index d108572f..1dc878b5 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Configuração de canal"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Contr. p/ os pais"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Sobre"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Alta definição"</string>
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Configuração de canal"</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 foi classificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="channel_source_item_setup" msgid="1330441915487807542">"Fontes do canal"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Novos canais disponíveis"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Pers. lista canais"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Escolher canais para guia de programação"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Não configurado"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Não foi possível iniciar as preferências do sistema para closed captions."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d canal adicionado"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d canais adicionados"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d canais adicionados</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">"Contr. p/ os pais"</string>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Inserir novo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirme seu PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Informe seu PIN atual"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Um PIN incorreto foi digitado cinco vezes.\nTente novamente em <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Um PIN incorreto foi digitado cinco vezes.\nTente novamente em <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundos."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Você digitou o PIN errado cinco vezes.\nTente novamente em <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
+ <item quantity="other">Você digitou o PIN errado cinco vezes.\nTente novamente em <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
+ </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_about" msgid="4572960435017168299">"Sobre"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licenças de código aberto"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Config."</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_setup_new_inputs" msgid="4845822152617430787">"Novos canais disponíveis"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Controle dos pais"</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="about_menu_version" msgid="6303769835664868129">"Versão"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versão"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opções do desenvolvedor"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Ativar sintonizador de TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Para ouvir o som do sintonizador de TV USB, sua TV deve ser compatível com a passagem AC3."</string>
@@ -166,15 +164,21 @@
<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="episode_format" msgid="4881195874563241096">"T<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Fontes do canal"</string>
- <string name="setup_description" msgid="8728423605912915099">"Defina canais ao vivo a partir das fontes disponíveis. Isso pode demorar alguns minutos, dependendo da fonte do canal."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Concluído"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canal disponível"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d canais disponíveis"</item>
- </plurals>
+ <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="one">%1$d canais</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">"Novas"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Não configurada"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Adquirir mais fontes"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Procurar 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>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, entendi."</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Pressione \"SELECIONAR\""</b>" para acessar o menu da TV."</string>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"O app \"Canais ao vivo\" não é compatível com este dispositivo com Android Lollipop."</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_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>
</resources>
diff --git a/res/values-ro/arrays.xml b/res/values-ro/arrays.xml
index ef2562ef..60827ee9 100644
--- a/res/values-ro/arrays.xml
+++ b/res/values-ro/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiere"</item>
<item msgid="8215762047341133299">"Tehnică/Știință"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canale live"</item>
+ <item msgid="7307688057853449735">"Un mod simplu de a descoperi conținut"</item>
+ <item msgid="7566838222783641942">"Descărcați aplicații, obțineți mai multe canale"</item>
+ <item msgid="8646630833216197238">"Personalizați lista de canale"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Vizionați conținutul din aplicațiile dvs. așa cum ați viziona canalele pe televizor."</item>
+ <item msgid="1855708984677953238">"Căutați conținut în aplicațiile dvs. folosind un ghid familiar și o interfață plăcută,\nla fel ca în cazul canalelor pe televizor."</item>
+ <item msgid="3420760668363283731">"Adăugați mai multe canale instalând aplicații care oferă canale live. \nGăsiți aplicații compatibile în Magazinul Google Play folosind linkul din meniul televizorului."</item>
+ <item msgid="8974157841656828507">"Configurați noile surse de canale instalate ca să personalizați lista de canale. \nPentru a începe, alegeți Sursele canalelor din meniul Setări."</item>
+ </string-array>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index e82f1880..b012470e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Configurați canal"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Control parental"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Despre"</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>
@@ -84,28 +83,23 @@
<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">"Grupați după"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Configurați canal"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Acest program este blocat"</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="channel_source_item_setup" msgid="1330441915487807542">"Sursele canalelor"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Noi canale disponibile"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Person. listă canale"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Alegeți canale pentru ghidul de programe"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Neconfigurat"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Eroare la inițierea preferințelor pentru subtitrări la nivel de sistem."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"S-a adăugat %1$d canal"</item>
- <item quantity="other" msgid="1078861616751739285">"S-au adăugat %1$d de canale"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="few">%1$d canale adăugate</item>
+ <item quantity="other">%1$d de canale adăugate</item>
+ <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>
<string name="option_channels_locked" msgid="5797855082297549907">"Canale blocate"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Blocaţi toate"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Blocați toate"</string>
<string name="option_channels_unlock_all" msgid="6839513296447567623">"Deblocați toate"</string>
<string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Canale ascunse"</string>
<string name="option_program_restrictions" msgid="241342023067364108">"Restricții program"</string>
@@ -136,20 +130,26 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduceți un nou cod PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmați codul PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Introduceți codul PIN actual"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Ați introdus greșit codul PIN de 5 ori.\nÎncercați din nou peste <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> secundă."</item>
- <item quantity="other" msgid="8829550842387756054">"Ați introdus greșit codul PIN de 5 ori.\nÎncercați din nou peste <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> (de) secunde."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="few">Ați introdus codul PIN greșit de 5 ori.\nÎncercați din nou peste <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> secunde.</item>
+ <item quantity="other">Ați introdus codul PIN greșit de 5 ori.\nÎncercați din nou peste <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> de secunde.</item>
+ <item quantity="one">Ați introdus codul PIN greșit de 5 ori.\nÎncercați din nou peste <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> secundă.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Despre"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licențe open source"</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_menu_licenses" msgid="1257646083838406103">"Licențe open source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licențe open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Versiune"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versiune"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Opțiuni dezvoltator"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Activați tunerul TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Pentru a auzi sunetul tunerului TV USB, este necesar ca televizorul dvs. să accepte trecerea semnalelor AC3."</string>
- <string name="developer_menu_ac3_support" msgid="8542930057443915670">"Compatibilitatea cu conținutul audio AC3"</string>
+ <string name="developer_menu_ac3_support" msgid="8542930057443915670">"Compatibilitate audio cu AC3"</string>
<string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"Televizorul dvs. acceptă trecerea semnalelor AC3."</string>
<string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"Televizorul dvs. nu acceptă trecerea semnalelor AC3."</string>
<string name="about_menu_improve" msgid="3712578027009311401">"Contribuiți la îmbunătățirea aplicației „Canale live”"</string>
@@ -166,15 +166,22 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Fără titlu"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canal blocat"</string>
<string name="episode_format" msgid="4881195874563241096">"Sezonul <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>, episodul <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Sursele canalelor"</string>
- <string name="setup_description" msgid="8728423605912915099">"Configurați canalele live din sursele disponibile. Poate dura câteva minute, în funcție de sursa canalului."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Terminat"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d canal disponibil"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d (de) canale disponibile"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Noi"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Surse"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="few">%1$d canale</item>
+ <item quantity="other">%1$d de canale</item>
+ <item quantity="one">%1$d canal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Niciun canal disponibil"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nou"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Neconfigurată"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Găsiți mai multe surse"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Răsfoiți aplicațiile care oferă canale live"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Sunt disponibile noi surse de canale"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Descoperiți canale din noile surse de canale.\nConfigurați-le acum sau mai târziu din setarea pentru sursele de canale."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configurați acum"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, am înțeles"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Apăsați pe SELECTAȚI"</b>" pentru a accesa meniul TV."</string>
@@ -191,4 +198,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Tasta BACK este pentru dispozitivul conectat. Apăsați pe butonul HOME pentru a ieși."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Aplicația „Canale live” nu este acceptată pe acest dispozitiv cu Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Aplicația „Canale live” are nevoie de permisiunea de a citi lista de programe TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configurați sursele"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Canalele live combină experiența canalelor TV tradiționale cu cea a canalelor cu redare în flux, oferită de aplicații. \n\nÎncepeți prin a configura sursele canalelor care au fost deja instalate. Sau căutați în Magazinul Google Play mai multe aplicații care oferă canale live."</string>
</resources>
diff --git a/res/values-ru/arrays.xml b/res/values-ru/arrays.xml
index fdd92b18..db7788bb 100644
--- a/res/values-ru/arrays.xml
+++ b/res/values-ru/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Новинки"</item>
<item msgid="8215762047341133299">"Наука и техника"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Каналы Live"</item>
+ <item msgid="7307688057853449735">"Всегда есть что посмотреть"</item>
+ <item msgid="7566838222783641942">"Больше приложений – больше каналов"</item>
+ <item msgid="8646630833216197238">"Свой собственный список каналов"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Смотрите видео из приложений, как каналы на телевизоре."</item>
+ <item msgid="1855708984677953238">"Переключайте видео из приложений, как каналы на телевизоре.\n"</item>
+ <item msgid="3420760668363283731">"Добавляйте новые каналы, устанавливая приложения, поддерживающие потоковую видеотрансляцию.\nНайти такие приложения можно в Play Маркете прямо через меню телевизора."</item>
+ <item msgid="8974157841656828507">"Создавайте свои личные списки каналов.\nДля этого выберите пункт \"Источники каналов\" в меню \"Настройки\"."</item>
+ </string-array>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index da37eb3d..906535e5 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Настройка каналов"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Родительский контроль"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Информация"</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>
@@ -84,21 +83,17 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Настройка каналов"</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="channel_source_item_setup" msgid="1330441915487807542">"Источники каналов"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Доступны новые каналы"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Настроить список"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Выбрать каналы для телегида"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Не настроено"</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">
- <item quantity="one" msgid="6074059986849579215">"Добавлено каналов: %1$d"</item>
- <item quantity="other" msgid="1078861616751739285">"Добавлено каналов: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Добавлен %1$d канал</item>
+ <item quantity="few">Добавлено %1$d канала</item>
+ <item quantity="many">Добавлено %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>
@@ -136,19 +131,26 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Вы ввели неправильный PIN-код 5 раз.\nПовторите попытку через <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> сек."</item>
- <item quantity="other" msgid="8829550842387756054">"Вы ввели неправильный PIN-код 5 раз.\nПовторите попытку через <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> сек."</item>
- </plurals>
+ <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="few">Вы ввели неверный PIN-код 5 раз.\nПовторите попытку через <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунды.</item>
+ <item quantity="many">Вы ввели неверный 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_about" msgid="4572960435017168299">"Информация"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Лицензии открытого ПО"</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="about_menu_version" msgid="6303769835664868129">"Версия"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Версия"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Для разработчиков"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Включить USB-тюнер"</string>
- <string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Чтобы услышать звук при использовании USB-тюнера, телевизор должен поддерживать сквозную передачу в формате AC3."</string>
+ <string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Для воспроизведения звука при использовании USB-тюнера телевизор должен поддерживать сквозную передачу в формате AC3."</string>
<string name="developer_menu_ac3_support" msgid="8542930057443915670">"Поддержка AC3"</string>
<string name="developer_menu_ac3_support_yes" msgid="8292133113564798078">"Ваш телевизор поддерживает сквозную передачу в формате AC3."</string>
<string name="developer_menu_ac3_support_no" msgid="6509302484099707809">"Ваш телевизор не поддерживает сквозную передачу в формате AC3."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Без названия"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал заблокирован"</string>
<string name="episode_format" msgid="4881195874563241096">"Сезон <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: серия <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>, \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
- <string name="setup_title" msgid="7268875010986705651">"Источники каналов"</string>
- <string name="setup_description" msgid="8728423605912915099">"Настройка каналов прямого эфира из доступных источников. Она может занять несколько минут в зависимости от источника."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Готово"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Каналы доступны (%1$d)"</item>
- <item quantity="other" msgid="2386588423841837714">"Каналы доступны (%1$d)"</item>
- </plurals>
+ <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="few">%1$d канала</item>
+ <item quantity="many">%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_play_store_action_title" msgid="859347291072224673">"Другие источники"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Находите приложения, позволяющие смотреть телеканалы в прямом эфире"</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>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Кнопка \"Назад\" управляет подключенным устройством. Чтобы выйти, нажмите \"Главный экран\"."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Прямой эфир не поддерживается на этом устройстве с Android 5.0."</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">"Каналы Live – это сочетание обычных телеканалов и потоковых видеотрансляций, идущих через установленные приложения.\n\nНачните с настройки уже имеющихся источников контента или найдите в Play Маркете другие медиаприложения."</string>
</resources>
diff --git a/res/values-si-rLK/arrays.xml b/res/values-si-rLK/arrays.xml
index 70221dcc..657fb91d 100644
--- a/res/values-si-rLK/arrays.xml
+++ b/res/values-si-rLK/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ප්‍රමුඛ"</item>
<item msgid="8215762047341133299">"තාක්ෂණය/විද්‍යාව"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"සජීවී නාලිකා"</item>
+ <item msgid="7307688057853449735">"අන්තර්ගතය සොයා ගැනීමට සරල ක්‍රමයක්"</item>
+ <item msgid="7566838222783641942">"යෙදුම් බාගන්න, තවත් නාලිකා ලබා ගන්න"</item>
+ <item msgid="8646630833216197238">"ඔබේ නාලිකා පෙළ අභිමත කරන්න"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"TV මත නාලිකා නැරඹීම වැනි ඔබේ යෙදුම් වෙතින් අන්තර්ගතය නැරඹීම."</item>
+ <item msgid="1855708984677953238">"TV මත නාලිකා මෙන්ම හුරුපුරුදු මාර්ගෝපදේශයක් සහ මිත්‍රශීලී අතුරු මුහුණතක් සමගින්, \nඔබේ යෙදුම් වෙතින් අන්තර්ගතය බ්‍රවුස් කරන්න."</item>
+ <item msgid="3420760668363283731">"සජීවී නාලිකා පිරිනමන යෙදුම් ස්ථාපනය කිරීමෙන් තවත් නාලිකා එක් කරන්න. \nTV මෙනුව තුළ ඇති සබැඳිය භාවිත කිරීමෙන් Google Play Store තුළ ගැළපෙන යෙදුම් සොයා ගන්න."</item>
+ <item msgid="8974157841656828507">"ඔබේ නාලිකා ලැයිස්තුව අභිමත කිරීමට ඔබේ අලුතින් ස්ථාපනය කළ නාලිකා මූලාශ්‍ර පිහිටුවන්න. \nආරම්භ කිරීමට සැකසුම් මෙනුව තුළින් නාලිකා මූලාශ්‍ර තෝරන්න."</item>
+ </string-array>
</resources>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 676f9a81..ebdf4370 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"නාලිකා පිහිටුවීම්"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"මව්පිය පාලක"</string>
- <string name="options_item_about" msgid="3023532413252052050">"පිළිබඳ"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"නාලිකා පිහිටුවීම්"</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="channel_source_item_setup" msgid="1330441915487807542">"නාලිකා ප්‍රභව"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"නව නාළිකා දැන් තිබේ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"අභිරුචිකරණය කළ නාලිකා ලැයිස්තුව"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"ඔබගේ වැඩසටහන් මාර්ගෝපදේශය සඳහා නාලිකා තෝරන්න"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"සකසා නැත"</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">
- <item quantity="one" msgid="6074059986849579215">"නාලිකාව %1$d එකතු කරන ලදි"</item>
- <item quantity="other" msgid="1078861616751739285">"නාලිකා %1$d එකතු කරන ලදි"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"ඔබ වැරදි PIN අංකයක් 5 වරක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> කින් නැවත උත්සාහ කරන්න."</item>
- <item quantity="other" msgid="8829550842387756054">"ඔබ වැරදි PIN අංකයක් 5 වරක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> කින් නැවත උත්සාහ කරන්න."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"පිළිබඳ"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"විවෘත මූලාශ්‍ර වරපත්"</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="about_menu_version" msgid="6303769835664868129">"අනුවාදය"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"අනුවාදය"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"සංවර්ධක විකල්ප"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV සුසරකය සබල කරන්න"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV සුසරකයේ හඬ ඇසීමට, AC3 passthrough සඳහා ඔබේ TV සහාය දැක්විය යුතුය."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"මාතෘකාවක් නොමැත"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"නාලිකාව අවහිර කරන ලදි"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"නාලිකා ප්‍රභව"</string>
- <string name="setup_description" msgid="8728423605912915099">"ලබා ගත හැකි මූලාශ්‍ර වෙතින් සජීවී නාලිකා පිහිටුවන්න. නාලිකා මූලාශ්‍රය අනුව මෙය මිනිත්තු කිහිපයක් ගත හැකිය."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"නිමයි"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"නාලිකා %1$d ක් ලබා ගත හැකිය"</item>
- <item quantity="other" msgid="2386588423841837714">"නාලිකා %1$d ක් ලබා ගත හැකිය"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"තවත් මූලාශ්‍ර ලබා ගන්න"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"සජීවී නාලිකා පිරිනමන යෙදුම් බ්‍රවුස් කරන්න"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"සම්බන්ධිත උපාංගය සඳහා BACK යතුර. පිටවීමට Home බොත්තම ඔබන්න."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop සමගින් සජීවී නාලිකා මෙම උපාංගය මත සහාය නොදක්වයි."</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>
</resources>
diff --git a/res/values-sk/arrays.xml b/res/values-sk/arrays.xml
index 81cae65f..7c6b4d49 100644
--- a/res/values-sk/arrays.xml
+++ b/res/values-sk/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiéra"</item>
<item msgid="8215762047341133299">"Veda a technika"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Televízia online"</item>
+ <item msgid="7307688057853449735">"Jednoduchý spôsob, ako nájsť obsah"</item>
+ <item msgid="7566838222783641942">"Získajte viac kanálov sťahovaním aplikácií"</item>
+ <item msgid="8646630833216197238">"Prispôsobte si poradie kanálov"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Pozerajte obsah z aplikácií, ako keby ste pozerali kanály v televízii."</item>
+ <item msgid="1855708984677953238">"Prehliadajte obsah aplikácií pomocou známeho sprievodcu a priateľského rozhrania, \nskoro ako kanály v televízii."</item>
+ <item msgid="3420760668363283731">"Pridajte si ďalšie kanály inštalovaním aplikácií, ktoré poskytujú televíziu online. \nNájdite kompatibilné aplikácie v Obchode Google Play pomocou odkazu v ponuke televízie."</item>
+ <item msgid="8974157841656828507">"Nastavte novonainštalované zdroje kanálov a prispôsobte si tak zoznam kanálov. \nZačnite výberom zdrojov kanálov v ponuke Nastavenia."</item>
+ </string-array>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 947623d1..768b09ae 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Nastav. kanála"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Rodič. kontrola"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Informácie"</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>
@@ -84,21 +83,17 @@
<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">"Zoskupiť podľa"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Nastaviť kanál"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Tento program je zablokovaný."</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="channel_source_item_setup" msgid="1330441915487807542">"Zdroje kanálov"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"K dispozícii sú nové kanály."</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Prispôsobiť zoznam"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Vybrať kanály pre sprievodcu programom"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Nenastavené"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Celosystémové nastavenia skrytých titulkov nie je možné spustiť"</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d pridaný kanál"</item>
- <item quantity="other" msgid="1078861616751739285">"Pridané kanály: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="few">%1$d pridané kanály</item>
+ <item quantity="many">%1$d pridaného kanála</item>
+ <item quantity="other">%1$d pridaných kanálov</item>
+ <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>
@@ -136,16 +131,23 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Zadajte nový kód PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Potvrdenie kódu PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Zadanie súčasného kódu PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Zadali ste päťkrát nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- <item quantity="other" msgid="8829550842387756054">"Zadali ste päťkrát nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> s."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="few">Päťkrát ste zadali nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="many">Päťkrát ste zadali nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundy.</item>
+ <item quantity="other">Päťkrát ste zadali nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekúnd.</item>
+ <item quantity="one">Päťkrát ste zadali nesprávny kód PIN.\nSkúste to znova o <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekundu.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Informácie"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Licencie open source"</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_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_menu_licenses" msgid="1257646083838406103">"Licencie open source"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Licencie open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Verzia"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Verzia"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Možnosti pre vývojárov"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Povoliť TV tuner s rozhraním USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Ak chcete počuť zvuk TV tunera s rozhraním USB, váš televízor by mal podporovať formát AC3."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Bez názvu"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanál bol zablokovaný"</string>
<string name="episode_format" msgid="4881195874563241096">"S <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Zdroje kanálov"</string>
- <string name="setup_description" msgid="8728423605912915099">"Nastavte aktívne kanály z dostupných zdrojov. V závislosti od zdroja kanála môže táto akcia trvať aj niekoľko minút."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Hotovo"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Dostupný je %1$d kanál"</item>
- <item quantity="other" msgid="2386588423841837714">"Počet dostupných kanálov: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nové"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Zdroje"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="few">%1$d kanály</item>
+ <item quantity="many">%1$d kanála</item>
+ <item quantity="other">%1$d kanálov</item>
+ <item quantity="one">%1$d kanál</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nie sú k dispozícii žiadne kanály"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nové"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nenastavené"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Získať ďalšie zdroje"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Prehliadajte aplikácie, ktoré ponúkajú 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>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, rozumiem"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Stlačením tlačidla VYBRAŤ"</b>" prejdete do TV ponuky."</string>
@@ -191,4 +201,6 @@
<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_not_supported_device" msgid="4469404625040284722">"V tomto zariadení so systémom Android Lollipop nie sú aktívne kanály podporované."</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>
</resources>
diff --git a/res/values-sl/arrays.xml b/res/values-sl/arrays.xml
index 32070bcf..3867c26a 100644
--- a/res/values-sl/arrays.xml
+++ b/res/values-sl/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiera"</item>
<item msgid="8215762047341133299">"Tehnika/znanost"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Kanali v živo"</item>
+ <item msgid="7307688057853449735">"Preprost način odkrivanja vsebine"</item>
+ <item msgid="7566838222783641942">"Prenos aplikacij, več kanalov"</item>
+ <item msgid="8646630833216197238">"Prilagajanje izbora kanalov"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Gledanje vsebine iz aplikacij, kot bi gledali TV-kanale."</item>
+ <item msgid="1855708984677953238">"Brskanje po vsebini iz aplikacij z znanim vodnikom in preprostim vmesnikom, \ntako kot pri TV-kanalih."</item>
+ <item msgid="3420760668363283731">"Dodajanje več kanalov, tako da namestite aplikacije, ki omogočajo kanale v živo. \nIskanje združljivih aplikacij v Trgovini Google Play, tako da uporabite povezavo v TV-meniju."</item>
+ <item msgid="8974157841656828507">"Nastavitev novo nameščenih virov kanalov za prilagajanje seznama kanalov. \nČe želite začeti, v meniju z nastavitvami izberite vire kanalov."</item>
+ </string-array>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 9c6699e6..d041e42c 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Nastav. kanalov"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Staršev. nadzor"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Vizitka"</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>
@@ -84,21 +83,17 @@
<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">"Razvrsti po:"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Nastavitev kanalov"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ta program je blokiran"</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="channel_source_item_setup" msgid="1330441915487807542">"Viri kanalov"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Na voljo so novi kanali"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Prilagajanje seznama kanalov"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Izberite kanale za programski vodnik"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Ni nastavljeno"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ni mogoče začeti sistemskih nastavitev za podnapise."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Št. dodanih kanalov: %1$d"</item>
- <item quantity="other" msgid="1078861616751739285">"Št. dodanih kanalov: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d dodan kanal</item>
+ <item quantity="two">%1$d dodana kanala</item>
+ <item quantity="few">%1$d dodani kanali</item>
+ <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>
@@ -136,16 +131,23 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Vnesite novo kodo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Potrditev kode PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Vnos trenutne kode PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekundo."</item>
- <item quantity="other" msgid="8829550842387756054">"Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez toliko sekund: <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundo.</item>
+ <item quantity="two">Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundi.</item>
+ <item quantity="few">Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunde.</item>
+ <item quantity="other">Petkrat ste vnesli napačno kodo PIN.\nPoskusite znova čez <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekund.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Vizitka"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Odprtokodne licence"</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_menu_licenses" msgid="1257646083838406103">"Odprtokodne licence"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Odprtokodne licence"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Različica"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Različica"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Možnosti za razvijalce"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Omogoči sprejemnik za TV-kanale USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Če želite slišati zvok sprejemnika za TV-kanale USB, moraš vaš televizor podpirati AC3-prepustnost."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Brez naslova"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal je blokiran"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>. sezona: <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>. epizoda – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Viri kanalov"</string>
- <string name="setup_description" msgid="8728423605912915099">"Nastavitev kanalov v živo iz razpoložljivih virov. To lahko traja nekaj minut, odvisno od vira kanala."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Končano"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Na voljo je %1$d kanal"</item>
- <item quantity="other" msgid="2386588423841837714">"Na voljo je toliko kanalov: %1$d"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Novo"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Viri"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d kanal</item>
+ <item quantity="two">%1$d kanala</item>
+ <item quantity="few">%1$d kanali</item>
+ <item quantity="other">%1$d kanalov</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Ni kanalov"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Novo"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Ni nastavljeno"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Več virov"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Brskanje po aplikacijah, ki ponujajo kanale v živo"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Na voljo so novi viri kanalov"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Novi viri kanalov imajo na voljo nove kanale.\nNastavite jih ali to storite pozneje v nastavitvi za vire kanalov."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Nastavite zdaj"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"V redu, razumem"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Pritisnite »IZBIRA«"</b>", če želite dostopati do menija TV-ja."</string>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Tipka NAZAJ je za priključena naprave. Pritisnite DOMOV za izhod."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Kanali v živo niso podprti v tej napravi s sistemom Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Kanali v živo potrebujejo dovoljenje za branje televizijskih sporedov."</string>
+ <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>
</resources>
diff --git a/res/values-sr/arrays.xml b/res/values-sr/arrays.xml
index 1638027b..3a96baf4 100644
--- a/res/values-sr/arrays.xml
+++ b/res/values-sr/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Премијер"</item>
<item msgid="8215762047341133299">"Технологија/наука"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Канали уживо"</item>
+ <item msgid="7307688057853449735">"Једноставан начин да откривате садржај"</item>
+ <item msgid="7566838222783641942">"Преузимајте апликације, добијте још канала"</item>
+ <item msgid="8646630833216197238">"Прилагодите листу канала"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Гледајте садржај из апликација као да гледате канале на телевизору."</item>
+ <item msgid="1855708984677953238">"Прегледајте садржај из апликација помоћу познатог водича и једноставног интерфејса, \nкао да гледате канале на телевизору."</item>
+ <item msgid="3420760668363283731">"Додајте још канала тако што ћете инсталирати апликације које нуде канале уживо. \nПронађите компатибилне апликације у Google Play продавници помоћу линка у менију на телевизору."</item>
+ <item msgid="8974157841656828507">"Подесите недавно инсталиране изворе канала да бисте прилагодили листу канала. \nИзаберите Изворе канала у менију Подешавања да бисте започели."</item>
+ </string-array>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index f5517795..a75a21ad 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Подешав. канала"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Родитељски надзор"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Основни подаци"</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>
@@ -84,21 +83,16 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Подешавање канала"</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="channel_source_item_setup" msgid="1330441915487807542">"Извори канала"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Доступни су нови канали"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Прилагод. листу канала"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Изаберите канале за водич за програм"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Није подешен"</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">
- <item quantity="one" msgid="6074059986849579215">"Додат је %1$d канал"</item>
- <item quantity="other" msgid="1078861616751739285">"Додатих канала: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Додат је %1$d канал</item>
+ <item quantity="few">Додата су %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>
@@ -136,16 +130,22 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Унели сте погрешан PIN 5 пута.\n Покушајте поново за <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунду."</item>
- <item quantity="other" msgid="8829550842387756054">"Унели сте погрешан PIN 5 пута.\nПокушајте поново за <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> секунди."</item>
- </plurals>
+ <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="few">Унели сте погрешан 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_about" msgid="4572960435017168299">"Основни подаци"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Лиценце отвореног кода"</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="about_menu_version" msgid="6303769835664868129">"Верзија"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Верзија"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Опције за програмера"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Омогући USB тјунер за ТВ"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Да бисте чули звук USB тјунера за ТВ, ТВ треба да подржава AC3 пропуштање."</string>
@@ -166,15 +166,22 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Нема наслова"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал је блокиран"</string>
<string name="episode_format" msgid="4881195874563241096">"Серијал <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>, епизода <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Извори канала"</string>
- <string name="setup_description" msgid="8728423605912915099">"Подесите канале уживо из доступних извора. Ово може да потраје неколико минута у зависности од извора канала."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Готово"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Доступан је %1$d канал"</item>
- <item quantity="other" msgid="2386588423841837714">"Број доступних канала је %1$d"</item>
- </plurals>
+ <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="few">%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_play_store_action_title" msgid="859347291072224673">"Набави још извора"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Прегледајте апликације које нуде канале уживо"</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>" да бисте приступили TV менију."</string>
@@ -191,4 +198,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Тастер за НАЗАД је за повезане уређаје. Притисните дугме ПОЧЕТНА да бисте изашли."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Канали уживо нису подржани на овом уређају који користи Android Lollipop."</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>
</resources>
diff --git a/res/values-sv/arrays.xml b/res/values-sv/arrays.xml
index 7afb9410..46fde2cf 100644
--- a/res/values-sv/arrays.xml
+++ b/res/values-sv/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premiär"</item>
<item msgid="8215762047341133299">"Teknik/vetenskap"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Livekanaler"</item>
+ <item msgid="7307688057853449735">"Ett enkelt sätt att upptäcka innehåll"</item>
+ <item msgid="7566838222783641942">"Ladda ned appar och få fler kanaler"</item>
+ <item msgid="8646630833216197238">"Anpassa din kanallista"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Titta på innehåll från appar precis som du bläddrar mellan TV-kanaler."</item>
+ <item msgid="1855708984677953238">"Bläddra bland innehållet i appar med en guide du känner igen och ett användarvänligt gränssnitt, \nprecis som du gör med TV-kanaler."</item>
+ <item msgid="3420760668363283731">"Lägg till fler kanaler genom att installera appar som erbjuder livekanaler. \nDu hittar kompatibla appar i Google Play Butik när du klickar på länken i TV-menyn."</item>
+ <item msgid="8974157841656828507">"Anpassa din kanallista genom att konfigurera de nyinstallerade kanalkällorna. \nVälj Kanalkällor i menyn Inställningar om du vill komma igång."</item>
+ </string-array>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 8ff9e050..c8f457da 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanalinställn."</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Barnfilter"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Om"</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>
@@ -84,21 +83,15 @@
<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">"Ordna efter"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanalinställningar"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Programmet är blockerat"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanalkällor"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Det finns nya kanaler"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Anpassa kanallista"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Välj kanaler för programguiden"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Har inte konfigurerats"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Det går inte att öppna systeminställningarna för textning."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanal har lagts till"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanaler har lagts till"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanaler har lagts till</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ange en ny pinkod"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Bekräfta din pinkod"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Ange din aktuella pinkod"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Du har angett fel pinkod fem gånger.\nFörsök igen om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekund."</item>
- <item quantity="other" msgid="8829550842387756054">"Du har angett fel pinkod fem gånger.\nFörsök igen om <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> sekunder."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Du har angett fel pinkod fem gånger.\nFörsök igen om <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekunder.</item>
+ <item quantity="one">Du har angett fel pinkod fem gånger.\nFörsök igen om <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekund.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Om"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Öppen källkod"</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_menu_licenses" msgid="1257646083838406103">"Licenser för öppen källkod"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Öppen källkod"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Version"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Utvecklaralternativ"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Aktivera USB-TV-mottagare"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"TV:n måste ha stöd för AC3-vidarebefordran om ljudet ska höras från USB-TV-mottagaren."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Ingen titel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanalen har blockerats"</string>
<string name="episode_format" msgid="4881195874563241096">"Säsong <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Avsnitt <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanalkällor"</string>
- <string name="setup_description" msgid="8728423605912915099">"Ställ in livekanaler från de tillgängliga källorna. Det här kan ta några minuter beroende på kanalkällan."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Klar"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanal är tillgänglig"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanaler är tillgängliga"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Nytt"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Källor"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanaler</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Inga kanaler är tillgängliga"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nytt"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Har inte konfigurerats"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Hämta fler källor"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Sök efter appar med livekanaler"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Det finns nya kanalkällor"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Det finns nya kanalkällor med kanaler.\nKonfigurera dem nu eller gör det senare i inställningarna för kanalkällor."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Konfigurera nu"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, jag förstår"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Tryck på VÄLJ"</b>" för att öppna TV-menyn."</string>
@@ -191,4 +195,6 @@
<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_not_supported_device" msgid="4469404625040284722">"Livekanaler stöds inte på enheter med Android Lollipop."</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>
</resources>
diff --git a/res/values-sw/arrays.xml b/res/values-sw/arrays.xml
index a4106176..72fdf8ee 100644
--- a/res/values-sw/arrays.xml
+++ b/res/values-sw/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Zinazoongoza"</item>
<item msgid="8215762047341133299">"Teknolojia/Sayansi"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Televisheni Mtandaoni"</item>
+ <item msgid="7307688057853449735">"Njia rahisi ya kugundua maudhui"</item>
+ <item msgid="7566838222783641942">"Pakua programu na upate vituo zaidi"</item>
+ <item msgid="8646630833216197238">"Badilisha mpangilio wa vituo vyako jinsi upendavyo"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Tazama maudhui kwenye programu zako jinsi unavyotazama vituo vya TV."</item>
+ <item msgid="1855708984677953238">"Kagua maudhui kwenye programu zako ukitumia mwongozo unaoufahamu na kiolesura rahisi, \njinsi ilivyo kwenye vituo vya TV."</item>
+ <item msgid="3420760668363283731">"Ongeza vituo zaidi kwa kusakinisha programu zinazotoa huduma za televisheni mtandaoni. \nTafuta programu zinazoweza kutumika katika Duka la Google Play kwa kutumia kiungo kilicho ndani ya menyu ya TV."</item>
+ <item msgid="8974157841656828507">"Weka mipangilio ya vyanzo vya vituo ulivyosakinisha hivi karibuni ili ubadilishe orodha ya vituo vyako jinsi upendavyo. \n Chagua vyanzo vya vituo katika menyu ya Mipangilio ili uanze kutumia."</item>
+ </string-array>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index e77e223e..64fd515c 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kusanidi kituo"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Udhibiti wa wazazi"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Kuhusu"</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>
@@ -84,21 +83,15 @@
<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">"Panga kikundi kwa"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kusanidi kituo"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Kipindi hiki kimezuiwa"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Kipindi hiki kimekadiriwa <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="channel_source_item_setup" msgid="1330441915487807542">"Vyanzo vya vituo"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Vituo vipya vinapatikana"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Geuza orodha ya vituo iwe unavyotaka"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Chagua vituo kwa ajili ya mwongozo wa programu yako"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Haijasanidiwa"</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_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Haikuweza kuanzisha mapendeleo ya mfumo mzima kwa manukuu."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Kituo %1$d kimeongezwa"</item>
- <item quantity="other" msgid="1078861616751739285">"Vituo %1$d vimeongezwa"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Weka PIN mpya"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Thibitisha PIN yako"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Weka PIN yako ya sasa"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Uliweka PIN isiyo sahihi mara 5. \nJaribu tena baada ya sekunde <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- <item quantity="other" msgid="8829550842387756054">"Uliweka PIN isiyo sahihi mara 5. \n Jaribu tena baada ya sekunde <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Umeweka PIN isiyo sahihi mara 5.\nJaribu tena baada ya sekunde <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>.</item>
+ <item quantity="one">Umeweka PIN isiyo sahihi mara 5.\nJaribu tena baada ya sekunde <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g>.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Kuhusu"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Leseni za programu huria"</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_menu_licenses" msgid="1257646083838406103">"Leseni za programu huria"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Leseni za programu huria"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Toleo"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Toleo"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Chaguo za wasanidi programu"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Washa kitafuta vituo cha TV cha USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Ili kusikia sauti ya kitafuta vituo cha TV cha USB, TV yako inapaswa kutumia mawimbi ya AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Kichwa hakijaongezwa"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kituo kimezuiwa"</string>
<string name="episode_format" msgid="4881195874563241096">"Msimu wa <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Kipindi cha <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g><xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Vyanzo vya vituo"</string>
- <string name="setup_description" msgid="8728423605912915099">"Panga vituo vya moja kwa moja kutoka vyanzo vinavyopatikana. Hatua hii inaweza kuchukua dakika kadhaa kulingana na chanzo cha kituo."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Mwisho"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Kituo %1$d kinapatikana"</item>
- <item quantity="other" msgid="2386588423841837714">"Vituo %1$d vinapatikana"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Vipya"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Vyanzo"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">Vituo %1$d</item>
+ <item quantity="one">Kituo %1$d</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Hakuna kituo kinachopatikana"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Mpya"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Mipangilio haijawekwa"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Pata vyanzo zaidi"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Kagua programu zinazotoa vituo vya moja kwa moja"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Vyanzo vipya vya vituo vinavyopatikana"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Kuna vituo katika vyanzo vipya vya vituo. \nWeka vituo hivyo sasa au baadaye katika mipangilio ya vyanzo vya vituo."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Weka mipangilio sasa"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Sawa, nimeelewa"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Bonyeza CHAGUA "</b>" ili ufikie menyu ya televisheni."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Kitufe cha NYUMA ni kwa ajili ya kifaa kilichounganishwa. Bonyeza kitufe cha MWANZO ili uondoe."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Kipengele cha Vituo vya Moja kwa Moja hakiwezi kutumiwa kwenye kifaa hiki kwa kutumia Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Kipengele cha Vituo vya Moja kwa Moja kinahitaji idhini ili kione orodha ya vipindi vya televisheni."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Weka mipangilio ya vyanzo vyako"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Televisheni mtandaoni hujumuisha hali ya matumizi ya vituo vya TV ya kawaida na vituo vya utiririshaji vinavyotolewa na programu. \n\nAnza kutumia kwa kuweka mipangilio ya vyanzo vya vituo ambavyo tayari vimesakinishwa. Au kagua Duka la Google Play ili upate programu zaidi zinazotoa huduma za televisheni mtandaoni."</string>
</resources>
diff --git a/res/values-ta-rIN/arrays.xml b/res/values-ta-rIN/arrays.xml
index 3281292f..9d2c1f24 100644
--- a/res/values-ta-rIN/arrays.xml
+++ b/res/values-ta-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ப்ரீமியர்"</item>
<item msgid="8215762047341133299">"தொழில்நுட்பம்/அறிவியல்"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"நேரலைச் சேனல்கள்"</item>
+ <item msgid="7307688057853449735">"உள்ளடக்கத்தைத் தேடுவதற்கான எளிய வழி"</item>
+ <item msgid="7566838222783641942">"பயன்பாடுகளை இறக்கி, கூடுதல் சேனல்களைப் பெறலாம்"</item>
+ <item msgid="8646630833216197238">"சேனல் வரிசையைத் தனிப்பயனாக்கலாம்"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"டிவியில் சேனல்களைப் பார்ப்பதைப் போன்றே, பயன்பாடுகளின் உள்ளடக்கத்தைப் பார்க்கலாம்."</item>
+ <item msgid="1855708984677953238">"டிவியில் சேனல்களைப் பார்ப்பதைப் போன்றே, \nபயன்படுத்துவதற்கு எளிதான வழிகாட்டி மற்றும் அறிமுகமான இடைமுகத்தின் மூலம் பயன்பாடுகளின் உள்ளடக்கத்தில் உலாவலாம்."</item>
+ <item msgid="3420760668363283731">"நேரலைச் சேனல்களை வழங்கும் பயன்பாடுகளை நிறுவி கூடுதல் சேனல்களைச் சேர்க்கலாம். \nடிவி மெனுவில் உள்ள இணைப்பைப் பயன்படுத்தி Google Play ஸ்டோரில் இணக்கமான பயன்பாடுகளைக் கண்டறியலாம்."</item>
+ <item msgid="8974157841656828507">"சேனல் பட்டியலைத் தனிப்பயனாக்க, புதிதாக நிறுவிய சேனல் மூலங்களை அமைக்கலாம். \nதொடங்க, அமைப்புகள் மெனுவில் உள்ள சேனல் மூலங்களைத் தேர்வுசெய்யலாம்."</item>
+ </string-array>
</resources>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index ae74eea5..095a9661 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"சேனல் அமைவு"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"பெற்றோர் கட்டுப்பாடுகள்"</string>
- <string name="options_item_about" msgid="3023532413252052050">"அறிமுகம்"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"சேனல் அமைவு"</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="channel_source_item_setup" msgid="1330441915487807542">"சேனல் மூலங்கள்"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"புதிய சேனல்கள் உள்ளன"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"சேனலை தனிப்படுத்து"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"நிகழ்ச்சி வழிகாட்டி சேனல்களைத் தேர்வுசெய்"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"அமைக்கப்படவில்லை"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d சேனல் சேர்க்கப்பட்டது"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d சேனல்கள் சேர்க்கப்பட்டன"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"5 முறை தவறாக பின்னை உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> வினாடி கழித்து மீண்டும் முயற்சிக்கவும்."</item>
- <item quantity="other" msgid="8829550842387756054">"5 முறை தவறாக பின்னை உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> வினாடிகள் கழித்து மீண்டும் முயற்சிக்கவும்."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"அறிமுகம்"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ஓப்பன் சோர்ஸ் உரிமங்கள்"</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="about_menu_version" msgid="6303769835664868129">"பதிப்பு"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"பதிப்பு"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"டெவெலப்பர் விருப்பங்கள்"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB டிவி ட்யூனரை இயக்கு"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB டிவி ட்யூனரின் ஒலியைக் கேட்க, டிவி AC3 அசல் ஒலியை ஆதரிக்க வேண்டும்."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"தலைப்பு இல்லை"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"சேனல் தடுக்கப்பட்டது"</string>
<string name="episode_format" msgid="4881195874563241096">"சீ<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: எபி. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"சேனல் மூலங்கள்"</string>
- <string name="setup_description" msgid="8728423605912915099">"கிடைக்கக்கூடிய மூலங்களிலிருந்து நேரலைச் சேனல்களை அமைக்கவும். சேனல் மூலத்தைப் பொறுத்து, இதற்கு சில நிமிடங்கள் ஆகலாம்."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"முடிந்தது"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d சேனல் உள்ளது"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d சேனல்கள் உள்ளன"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"கூடுதல் மூலங்களைப் பெறுக"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"நேரலை சேனல்களை வழங்கும் பயன்பாடுகளைத் தேடுக"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Back விசை இணைத்த சாதனத்திற்கானது. வெளியேற, Home பட்டனை அழுத்துக."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop இல் இயங்கும் இந்தச் சாதனத்தில் நேரலைச் சேனல்களுக்கு ஆதரவில்லை."</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>
</resources>
diff --git a/res/values-te-rIN/arrays.xml b/res/values-te-rIN/arrays.xml
index b5104952..de6abf32 100644
--- a/res/values-te-rIN/arrays.xml
+++ b/res/values-te-rIN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ప్రీమియర్"</item>
<item msgid="8215762047341133299">"సాంకేతికం/శాస్త్రం"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"ప్రత్యక్ష ప్రసార ఛానెల్‌లు"</item>
+ <item msgid="7307688057853449735">"కంటెంట్‌ను కనుగొనడానికి సులభమైన మార్గం"</item>
+ <item msgid="7566838222783641942">"అనువర్తనాలను డౌన్‌లోడ్ చేసుకోండి, మరిన్ని ఛానెల్‌లను పొందండి"</item>
+ <item msgid="8646630833216197238">"మీ ఛానెల్ క్రమాన్ని అనుకూలీకరించండి"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"టీవీలో ఛానెల్‌లు చూస్తున్నట్లుగా మీ అనువర్తనాల్లో కంటెంట్‌ను చూడండి."</item>
+ <item msgid="1855708984677953238">"టీవీలో ఛానెల్‌ల మాదిరిగా \nమీ అనువర్తనాల్లో కంటెంట్‌ను సుపరిచయ మార్గదర్శిని మరియు స్నేహపూర్వక ఇంటర్‌ఫేస్‌తో బ్రౌజ్ చేయండి."</item>
+ <item msgid="3420760668363283731">"ప్రత్యక్ష ప్రసార ఛానెల్‌లను ఆఫర్ చేసే అనువర్తనాలను ఇన్‌స్టాల్ చేసుకోవడం ద్వారా మరిన్ని ఛానెల్‌లను జోడించండి. \nటీవీ మెనులోని లింక్‌ను ఉపయోగించడం ద్వారా Google Play స్టోర్‌లో అనుకూల అనువర్తనాలను కనుగొనండి."</item>
+ <item msgid="8974157841656828507">"మీ ఛానెల్ జాబితాను అనుకూలీకరించడానికి కొత్తగా ఇన్‌స్టాల్ చేయబడిన మీ ఛానెల్ మూలాధారాలను సెటప్ చేయండి. \nప్రారంభించడానికి సెట్టింగ్‌ల మెనులో ఛానెల్ మూలాధారాలను ఎంచుకోండి."</item>
+ </string-array>
</resources>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index 398ec7f1..5505a8ac 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"ఛానెల్ సెటప్"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"పేరెం. నియంత్ర."</string>
- <string name="options_item_about" msgid="3023532413252052050">"పరిచయం"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"ఛానెల్ సెటప్"</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="channel_source_item_setup" msgid="1330441915487807542">"ఛానెల్ సోర్స్‌లు"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"కొత్త ఛానెల్‌లు అందుబాటులో ఉన్నప్పుడు"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"ఛానెల్‌ జాబితాను అనుకూలీకరించండి"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"మీ ప్రోగ్రామ్ గైడ్ కోసం ఛానె. ఎంచుకోండి"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"సెటప్ చేయలేదు"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ఛానెల్ జోడించబడింది"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ఛానెల్‌లు జోడించబ."</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> సెకనులో మళ్లీ ప్రయత్నించండి."</item>
- <item quantity="other" msgid="8829550842387756054">"మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"పరిచయం"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ఓపెన్ సోర్స్ లైసెన్స్‌లు"</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="about_menu_version" msgid="6303769835664868129">"సంస్కరణ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"సంస్కరణ"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"డెవలపర్ ఎంపికలు"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB టీవీ ట్యూనర్‌ను ప్రారంభించు"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB టీవీ ట్యూనర్ శబ్దం వినిపించడానికి, మీ టీవీ AC3 గుండా ప్రసరణకు మద్దతు ఇవ్వాలి."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"శీర్షిక లేదు"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ఛానెల్ బ్లాక్ చేయబడింది"</string>
<string name="episode_format" msgid="4881195874563241096">"సీ.<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ఎపి. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"ఛానెల్ సోర్స్‌లు"</string>
- <string name="setup_description" msgid="8728423605912915099">"అందుబాటులో ఉన్న సోర్స్‌ల నుండి లైవ్ ఛానెల్‌లను సెటప్ చేయండి. ఛానెల్ సోర్స్‌ను బట్టి దీనికి కొన్ని నిమిషాలు పట్టవచ్చు."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"పూర్తయింది"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ఛానెల్ అందుబాటులో ఉంది"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ఛానెల్‌లు అందుబాటులో ఉన్నాయి"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"మరిన్ని మూలాలను పొందండి"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"ప్రత్యక్ష ప్రసార ఛానెల్‌లను అందించే అనువర్తనాలను బ్రౌజ్ చేయండి"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"BACK కీ కనెక్ట్ చేయబడిన పరికరం కోసం ఉద్దేశించినది. నిష్క్రమించడానికి HOME బటన్‌ను నొక్కండి."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Android Lollipop అమలులో ఉన్న ఈ పరికరంలో ప్రత్యక్ష ప్రసార ఛానెల్‌లకు మద్దతు లేదు."</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>
</resources>
diff --git a/res/values-th/arrays.xml b/res/values-th/arrays.xml
index 4a3f7236..105725f8 100644
--- a/res/values-th/arrays.xml
+++ b/res/values-th/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"ปฐมทัศน์"</item>
<item msgid="8215762047341133299">"วิทยาศาสตร์/เทคฯ"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"รายการถ่ายทอดสด"</item>
+ <item msgid="7307688057853449735">"วิธีง่ายๆ ในการค้นพบเนื้อหา"</item>
+ <item msgid="7566838222783641942">"ดาวน์โหลดแอปเพื่อรับช่องต่างๆ เพิ่ม"</item>
+ <item msgid="8646630833216197238">"กำหนดช่องรายการของคุณเอง"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"ชมเนื้อหาจากแอปของคุณได้ราวกับรับชมช่องรายการทางทีวี"</item>
+ <item msgid="1855708984677953238">"เรียกดูเนื้อหาจากแอปของคุณได้ด้วยคู่มือที่คุณคุ้นเคยและอินเทอร์เฟซที่ใช้งานง่าย \nเหมือนกับช่องรายการทางทีวี"</item>
+ <item msgid="3420760668363283731">"เพิ่มช่องได้ด้วยการติดตั้งแอปที่เสนอช่องถ่ายทอดสด \nค้นหาแอปที่เข้ากันได้ใน Google Play สโตร์โดยใช้ลิงก์ในเมนูทีวี"</item>
+ <item msgid="8974157841656828507">"ตั้งค่าแหล่งที่มาของช่องที่ติดตั้งใหม่เพื่อกำหนดรายการช่องของคุณเอง \nเลือกแหล่งที่มาของช่องในเมนูการตั้งค่าเพื่อเริ่มต้นใช้งาน"</item>
+ </string-array>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index f19061bb..2b6d2f75 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"การตั้งค่าช่อง"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"ผู้ปกครองควบคุม"</string>
- <string name="options_item_about" msgid="3023532413252052050">"เกี่ยวกับ"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"การตั้งค่าช่อง"</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="channel_source_item_setup" msgid="1330441915487807542">"แหล่งที่มาของช่อง"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"มีช่องใหม่ให้บริการ"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"กำหนดค่ารายการช่อง"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"เลือกช่องสำหรับคู่มือโปรแกรมของคุณ"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"ไม่ได้ตั้งค่า"</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">
- <item quantity="one" msgid="6074059986849579215">"เพิ่มแล้ว %1$d ช่อง"</item>
- <item quantity="other" msgid="1078861616751739285">"เพิ่มแล้ว %1$d ช่อง"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"คุณป้อน PIN ผิด 5 ครั้งแล้ว\nลองอีกครั้งใน <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> วินาที"</item>
- <item quantity="other" msgid="8829550842387756054">"คุณป้อน PIN ผิด 5 ครั้งแล้ว\nลองอีกครั้งใน <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> วินาที"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"เกี่ยวกับ"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"ใบอนุญาตโอเพนซอร์ส"</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="about_menu_version" msgid="6303769835664868129">"เวอร์ชัน"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"เวอร์ชัน"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ตัวเลือกสำหรับนักพัฒนา"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"เปิดใช้ตัวรับสัญญาณทีวีผ่าน USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"หากต้องการได้ยินเสียงของตัวรับสัญญาณทีวีผ่าน USB ทีวีของคุณต้องสนับสนุนการส่งผ่าน AC3"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"ไม่มีชื่อ"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"บล็อกช่องแล้ว"</string>
<string name="episode_format" msgid="4881195874563241096">"ซีซัน <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: ตอนที่ <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"แหล่งที่มาของช่อง"</string>
- <string name="setup_description" msgid="8728423605912915099">"ตั้งค่าช่องสดจากแหล่งที่มาที่พร้อมใช้งาน ขั้นตอนนี้อาจใช้เวลาหลายนาทีขึ้นอยู่กับแหล่งที่มาของช่อง"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"เสร็จสิ้น"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"มี %1$d ช่อง"</item>
- <item quantity="other" msgid="2386588423841837714">"มี %1$d ช่อง"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"รับแหล่งที่มาเพิ่มเติม"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"เรียกดูแอปที่เสนอรายการถ่ายทอดสด"</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>" เพื่อเข้าถึงเมนู TV"</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"แป้นกลับมีไว้สำหรับอุปกรณ์ที่เชื่อมต่อ กดปุ่มหน้าแรกเพื่อออก"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Live TV ไม่ได้รับการสนับสนุนบนอุปกรณ์นี้ซึ่งมี Android Lollipop"</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>
</resources>
diff --git a/res/values-tl/arrays.xml b/res/values-tl/arrays.xml
index 19be2040..3c1bf603 100644
--- a/res/values-tl/arrays.xml
+++ b/res/values-tl/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premier"</item>
<item msgid="8215762047341133299">"Teknolohiya/Agham"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Mga Live na Channel"</item>
+ <item msgid="7307688057853449735">"Isang simpleng paraan upang tumuklas ng content"</item>
+ <item msgid="7566838222783641942">"Mag-download ng mga app, makakuha ng higit pang mga channel"</item>
+ <item msgid="8646630833216197238">"I-customize ang iyong listahan ng channel"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Manood ng content mula sa iyong mga app tulad ng panonood ng mga channel sa TV."</item>
+ <item msgid="1855708984677953238">"Mag-browse ng content mula sa iyong mga app gamit ang isang pamilyar na gabay at madaling gamitin na interface, \ntulad ng mga channel sa TV."</item>
+ <item msgid="3420760668363283731">"Magdagdag ng higit pang mga channel sa pamamagitan ng pag-i-install ng mga app na nag-aalok ng mga live na channel. \nMaghanap ng mga tumutugmang app sa Google Play Store sa pamamagitan ng paggamit sa link sa loob ng menu ng TV."</item>
+ <item msgid="8974157841656828507">"I-set up ang iyong bagong na-install na mga pinagmulan ng channel upang i-customize ang iyong listahan ng channel. \nPiliin ang Mga pinagmulan ng channel sa loob ng menu ng Mga Setting upang magsimula."</item>
+ </string-array>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 4ff04b91..7cacf4bf 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Channel setup"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Parental controls"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Tungkol dito"</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>
@@ -84,21 +83,15 @@
<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">"Ipangkat ayon sa"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Setup ng channel"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Naka-block 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="channel_source_item_setup" msgid="1330441915487807542">"Mga channel source"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Available ang mga bagong channel"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Customize channel list"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Pumili ng mga channel para sa gabay sa programa"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Hindi naka-set up"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Hindi masimulan ang mga kagustuhan sa buong system para sa mga closed caption."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d channel ang nadagdag"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d channel ang nadagdag"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Nagdagdag ng %1$d channel</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ilagay ang bagong PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Kumpirmahin ang iyong PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Ilagay ang iyong kasalukuyang PIN"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"5 beses kang naglagay ng maling PIN.\nSubukang muli sa loob ng <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> segundo."</item>
- <item quantity="other" msgid="8829550842387756054">"5 beses kang naglagay ng maling PIN.\nSubukang muli sa loob ng <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> (na) segundo."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Inilagay mo ang maling PIN nang 5 beses.\nSubukang muli sa loob ng <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundo.</item>
+ <item quantity="other">Inilagay mo ang maling PIN nang 5 beses.\nSubukang muli sa loob ng <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> na segundo.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Tungkol dito"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Mga lisensyang open source"</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_menu_licenses" msgid="1257646083838406103">"Mga open source na lisensya"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Mga lisensyang open source"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Bersyon"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Bersyon"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Mga opsyon ng developer"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"I-enable ang USB TV tuner"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Upang marinig ang tunog ng USB TV tuner, dapat suportahan ng iyong TV ang AC3 passthrough."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Walang pamagat"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Naka-block ang channel"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Mga pinagmumulan ng channel"</string>
- <string name="setup_description" msgid="8728423605912915099">"Mag-set up ng mga live na channel mula sa mga available na pinagmulan. Maaari itong umabot ng ilang minuto depende sa pinagmulan ng channel."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Tapos na"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d channel ang available"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d (na) channel ang available"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Bago"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Mga Pinagmumulan"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d channel</item>
+ <item quantity="other">%1$d na channel</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Walang mga channel na available"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Bago"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Hindi naka-set up"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Kumuha ng higit pang mga mapagkukunan"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Mag-browse ng mga app na nag-aalok ng mga live channel"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"May mga bagong mapagkukunan ng channel"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"May mga inaalok na channel ang mga bagong mapagkukunan ng channel.\nI-set up na ang mga ito ngayon, o gawin ito sa ibang pagkakataon sa setting ng mga pinagkukunan ng channel."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"I-set up ngayon"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, nakuha ko"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Pindutin ang SELECT"</b>" upang i-access ang menu ng TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Ang BACK key ay para sa nakakonektang device. Pindutin ang HOME button upang lumabas."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Hindi sinusuportahan ang Live TV sa device na ito na may Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Kailangan ng pahintulot ng Live TV upang mabasa ang mga listahan sa TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"I-set up ang iyong mga pinagmulan"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Mapapanood sa mga live channel ang mga ipinapalabas sa mga nakasanayan nang TV channel at sa mga streaming channel na mula sa mga app. \n\nMagsimula sa pamamagitan ng pagse-set up ng mga pinagmulan ng channel na naka-install na. O mag-browse sa Google Play Store para sa higit pang mga app na nag-aalok ng mga live na channel."</string>
</resources>
diff --git a/res/values-tr/arrays.xml b/res/values-tr/arrays.xml
index 6e29e7f0..3dfd8e76 100644
--- a/res/values-tr/arrays.xml
+++ b/res/values-tr/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"İlk Gösterim"</item>
<item msgid="8215762047341133299">"Teknoloji/Bilim"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Canlı Yayın Kanalları"</item>
+ <item msgid="7307688057853449735">"İçeriği keşfetmenin basit bir yolu"</item>
+ <item msgid="7566838222783641942">"Uygulamaları indirin, daha çok kanal alın"</item>
+ <item msgid="8646630833216197238">"Kanal listenizi özelleştirin"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Uygulamalarınızdaki içerikleri TV\'nizdeki kanalları izler gibi izleyin."</item>
+ <item msgid="1855708984677953238">"Uygulamalarınızdaki içeriklere bildiğiniz bir rehber ve kullanıcı dostu bir arayüzle göz atın, \ntıpkı TV\'deki kanallarda olduğu gibi."</item>
+ <item msgid="3420760668363283731">"Canlı kanallar sunan uygulamalar yükleyerek daha fazla kanal ekleyin. \nTV menüsündeki bağlantıyı kullanarak Google Play Store\'daki uyumlu uygulamaları bulun."</item>
+ <item msgid="8974157841656828507">"Kanal listenizi özelleştirmek için yeni yüklediğiniz kanal kaynaklarını ayarlayın. \nBaşlangıç olarak Ayarlar menüsünden Kanal kaynaklarını seçin."</item>
+ </string-array>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 5ef1549e..9856bafc 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanal kurulumu"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ebeveyn denetimi"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Hakkında"</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>
@@ -84,21 +83,15 @@
<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">"Gruplama ölçütü"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanal kurulumu"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Bu program engellendi"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanal kaynakları"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Yeni kanallar mevcut"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Kanal listesini özelleştir"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Program rehberiniz için kanalları seçin"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Yapılandırılmadı"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Altyazılar için sistem genelinde tercihler başlatılamıyor."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d kanal eklendi"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d kanal eklendi"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanal eklendi</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Yeni PIN\'i girin"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"PIN\'inizi onaylayın"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Geçerli PIN\'inizi girin"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"PIN\'i 5 kez yanlış girdiniz.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> saniye içinde tekrar deneyin."</item>
- <item quantity="other" msgid="8829550842387756054">"PIN\'i 5 kez yanlış girdiniz.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> saniye içinde tekrar deneyin."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">5 kez yanlış PIN girdiniz.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> saniye sonra tekrar deneyin.</item>
+ <item quantity="one">5 kez yanlış PIN girdiniz.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> saniye sonra tekrar deneyin.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Hakkında"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Açık kaynak lisansları"</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_menu_licenses" msgid="1257646083838406103">"Açık kaynak lisansları"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Açık kaynak lisansları"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Sürüm"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Sürüm"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Geliştirici seçenekleri"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV kanal ayarlayıcıyı etkinleştir"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV kanal ayarlayıcıdan ses alabilmek için TV\'nizin AC3 geçişini desteklemesi gerekir."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Başlıksız"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal engellendi"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Böl. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanal kaynakları"</string>
- <string name="setup_description" msgid="8728423605912915099">"Kullanılabilir kaynaklardan canlı yayın kanallarını kurun. Bu işlem, kanal kaynağına bağlı olarak birkaç dakika sürebilir."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Bitti"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d kanal kullanılabilir"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d kanal kullanılabilir"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Yeni"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Kaynaklar"</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">"Kullanılabilir kanal yok"</string>
<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_play_store_action_title" msgid="859347291072224673">"Daha fazla kaynak al"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Canlı kanallar sunan uygulamalara göz at"</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>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Tamam, anladım"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307">"TV menüsüne erişmek için "<b>"SEÇ\'e basın"</b>"."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"GERİ tuşu bağlı cihazlar içindir. Çıkmak için ANA SAYFA düğmesine basın."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Bu cihazda Android Lollipop ile Canlı Kanallar desteklenmemektedir."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canlı Kanallar\'ın TV kanal listesini okuması için izin gerekiyor."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Kaynaklarınızı ayarlayın"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Canlı kanallar, geleneksel TV kanallarının deneyimini uygulamalar tarafından sağlanan kanal akışlarıyla birleştirir. \n\nHalihazırda yüklü kanal kaynaklarını ayarlayarak başlayın. İsterseniz canlı kanallar sunan diğer uygulamalar için Google Play Store\'a göz atabilirsiniz."</string>
</resources>
diff --git a/res/values-uk/arrays.xml b/res/values-uk/arrays.xml
index 052fff6b..4dba1d71 100644
--- a/res/values-uk/arrays.xml
+++ b/res/values-uk/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Популярне"</item>
<item msgid="8215762047341133299">"Наука й техніка"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Телеканали"</item>
+ <item msgid="7307688057853449735">"Простий спосіб знаходити вміст"</item>
+ <item msgid="7566838222783641942">"Завантажуйте додатки й отримуйте більше каналів"</item>
+ <item msgid="8646630833216197238">"Упорядковуйте список каналів"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Переглядайте вміст зі своїх додатків так само, як канали на телевізорі."</item>
+ <item msgid="1855708984677953238">"Знайомий посібник і зручний інтерфейс допоможуть вам переглядати вміст зі своїх додатків так само, \nяк канали на телевізорі."</item>
+ <item msgid="3420760668363283731">"Щоб додавати нові джерела, установлюйте додатки з телеканалами. \nЗнаходьте сумісні додатки в магазині Google Play за посиланням у меню телевізора."</item>
+ <item msgid="8974157841656828507">"Налаштуйте нещодавно встановлені джерела, щоб упорядкувати список каналів. \nЩоб почати, виберіть опцію \"Джерела каналів\" у меню \"Налаштування\"."</item>
+ </string-array>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index aae16b6c..a15fb797 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Налашт. каналів"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Батьк. контроль"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Інформація"</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>
@@ -84,21 +83,17 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Налаштув. каналів"</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="channel_source_item_setup" msgid="1330441915487807542">"Джерела каналів"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Доступні нові канали"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Налашт.спис.канал."</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Вибір каналів для програми телепередач"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Не налаштовано"</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">
- <item quantity="one" msgid="6074059986849579215">"Додано %1$d канал"</item>
- <item quantity="other" msgid="1078861616751739285">"Додано каналів: %1$d"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Додано %1$d канал</item>
+ <item quantity="few">Додано %1$d канали</item>
+ <item quantity="many">Додано %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>
@@ -136,16 +131,23 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"Ви 5 разів неправильно ввели PIN-код.\nПовторіть спробу через <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> с."</item>
- <item quantity="other" msgid="8829550842387756054">"Ви 5 разів неправильно ввели PIN-код.\nПовторіть спробу через <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> с."</item>
- </plurals>
+ <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="few">Ви 5 разів неправильно ввели PIN-код.\nПовторіть спробу через <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунди.</item>
+ <item quantity="many">Ви 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_about" msgid="4572960435017168299">"Інформація"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Ліцензії ПЗ з відкритим кодом"</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="about_menu_version" msgid="6303769835664868129">"Версія"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Версія"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Параметри розробника"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Увімкнути ТВ-тюнер USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Щоб ваш телевізор сприймав звук ТВ-тюнера USB, на ньому має підтримуватися транзит AC3."</string>
@@ -166,15 +168,23 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Без назви"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал заблоковано"</string>
<string name="episode_format" msgid="4881195874563241096">"Сезон <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>, серія <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>: \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
- <string name="setup_title" msgid="7268875010986705651">"Джерела каналів"</string>
- <string name="setup_description" msgid="8728423605912915099">"Налаштуйте активні канали з доступних джерел. Залежно від джерела, це може зайняти декілька хвилин."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Готово"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Доступний %1$d канал"</item>
- <item quantity="other" msgid="2386588423841837714">"Доступно каналів: %1$d"</item>
- </plurals>
+ <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="few">%1$d канали</item>
+ <item quantity="many">%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_play_store_action_title" msgid="859347291072224673">"Отримати більше джерел"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Переглянути додатки, які пропонують телеканали"</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>
@@ -191,4 +201,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Клавіша \"НАЗАД\" діє на підключеному пристрої. Натисніть \"ГОЛОВНИЙ ЕКРАН\", щоб вийти."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Додаток Live TV не підтримується на цьому пристрої з ОС Android Lollipop."</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>
</resources>
diff --git a/res/values-ur-rPK/arrays.xml b/res/values-ur-rPK/arrays.xml
index fd6a0bed..f54b4914 100644
--- a/res/values-ur-rPK/arrays.xml
+++ b/res/values-ur-rPK/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"پریمیئر"</item>
<item msgid="8215762047341133299">"ٹیک/سائنس"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"لائیو چینلز"</item>
+ <item msgid="7307688057853449735">"مواد دریافت کرنے کا ایک سادہ طریقہ"</item>
+ <item msgid="7566838222783641942">"ایپس ڈاؤن لوڈ کریں، مزید چینلز حاصل کریں"</item>
+ <item msgid="8646630833216197238">"اپنا چینل لائن اپ حسب ضرورت بنائیں"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"‏TV پر چینلز دیکھنے کی طرح اپنی ایپس سے مواد دیکھیں۔"</item>
+ <item msgid="1855708984677953238">"‏ایک مانوس گائیڈ اور دوستانہ انٹرفیس کے ساتھ اپنی ایپس سے مواد براؤز کریں، \nبالکل TV چینلز کی طرح۔"</item>
+ <item msgid="3420760668363283731">"‏لائیو چینلز کی پیشکش کرنے والی ایپس انسٹال کر کے مزید چینلز شامل کریں۔\nTVمینو کے اندر دیا گیا لنک استعمال کر کے Google Play اسٹور میں موافق ایپس تلاش کریں۔"</item>
+ <item msgid="8974157841656828507">"اپنے چینل کی فہرست کو حسب ضرورت بنانے کیلئے اپنے نئے انسٹال کردہ چینل ذرائع سیٹ اپ کریں۔ \nشروع کرنے کیلئے ترتیبات مینو کے اندر موجود چینل ذرائع سے انتخاب کریں۔"</item>
+ </string-array>
</resources>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index a342f874..d49edc92 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"چینل سیٹ اپ"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"والدین کے کنٹرولز"</string>
- <string name="options_item_about" msgid="3023532413252052050">"تفصیل"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"چینل سیٹ اپ"</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="channel_source_item_setup" msgid="1330441915487807542">"چینل کے مآخذ"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"نئے چینلز دستیاب ہیں"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"چینل لسٹ کسٹمائز کریں"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"اپنی پروگرام گائیڈ کیلئے چینلز منتخب کریں"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"ترتیب نہیں دیا گیا"</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">
- <item quantity="one" msgid="6074059986849579215">"‏%1$d چینل شامل کیا گیا"</item>
- <item quantity="other" msgid="1078861616751739285">"‏%1$d چینلز شامل کیے گئے"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"‏آپ نے 5 بار غلط PIN درج کر دیا ہے۔\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> سیکنڈ بعد دوبارہ کوشش کریں۔"</item>
- <item quantity="other" msgid="8829550842387756054">"‏آپ نے 5 بار غلط PIN درج کر دیا ہے۔\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> سیکنڈ بعد دوبارہ کوشش کریں۔"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"تفصیل"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"اوپن سورس لائسنسز"</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="about_menu_version" msgid="6303769835664868129">"ورژن"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ورژن"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"ڈیولپر کے اختیارات"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"‏USB TV ٹیونر فعال کریں"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"‏USB TV ٹیونر کی آواز سننے کیلئے، آپ کے TV کو AC3 پاس تھرو کی معاونت کرنی چاہئیے۔"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"کوئی عنوان نہیں ہے"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"چینل مسدود کر دیا گیا"</string>
<string name="episode_format" msgid="4881195874563241096">"سیزن <xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: قسط <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"چینل کے مآخذ"</string>
- <string name="setup_description" msgid="8728423605912915099">"دستیاب مآخذ سے لائیو چینلز کو ترتیب دیں۔ چینل کے ماخذ کی بنیاد پر اس میں کئی منٹ لگ سکتے ہیں۔"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"ہوگیا"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"‏%1$d چینل دستیاب ہے"</item>
- <item quantity="other" msgid="2386588423841837714">"‏%1$d چینلز دستیاب ہیں"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"مزید مآخذ حاصل کریں"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"لائیو چینلز کی پیشکش کرنے والی ایپس براؤز کریں"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"‏BACK کلید منسلک آلہ کیلئے ہے۔ باہر نکلنے کیلئے HOME بٹن دبائیں۔"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"‏Android Lollipop والے اس آلے پر لائیو چینلز کی معاونت نہیں ہے۔"</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>
</resources>
diff --git a/res/values-uz-rUZ/arrays.xml b/res/values-uz-rUZ/arrays.xml
index ca5bb774..71619002 100644
--- a/res/values-uz-rUZ/arrays.xml
+++ b/res/values-uz-rUZ/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Premyera"</item>
<item msgid="8215762047341133299">"Fan va texnika"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Jonli efir"</item>
+ <item msgid="7307688057853449735">"Kontent bilan tanishishning sodda yo‘li"</item>
+ <item msgid="7566838222783641942">"Qo‘chimcha kanallarni ko‘rish uchun ilovalar yuklab olish"</item>
+ <item msgid="8646630833216197238">"Kanallar tartibini sozlang"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Televizorda kanallarni ko‘rgandek, ilovalaringizda ham kontentni shunday tomosha qiling."</item>
+ <item msgid="1855708984677953238">"Televizordagi kanallardek, ilovalaringizdagi kontentlarni \no‘zinga tanish teledasturlar va qulay interfeys yordamida ko‘ring."</item>
+ <item msgid="3420760668363283731">"Jonli efirlarni taklif qiluvchi qo‘shimcha kanallarni qo‘shish uchun ilovalar o‘rnating. \nTV menyusidagi havolalar yordamida Google Play Marketda mos ilovalarni toping."</item>
+ <item msgid="8974157841656828507">"Kanallar ro‘yxatini moslashtirish uchun yangi o‘rnatilgan manbalarni sozlang. \nBoshlash uchun “Sozlamalar” menyusida “Kanal manbalari” bandini tanlang."</item>
+ </string-array>
</resources>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index baf831e9..67a48ed6 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Kanalni sozlash"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ota-ona nazorati"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Ilova haqida"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Kanalni sozlash"</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="channel_source_item_setup" msgid="1330441915487807542">"Kanal manbalari"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Yangi kanallar qo‘shildi"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Ro‘yxatni sozlash"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Tele-yo‘lboshchi u-n kanallarni tanlang"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Sozlanmagan"</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">
- <item quantity="one" msgid="6074059986849579215">"%1$d ta kanal qo‘shildi"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d ta kanal qo‘shildi"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Yangi PIN kodni kiriting"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"PIN kodni tasdiqlang"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Joriy PIN kodni kiriting"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> soniyadan keyin qayta urinib ko‘ring."</item>
- <item quantity="other" msgid="8829550842387756054">"Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"Ilova haqida"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Ochiq kodli DT litsenziyalari"</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="about_menu_version" msgid="6303769835664868129">"Versiyasi"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versiyasi"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Dasturchi sozlamalari"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"USB TV-tyunerni yoqish"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"USB TV-tyuner ovozini eshitish uchun televizoringiz AC3 bevosita uzatmasini qo‘llab-quvvatlashi kerak."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Nomsiz"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal bloklangan"</string>
<string name="episode_format" msgid="4881195874563241096">"<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>-fasl <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g>-qism: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Kanal manbalari"</string>
- <string name="setup_description" msgid="8728423605912915099">"Mavjud manbalar asosida jonli efir kanallarini sozlang. U kanal manbasiga qarab bir necha daqiqa vaqt olishi mumkin."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Tayyor"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d ta kanal mavjud"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d ta kanal mavjud"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"Ko‘proq kanal manbalarini olish"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"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>
@@ -190,5 +194,7 @@
<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_not_supported_device" msgid="4469404625040284722">"Jonli efir Android Lollipop tizimi o‘rnatilgan mazkur qurilmada ishlamaydi."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Jonli efir televizor ro‘yxatlarini o‘qish uchun ruxsat zarur."</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>
</resources>
diff --git a/res/values-vi/arrays.xml b/res/values-vi/arrays.xml
index 0b104fbf..202d287a 100644
--- a/res/values-vi/arrays.xml
+++ b/res/values-vi/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"Cao cấp"</item>
<item msgid="8215762047341133299">"Công nghệ/Khoa học"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Kênh trực tiếp"</item>
+ <item msgid="7307688057853449735">"Một cách đơn giản để khám phá nội dung"</item>
+ <item msgid="7566838222783641942">"Tải ứng dụng xuống, nhận nhiều kênh hơn"</item>
+ <item msgid="8646630833216197238">"Tùy chỉnh danh sách kênh của bạn"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Xem nội dung từ các ứng dụng của bạn giống như xem các kênh trên TV."</item>
+ <item msgid="1855708984677953238">"Duyệt qua nội dung từ các ứng dụng của bạn với hướng dẫn quen thuộc và giao diện thân thiện, \ngiống như các kênh trên TV."</item>
+ <item msgid="3420760668363283731">"Thêm nhiều kênh hơn bằng cách cài đặt các ứng dụng cung cấp kênh trực tiếp. \nTìm các ứng dụng tương thích trong Cửa hàng Google Play bằng cách sử dụng liên kết trong menu TV."</item>
+ <item msgid="8974157841656828507">"Hãy thiết lập các nguồn kênh mới được cài đặt để tùy chỉnh danh sách kênh của bạn. \nChọn các nguồn Kênh trong menu Cài đặt để bắt đầu."</item>
+ </string-array>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 781a12a4..6bc7dd76 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Thiết lập kênh"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Kiểm soát của cha mẹ"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Giới thiệu"</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>
@@ -84,21 +83,15 @@
<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">"Nhóm theo"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"Thiết lập kênh"</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_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="channel_source_item_setup" msgid="1330441915487807542">"Nguồn kênh"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Đã có kênh mới"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Tùy chỉnh DS kênh"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Chọn kênh cho hướng dẫn chương trình"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Chưa thiết lập"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Không thể bắt đầu các tùy chọn trên toàn hệ thống cho phụ đề."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"Đã thêm %1$d kênh"</item>
- <item quantity="other" msgid="1078861616751739285">"Đã thêm %1$d kênh"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">Đã thêm %1$d kênh</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Nhập mã PIN mới"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Xác nhận mã PIN của bạn"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Nhập mã PIN hiện tại của bạn"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Bạn đã nhập sai mã PIN 5 lần.\nHãy thử lại sau <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> giây."</item>
- <item quantity="other" msgid="8829550842387756054">"Bạn đã nhập sai mã PIN 5 lần.\nHãy thử lại sau <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> giây."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Bạn đã nhập sai mã PIN 5 lần.\nHãy thử lại sau <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> giây.</item>
+ <item quantity="one">Bạn đã nhập sai mã PIN 5 lần.\nHãy thử lại sau <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> giây.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Giới thiệu"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Giấy phép nguồn mở"</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_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="about_menu_version" msgid="6303769835664868129">"Phiên bản"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Phiên bản"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Tùy chọn nhà phát triển"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Bật bộ dò TV USB"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Để nghe được âm thanh của bộ dò TV USB, TV của bạn cần hỗ trợ chuyển qua AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Không có tiêu đề"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Đã chặn kênh"</string>
<string name="episode_format" msgid="4881195874563241096">"Mùa<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: P<xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Nguồn kênh"</string>
- <string name="setup_description" msgid="8728423605912915099">"Thiết lập kênh trực tiếp từ những nguồn sẵn có. Quá trình này có thể mất vài phút tùy thuộc vào nguồn kênh."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Xong"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"Có %1$d kênh"</item>
- <item quantity="other" msgid="2386588423841837714">"Có %1$d kênh"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Mới"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Nguồn"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kênh</item>
+ <item quantity="one">%1$d kênh</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Không có kênh nào"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Mới"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Chưa thiết lập"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Xem nguồn khác"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Duyệt qua các ứng dụng cung cấp kênh truyền hình trực tiếp"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Có nguồn kênh mới"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Nguồn kênh mới có kênh để cung cấp.\nHãy thiết lập các kênh bây giờ hoặc thiết lập sau này trong cài đặt nguồn kênh."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Thiết lập ngay"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, đã hiểu"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Nhấn CHỌN"</b>" để truy cập menu TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Phím QUAY LẠI dành cho thiết bị đã kết nối. Nhấn nút HOME để thoát."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Kênh trực tiếp không được hỗ trợ trên thiết bị chạy Android Lollipop này."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Kênh trực tiếp cần quyền đọc danh sách TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Thiết lập nguồn của bạn"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Kênh trực tiếp kết hợp trải nghiệm của các kênh TV truyền thống với các kênh truyền trực tuyến do các ứng dụng cung cấp. \n\nHãy bắt đầu bằng cách thiết lập các nguồn kênh đã được cài đặt. Hoặc duyệt qua Cửa hàng Google Play để có thêm nhiều ứng dụng cung cấp kênh trực tiếp."</string>
</resources>
diff --git a/res/values-zh-rCN/arrays.xml b/res/values-zh-rCN/arrays.xml
index 86105072..4bd6fa10 100644
--- a/res/values-zh-rCN/arrays.xml
+++ b/res/values-zh-rCN/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"首映"</item>
<item msgid="8215762047341133299">"科技"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"直播频道"</item>
+ <item msgid="7307688057853449735">"轻松探索各种精彩内容"</item>
+ <item msgid="7566838222783641942">"下载应用,获取更多频道"</item>
+ <item msgid="8646630833216197238">"定制您的频道节目单"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"像观看电视频道一样浏览您应用中的内容。"</item>
+ <item msgid="1855708984677953238">"通过熟悉的指南和好用的界面浏览您应用中的内容,\n就像观看电视频道一样。"</item>
+ <item msgid="3420760668363283731">"安装可提供直播频道的应用即可添加更多频道。\n您可以使用电视菜单中的链接在 Google Play 商店中查找兼容的应用。"</item>
+ <item msgid="8974157841656828507">"设置新安装的频道来源即可定制您的频道列表。\n在“设置”菜单中选择“频道来源”即可开始进行设置。"</item>
+ </string-array>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 56aed226..b4743f30 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"频道设置"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"家长控制"</string>
- <string name="options_item_about" msgid="3023532413252052050">"简介"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"高清"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"标清"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"分组依据"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"频道设置"</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="channel_source_item_setup" msgid="1330441915487807542">"频道来源"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"有新频道"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"自定义频道列表"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"为您的收视指南选择频道"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"未设置"</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">
- <item quantity="one" msgid="6074059986849579215">"已添加%1$d个频道"</item>
- <item quantity="other" msgid="1078861616751739285">"已添加%1$d个频道"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"您已连续 5 次输错 PIN 码。\n请在 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒后重试。"</item>
- <item quantity="other" msgid="8829550842387756054">"您已连续 5 次输错 PIN 码。\n请在 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒后重试。"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"简介"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"开放源代码许可"</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="about_menu_version" msgid="6303769835664868129">"版本"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"开发者选项"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"启用 USB 电视调谐器"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"要想听到 USB 电视调谐器的声音,您的电视需要支持 AC3 直通输出功能。"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"无标题"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"频道已屏蔽"</string>
<string name="episode_format" msgid="4881195874563241096">"第 <xliff:g id="SEASON_NUMBER">%1$d</xliff:g> 季第 <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> 集《<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>》"</string>
- <string name="setup_title" msgid="7268875010986705651">"频道来源"</string>
- <string name="setup_description" msgid="8728423605912915099">"从可用来源中设置直播频道。这可能需要几分钟的时间,具体取决于频道来源。"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"完成"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"有 %1$d 个频道"</item>
- <item quantity="other" msgid="2386588423841837714">"有 %1$d 个频道"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"获取更多来源"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"浏览提供直播频道的应用"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"“返回”键用于控制连接的设备。按“主屏幕”按钮即可退出。"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"此 Android Lollipop 设备不支持直播频道。"</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>
</resources>
diff --git a/res/values-zh-rHK/arrays.xml b/res/values-zh-rHK/arrays.xml
index 7fc3cde0..1fcac667 100644
--- a/res/values-zh-rHK/arrays.xml
+++ b/res/values-zh-rHK/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"首選"</item>
<item msgid="8215762047341133299">"科技/科學"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"直播頻道"</item>
+ <item msgid="7307688057853449735">"輕鬆探索各種內容"</item>
+ <item msgid="7566838222783641942">"下載應用程式,觀看更多頻道"</item>
+ <item msgid="8646630833216197238">"自訂您的頻道節目表"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"像觀看電視頻道一樣瀏覽您應用程式中的內容。"</item>
+ <item msgid="1855708984677953238">"透過熟悉的節目指南和易用的介面瀏覽您應用程式中的內容,\n就像觀看電視頻道一樣。"</item>
+ <item msgid="3420760668363283731">"安裝提供直播頻道的應用程式即可新增更多頻道。\n您可以使用電視選單中的連結,前往「Google Play 商店」尋找相容的應用程式。"</item>
+ <item msgid="8974157841656828507">"設定新安裝的頻道來源,即可自訂您的頻道清單。\n在「設定」選單中選擇頻道來源即可開始設定。"</item>
+ </string-array>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index a1457ecd..368b5cd9 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"頻道設定"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"家長監護"</string>
- <string name="options_item_about" msgid="3023532413252052050">"關於"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"高清"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"標清"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"分組依據"</string>
- <string name="side_panel_title_channel_sources" msgid="2171195037212553286">"頻道設定"</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="channel_source_item_setup" msgid="1330441915487807542">"頻道來源"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"可供設定的新頻道"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"自訂頻道清單"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"選擇要提供節目指南的頻道"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"未設定"</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">
- <item quantity="one" msgid="6074059986849579215">"已新增 %1$d 個頻道"</item>
- <item quantity="other" msgid="1078861616751739285">"已新增 %1$d 個頻道"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"您已輸入 5 次錯誤的 PIN。\n請於 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒後再試一次。"</item>
- <item quantity="other" msgid="8829550842387756054">"您已輸入 5 次錯誤的 PIN。\n請於 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒後再試一次。"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"關於"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"開放原始碼授權"</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="about_menu_version" msgid="6303769835664868129">"版本"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"開發人員選項"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"啟用 USB 電視調諧器"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"如要收聽 USB 電視調諧器的音訊,電視需要支援 AC3 直通輸出。"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"無標題"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"已封鎖的頻道"</string>
<string name="episode_format" msgid="4881195874563241096">"第 <xliff:g id="SEASON_NUMBER">%1$d</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> 集 <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"頻道來源"</string>
- <string name="setup_description" msgid="8728423605912915099">"從可供來源建立直播頻道。過程約需數分鐘,視乎頻道來源而定。"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"完成"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d 個可用頻道"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d 個可用頻道"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"取得更多來源"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"瀏覽提供直播頻道的應用程式"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"[返回] 鍵適用於已連結的裝置。按一下 [主畫面] 按鈕即可結束。"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"此 Android Lollipop 裝置不支援「直播頻道」。"</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>
</resources>
diff --git a/res/values-zh-rTW/arrays.xml b/res/values-zh-rTW/arrays.xml
index 49e24dde..8647afb4 100644
--- a/res/values-zh-rTW/arrays.xml
+++ b/res/values-zh-rTW/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"首映"</item>
<item msgid="8215762047341133299">"科技/科學"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"直播頻道"</item>
+ <item msgid="7307688057853449735">"輕鬆探索各種內容"</item>
+ <item msgid="7566838222783641942">"下載應用程式,取得更多頻道"</item>
+ <item msgid="8646630833216197238">"自訂您的頻道節目表"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"像觀看電視頻道一樣瀏覽您應用程式中的內容。"</item>
+ <item msgid="1855708984677953238">"透過熟悉的節目指南和好用的介面,瀏覽您應用程式中的內容,\n就像觀看電視頻道一樣簡單。"</item>
+ <item msgid="3420760668363283731">"安裝提供直播頻道的應用程式即可新增更多頻道。\n您可以使用電視選單中的連結,前往 Google Play 商店尋找相容的應用程式。"</item>
+ <item msgid="8974157841656828507">"設定新安裝的頻道來源以自訂您的頻道清單。\n選擇「設定」選單中的 [頻道來源] 即可開始進行設定。"</item>
+ </string-array>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index b82f8b41..0a3b4cc1 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"頻道設定"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"家長監護"</string>
- <string name="options_item_about" msgid="3023532413252052050">"關於"</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>
@@ -84,21 +83,15 @@
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"頻道設定"</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="channel_source_item_setup" msgid="1330441915487807542">"頻道來源"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"有新頻道"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"自訂頻道清單"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"為您的節目指南選擇頻道"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"尚未設定"</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">
- <item quantity="one" msgid="6074059986849579215">"新增了 %1$d 個頻道"</item>
- <item quantity="other" msgid="1078861616751739285">"新增了 %1$d 個頻道"</item>
- </plurals>
+ <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>
@@ -136,16 +129,21 @@
<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">
- <item quantity="one" msgid="5555357148779935468">"您已輸入 5 次錯誤的 PIN 碼。\n請於 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒後再試一次。"</item>
- <item quantity="other" msgid="8829550842387756054">"您已輸入 5 次錯誤的 PIN 碼。\n請於 <xliff:g id="REMAINING_SECONDS">%1$d</xliff:g> 秒後再試一次。"</item>
- </plurals>
+ <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_about" msgid="4572960435017168299">"關於"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"開放原始碼授權"</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="about_menu_version" msgid="6303769835664868129">"版本"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"開發人員選項"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"啟用 USB 電視調諧器"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"您的電視必須支援 AC3 傳輸功能,才能播放 USB 電視調諧器的聲音。"</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"無標題"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"頻道遭到封鎖"</string>
<string name="episode_format" msgid="4881195874563241096">"第 <xliff:g id="SEASON_NUMBER">%1$d</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> 集「<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>」"</string>
- <string name="setup_title" msgid="7268875010986705651">"頻道來源"</string>
- <string name="setup_description" msgid="8728423605912915099">"從可用來源中設定直播頻道。取決於您的頻道來源,這可能需要一些時間。"</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"完成"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"提供 %1$d 個頻道"</item>
- <item quantity="other" msgid="2386588423841837714">"提供 %1$d 個頻道"</item>
- </plurals>
+ <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_play_store_action_title" msgid="859347291072224673">"取得更多頻道來源"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"瀏覽提供直播頻道的應用程式"</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>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"返回鍵適用於連線的裝置,按下主螢幕按鈕即可結束。"</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"這個搭載 Android Lollipop 的裝置不支援「直播頻道」。"</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>
</resources>
diff --git a/res/values-zu/arrays.xml b/res/values-zu/arrays.xml
index 95ded427..03f7be29 100644
--- a/res/values-zu/arrays.xml
+++ b/res/values-zu/arrays.xml
@@ -42,4 +42,16 @@
<item msgid="7452153120614274095">"I-Premier"</item>
<item msgid="8215762047341133299">"Ubuchwepheshe/isayensi"</item>
</string-array>
+ <string-array name="welcome_page_titles">
+ <item msgid="8322900543391231769">"Iziteshi ezibukhoma"</item>
+ <item msgid="7307688057853449735">"Indlela elula yokuthola okuqukethwe"</item>
+ <item msgid="7566838222783641942">"Landa izinhlelo zokusebenza, thola iziteshi eziningi"</item>
+ <item msgid="8646630833216197238">"Enza ngendlela oyifisayo okuzayo kwesiteshi sakho"</item>
+ </string-array>
+ <string-array name="welcome_page_descriptions">
+ <item msgid="8445334820787831823">"Buka okuqukethwe kusukela kuzinhlelo zakho zokusebenza njengokubukela iziteshi ku-TV."</item>
+ <item msgid="1855708984677953238">"Dlulisa amehlo kokuqukethwe kusukela kuzinhlelo zakho zokusebenza ngomhlahlandlela ojwayelekile onesixhumi esibonakalayo esinobungane, \nnjengeziteshi ku-TV."</item>
+ <item msgid="3420760668363283731">"Engeza iziteshi eziningi ngokufaka izinhlelo zokusebenza ezinikeza iziteshi ezibukhoma. \nThola izinhlelo zokusebenza ezihambisanayo ku-Google Play Isitolo ngokusebenzisa isixhumanisi esingaphakathi kwemenyu ye-TV."</item>
+ <item msgid="8974157841656828507">"Setha imithombo yakho yesiteshi emisha efakiwe ukuze wenze ngendlela oyifisayo uhlu lwakho lwesiteshi. \nKhetha imithombo yesiteshi ngaphakathi kwemenyu yezilungiselelo ukuze uqalise."</item>
+ </string-array>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 84a128a9..b59592fa 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -39,9 +39,8 @@
<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_channel_sources" msgid="2217574947817750560">"Ukusethwa kwesiteshi"</string>
- <string name="options_item_parental_controls" msgid="7880060136509458287">"Ukulawula kwabazali"</string>
- <string name="options_item_about" msgid="3023532413252052050">"Mayelana"</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>
@@ -84,21 +83,15 @@
<string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"I-HD"</string>
<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="side_panel_title_channel_sources" msgid="2171195037212553286">"Ukusethwa kwesiteshi"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Lolu hlelo luvinjiwe"</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="channel_source_item_setup" msgid="1330441915487807542">"Imithombo yeziteshi"</string>
- <string name="channel_source_item_setup_new_inputs" msgid="2992665972254089976">"Iziteshi ezintsha ziyatholakala"</string>
- <string name="channel_source_item_customize_channels" msgid="2836316051162501082">"Yenza ngezifiso uhlu lweziteshi"</string>
- <string name="channel_source_item_customize_channels_description" msgid="3124895053900086630">"Khetha iziteshi zomhlahlandlela wohlelo lwakho"</string>
- <string name="channel_description_setup_now" msgid="7643342362645622249">"Akusethiwe"</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>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ayikwazi ukuqala okuncamelayo kwesistimu okubanzi kwemibhalo engezansi."</string>
- <plurals name="msg_channel_added">
- <item quantity="one" msgid="6074059986849579215">"%1$d isiteshi singeziwe"</item>
- <item quantity="other" msgid="1078861616751739285">"%1$d iziteshi zingeziwe"</item>
- </plurals>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d iziteshi ezingeziwe</item>
+ <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>
@@ -136,16 +129,21 @@
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Faka iphinikhodi entsha"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Qinisekisa i-PIN yakho"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Faka i-PIN yakho yamanje"</string>
- <plurals name="pin_enter_countdown">
- <item quantity="one" msgid="5555357148779935468">"Ufake iphinikhodi engalungile izikhathi ezingu-5.\nZama futhi kusekhondi elingu-<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- <item quantity="other" msgid="8829550842387756054">"Ufake iphinikhodi engalungile izikhathi ezingu-5.\nZama futhi kumasekhondi angu-<xliff:g id="REMAINING_SECONDS">%1$d</xliff:g>."</item>
- </plurals>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Ufake iphinikhodi engalungile izikhathi ezingu-5.\nZama futhi kumasekhondi angu-<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>.</item>
+ <item quantity="other">Ufake iphinikhodi engalungile izikhathi ezingu-5.\nZama futhi kumasekhondi angu-<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>.</item>
+ </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="side_panel_title_about" msgid="4572960435017168299">"Mayelana"</string>
- <string name="about_menu_licenses" msgid="4831892908710402185">"Amalayisense womthombo ovulekile"</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_menu_licenses" msgid="1257646083838406103">"Amalayisense womthombo ovulekile"</string>
<string name="dialog_title_licenses" msgid="4471754920475076623">"Amalayisense womthombo ovulekile"</string>
- <string name="about_menu_version" msgid="6303769835664868129">"Inguqulo"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Inguqulo"</string>
<string name="side_panel_title_developer" msgid="7287627759979090359">"Izinketho zonjiniyela"</string>
<string name="developer_menu_enable_usb_tv_tuner" msgid="8380174840125430895">"Nika amandla isishuni se-USB TV"</string>
<string name="developer_menu_enable_usb_tv_tuner_description" msgid="7122833064850110134">"Ukuze uzwe umsindo wesishuni se-USB TV, i-TV yakho kufanele isekele ukuphuma kwe-AC3."</string>
@@ -166,15 +164,21 @@
<string name="channel_banner_no_title" msgid="8660301979190693176">"Asikho isihloko"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Isiteshi sivinjiw"</string>
<string name="episode_format" msgid="4881195874563241096">"S<xliff:g id="SEASON_NUMBER">%1$d</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$d</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="setup_title" msgid="7268875010986705651">"Imithombo yeziteshi"</string>
- <string name="setup_description" msgid="8728423605912915099">"Setha iziteshi ezibukhoma kusukela kumithombo etholakalayo. Lokhu kungathatha amaminithi ambalwa ngokuya ngomthombo wesiteshi."</string>
- <string name="setup_done_button_label" msgid="3488134953528237729">"Kwenziwe"</string>
- <plurals name="setup_input_channels">
- <item quantity="one" msgid="7847402892516958129">"%1$d isiteshi esitholakalayo"</item>
- <item quantity="other" msgid="2386588423841837714">"%1$d iziteshi ezitholakalayo"</item>
- </plurals>
+ <string name="setup_category_new" msgid="2899355289563443627">"Okusha"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Imithombo"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d iziteshi</item>
+ <item quantity="other">%1$d iziteshi</item>
+ </plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Azikho iziteshi ezitholakalayo"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Okusha"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Akusethiwe"</string>
+ <string name="setup_play_store_action_title" msgid="859347291072224673">"Thola imithombo eminingi"</string>
+ <string name="setup_play_store_action_description" msgid="2472226338824629506">"Dlulisa amehlo kuziphequluli ezinikeza iziteshi ezibukhoma"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Imithombo yesiteshi esisha iyatholakala"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Imithombo yesiteshi emisha ineziteshi ezinikezelayo.\nIsethe manje, noma yenza lokhu emuva kwesikhathi kusilungiselelo somthombo wesiteshi."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Setha manje"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Kulungile, ngiyitholile"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
<string name="intro_description" msgid="7806473686446937307"><b>"Cindezela okuthi KHETHA"</b>" ukuze ufinyelele imenyu ye-TV."</string>
@@ -191,4 +195,6 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Ukhiye we-EMUVA ungowedivayisi exhunyiwe. Cindezela kunkinobho ye-IKHAYA ukuze uphume."</string>
<string name="msg_not_supported_device" msgid="4469404625040284722">"Iziteshi ezibukhoma azisekelwa kule divayisi nge-Android Lollipop."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Iziteshi ezibukhoma zidinga imvume ukuze zifunde ukufakwa kuhlu kwe-TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Setha imithombo yakho"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Iziteshi ezibukhoma zihlanganisa umuzwa wosiko weziteshi ze-TV ngokusakaza iziteshi ezinikezwe izinhlelo zokusebenza.\n\nQalisa ngokusetha imithombo yesiteshi esivele ifakiwe. Noma dlulisa amehlo ku-Google Play Isitolo ukuze uthole izinhlelo zokusebenza eziningi ezinikezela iziteshi ezibukhoma."</string>
</resources>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index e887e6d0..583ad51f 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -51,21 +51,24 @@
<item>Tech/Science</item>
</string-array>
- <!-- Titles in the onboarding page.
- TODO: set translatable to true. -->
- <string-array name="welcome_page_titles" translatable="false">
+ <!-- Titles in the onboarding page. -->
+ <string-array name="welcome_page_titles">
<item>Live TV</item>
- <item>Download new channels</item>
+ <item>A simple way to discover content</item>
+ <item>Download apps, get more channels</item>
<item>Customize your channel line-up</item>
- <item>Watch, pause, and rewind live TV</item>
</string-array>
- <!-- Descriptions in the onboarding page.
- TODO: set translatable to true. -->
- <string-array name="welcome_page_descriptions" translatable="false">
- <item>Combine broadcast TV with streaming channels provided by your apps.</item>
- <item>Customize your channel line up by downloading apps that offer streaming channels.\nYou can find compatible apps in the Google Play Store.</item>
- <item>Set up newly installed channels from the Channel Sources option within the TV menu</item>
- <item>Enjoy over-the-air channels like ABC, CBS, NBC, and FOX\nwhen you add a compatible TV tuner &amp; HDTV antenna to your Nexus Player.</item>
+ <!-- Descriptions in the onboarding page. -->
+ <string-array name="welcome_page_descriptions">
+ <item>Watch content from your apps like watching channels on TV.</item>
+ <item>Browse content from your apps with a familiar guide and friendly interface,
+\njust like channels on TV.</item>
+ <item>Add more channels by installing apps that offer live channels.
+\nFind compatible apps in Google Play Store by using the link within the TV menu.</item>
+ <!-- Refer to @string/settings_channel_source_item_setup for "Channel sources" menu
+ and @string/options_item_settings for "Settings" menu. -->
+ <item>Set up your newly installed channel sources to customize your channel list.
+\nChoose the Channel sources within the Settings menu to get started.</item>
</string-array>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9cb121e8..cb0bd2df 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -133,10 +133,11 @@
<!-- Setup -->
<color name="setup_title">#EEEEEE</color>
<color name="setup_description">#B3EEEEEE</color>
- <color name="setup_background">#E701579B</color>
- <color name="setup_divider">#4DEEEEEE</color>
-
- <!-- Onboarding screen -->
- <color name="onboarding_dot_selected">#FFFFFFFF</color>
- <color name="onboarding_dot_unselected">#4DFFFFFF</color>
+ <!-- Add alpha value to common_tv_background -->
+ <color name="setup_background">#E70288D1</color>
+ <!-- Add alpha value to common_setup_action_background -->
+ <color name="setup_actions_background">#B30374BF</color>
+ <!-- Add alpha value to common_setup_done_container_background -->
+ <color name="setup_done_button_container_background">#8004549D</color>
+ <color name="setup_category">#3EC2FF</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c4d9977d..73f04a4c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -144,10 +144,6 @@
<dimen name="option_item_divider_text_margin_top">18dp</dimen>
<dimen name="option_item_channel_check_spacing">12dp</dimen>
- <!-- Setup -->
- <!-- 62.5 % is a position for top padding + non-padding area's height / 2. -->
- <item name="setup_item_window_alignment_offset_percent" format="float" type="dimen">62.5</item>
-
<!-- Program guide -->
<dimen name="program_guide_shift_start_to_end_x">238dp</dimen>
<dimen name="program_guide_shift_end_to_start_x">-238dp</dimen>
@@ -303,9 +299,16 @@
<dimen name="pin_number_picker_text_view_width">48dp</dimen>
<dimen name="pin_number_picker_text_view_height">48dp</dimen>
- <!-- Onboarding welcome screen -->
- <dimen name="onboarding_welcome_content_width">536dp</dimen>
- <dimen name="onboarding_dot_radius">4dp</dimen>
- <dimen name="onboarding_dot_gap">12dp</dimen>
- <dimen name="onboarding_welcome_page_transition_distance">60dp</dimen>
+ <!-- Onboarding screens -->
+ <eat-comment />
+ <dimen name="onboarding_welcome_content_margin_top">67dp</dimen>
+ <dimen name="onboarding_welcome_content_margin_bottom">50dp</dimen>
+ <dimen name="onboarding_welcome_shadow_height">9dp</dimen>
+ <dimen name="onboarding_welcome_shadow_margin_top">16dp</dimen>
+ <!-- This value is lb_onboarding_content_margin_bottom(98dp)
+ + lb_onboarding_welcome_content_margin_bottom(50dp)
+ + lb_onboarding_welcome_shadow_height(9dp)
+ + lb_onboarding_welcome_shadow_margin_top(16dp)
+ + margin from tv_container(70dp) -->
+ <dimen name="onboarding_welcome_arrow_margin_bottom">243dp</dimen>
</resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 22925bd3..08f55043 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -79,8 +79,4 @@
<integer name="max_recycled_view_pool_epg_table_row">15</integer>
<integer name="max_recycled_view_pool_epg_header_row_item">7</integer>
<integer name="max_recycled_view_pool_epg_side_panel_row">12</integer>
-
- <!-- Fullscreen dialogs (e.g. Setup dialog) -->
- <integer name="fullscreen_dialog_enter_translation_x">200</integer>
- <integer name="fullscreen_dialog_exit_translation_x">-200</integer>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2e0642d2..0bf026db 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -29,9 +29,6 @@
<!-- Name of application [CHAR LIMIT=NONE] -->
<string name="app_name">Live TV</string>
- <!--TODO(DVR): decide if translation needed Name of DVR service [CHAR LIMIT=NONE] -->
- <string name="dvr_service_name" translatable="false">DVR Service</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_receiveInputEvent" translatable="false">receive input events from Live TV app</string>
@@ -115,12 +112,10 @@
<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 "Channel Setup" item in the TV option row. [CHAR LIMIT=17] -->
- <string name="options_item_channel_sources">Channel setup</string>
- <!-- Label of "Parental controls" item in the TV option row. [CHAR LIMIT=17] -->
- <string name="options_item_parental_controls">Parental controls</string>
- <!-- Label of "About the Live TV application" item in the TV option row. [CHAR LIMIT=17] -->
- <string name="options_item_about">About</string>
+ <!-- Label of "Get more channels" item in the TV option row. [CHAR LIMIT=17] -->
+ <string name="options_item_more_channels">Get more channels</string>
+ <!-- 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] -->
@@ -240,11 +235,6 @@
<!-- Title of "Group by" side panel to set grouping type [CHAR LIMIT=30] -->
<string name="side_panel_title_group_by">Group by</string>
- <!-- Inside "Channel setup" option side panel -->
- <eat-comment />
- <!-- Title of "Channel setup" option. [CHAR LIMIT=30] -->
- <string name="side_panel_title_channel_sources">Channel setup</string>
-
<!-- Inside full EPG -->
<eat-comment />
<!-- Description in the TV guide when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
@@ -252,22 +242,6 @@
<!-- 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>
- <!-- Inside menu for each input after selecting one input in "Channels" option -->
- <eat-comment />
- <!-- Label of "Channel sources" item to setup channels. [CHAR LIMIT=30] -->
- <string name="channel_source_item_setup">Channel sources</string>
- <!-- Description of "Channel sources" item only when new inputs are available.
- [CHAR LIMIT=NONE] -->
- <string name="channel_source_item_setup_new_inputs">New channels available</string>
- <!-- Label of "Customize channels list" item to select and deselect channels.
- [CHAR LIMIT=30] -->
- <string name="channel_source_item_customize_channels">Customize channel list</string>
- <!-- Description of "Customize channels list" item. [CHAR LIMIT=NONE] -->
- <string name="channel_source_item_customize_channels_description">Choose channels for your program guide</string>
-
- <!-- Channel description: channel scan is needed, because the input is just installed.
- [CHAR LIMIT=40] -->
- <string name="channel_description_setup_now">Not set up</string>
<!-- Message when a channel item is clicked for channel auto-scan, but the input doesn't
have auto-scan function. [CHAR LIMIT=NONE] -->
<string name="msg_no_setup_activity">The input doesn\'t support auto-scan</string>
@@ -395,16 +369,28 @@
<!-- 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>
- <!-- menu for "About" option -->
+ <!-- menu for "Settings" option -->
<eat-comment />
- <!-- Title of "About the Live TV application" option. [CHAR LIMIT=30] -->
- <string name="side_panel_title_about">About</string>
+ <!-- Title of "Settings" option. [CHAR LIMIT=30] -->
+ <string name="side_panel_title_settings">Settings</string>
+ <!-- Label of "Customize channels list" item to select and deselect channels.
+ [CHAR LIMIT=30] -->
+ <string name="settings_channel_source_item_customize_channels">Customize channel list</string>
+ <!-- Description of "Customize channels list" item. [CHAR LIMIT=NONE] -->
+ <string name="settings_channel_source_item_customize_channels_description">Choose channels for your program guide</string>
+ <!-- Label of "Channel sources" item to setup channels. [CHAR LIMIT=30] -->
+ <string name="settings_channel_source_item_setup">Channel sources</string>
+ <!-- Description of "Channel sources" item only when new inputs are available.
+ [CHAR LIMIT=NONE] -->
+ <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>
<!-- Menu item to show licenses for open source code used in the app [CHAR LIMIT=35] -->
- <string name="about_menu_licenses">Open source licenses</string>
+ <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 that shows the application version(eg 1.2.03-final) as a second line below this title [CHAR LIMIT=35] -->
- <string name="about_menu_version">Version</string>
+ <string name="settings_menu_version">Version</string>
<!-- menu for "Developer options" -->
<eat-comment />
@@ -463,23 +449,38 @@
<!-- The episode title format displayed on the info banner. For example, "S1: Ep. 1 Winter is coming". -->
<string name="episode_format">S<xliff:g id="season_number" example="1">%1$d</xliff:g>: Ep. <xliff:g id="episode_number" example="1">%2$d</xliff:g> <xliff:g id="episode_title" example="Winder is coming">%3$s</xliff:g></string>
- <!-- Setup dialog -->
+ <!-- Setup Sources Fragment -->
<eat-comment />
- <!-- Title of Setup Dialog [CHAR LIMIT=30] -->
- <string name="setup_title">Channel sources</string>
- <!-- Description of Setup Dialog. [CHAR LIMIT=NONE] -->
- <string name="setup_description">Set up live channels from the available sources. This may take several minutes depending on the channel source.</string>
- <!-- Label of done button [CHAR LIMIT=30] -->
- <string name="setup_done_button_label">Done</string>
+ <!-- Category name for the newly installed channel sources(inputs).-->
+ <string name="setup_category_new">New</string>
+ <!-- Category name for the installed channel sources(inputs). -->
+ <string name="setup_category_done">Sources</string>
<!-- Description of an input to describe its channel count. [CHAR LIMIT=40] -->
<plurals name="setup_input_channels">
- <item quantity="one">%1$d channel available</item>
- <item quantity="other">%1$d channels available</item>
+ <item quantity="one">%1$d channel</item>
+ <item quantity="other">%1$d channels</item>
</plurals>
<!-- Description of an input with 0 channels. [CHAR LIMIT=40] -->
<string name="setup_input_no_channels">No channels available</string>
<!-- Description of newly installed inputs. [CHAR LIMIT=40] -->
<string name="setup_input_new">New</string>
+ <!-- Description of an input which was installed but not setup yet. [CHAR LIMIT=40] -->
+ <string name="setup_input_setup_now">Not set up</string>
+ <!-- Title for the link to the play store to get more channel sources. -->
+ <string name="setup_play_store_action_title">Get more sources</string>
+ <!-- Description for the link to the play store to get more channel sources. -->
+ <string name="setup_play_store_action_description">Browse apps that offer live channels</string>
+
+ <!-- New Sources Fragment -->
+ <eat-comment />
+ <!-- Title for the new sources fragment -->
+ <string name="new_sources_title">New channel sources available</string>
+ <!-- Description for the new sources fragment -->
+ <string name="new_sources_description">New channel sources have channels to offer.\nSet them up now, or do this later in the channel sources setting.</string>
+ <!-- String for the "Set up now" action -->
+ <string name="new_sources_action_setup">Set up now</string>
+ <!-- String for the "skip" action -->
+ <string name="new_sources_action_skip">Ok, got it</string>
<!-- Intro dialog -->
<eat-comment />
@@ -487,17 +488,6 @@
<!-- Description of Intro Dialog [CHAR LIMIT=NONE] -->
<string name="intro_description"><b>Press SELECT</b> to access the TV menu.</string>
- <!-- DVR in EPG
- TODO(DVR): make translatable true. -->
- <eat-comment />
- <!-- 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>
-
<!-- Toast messages -->
<eat-comment />
<!-- Error message when there is no TV input. [CHAR LIMIT=NONE] -->
@@ -553,27 +543,52 @@
<!-- Onboarding experience.
TODO: Change translatable to true.-->
- <!-- Text for the Live TV overview screen in onboarding. -->
- <string name="app_overview_text" translatable="false">Get Live TV</string>
- <!-- Description for the Live TV overview screen in onboarding. -->
- <string name="app_overview_description_has_ac3" translatable="false">Live channels combine the experience of traditional TV channels with streaming channels provided by apps. Get started by setting up the channel sources you already have available, or browse the Google Play Store for more apps that offer live channels.
-\nAlso, learn about getting over-the-air broadcast channels like ABC, CBS, NBC, and FOX when you add a compatible TV tuner &amp; HDTV antenna to your Nexus Player.</string>
- <string name="app_overview_description_no_ac3" translatable="false">Live channels combine the experience of traditional TV channels with streaming channels provided by apps. Get started by setting up the channel sources you already have available, or browse the Google nPlay Store for more apps that offer live channels.</string>
- <!-- Text for the action for setting up channel sources. It will show the setup page of the channel sources. -->
- <string name="app_overview_action_text_setup_source" translatable="false">Set up your channel sources</string>
- <!-- Description for the action for setting up channel sources. It will show the setup page of the channel sources. -->
- <string name="app_overview_action_description_setup_source" translatable="false">View the channel sources already installed</string>
- <!-- Text for the action for getting more channels from play store. It will show the play store page. -->
- <string name="app_overview_action_text_play_store" translatable="false">Get streaming channels</string>
- <!-- Description for the action for getting more channels from play store. It will show the play store page. -->
- <string name="app_overview_action_description_play_store" translatable="false">Browse apps that offer live channels</string>
- <!-- Text for the action for setting up channel of USB tuner. It will show the channel scan page. -->
- <string name="app_overview_action_text_usb_tuner" translatable="false">Get over-the-air TV channels</string>
- <!-- Description for the action for setting up channel of USB tuner. It will show the channel scan page. -->
- <string name="app_overview_action_description_usb_tuner" translatable="false">Learn about compatible TV tuners</string>
+ <eat-comment />
<!-- Text for the channel sources screen in onboarding. -->
- <string name="setup_sources_text" translatable="false">Channel sources</string>
+ <string name="setup_sources_text">Set up your sources</string>
<!-- Description for channel sources screen in onboarding. -->
- <string name="setup_sources_description" translatable="false">Set up live channels from the available sources. This may take several minutes depending on the channel source.
-\nGet more channels by installing compatible apps from the Google Play Store.</string>
+ <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 />
+ <!-- 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" translatable="false">DVR</string>
+
+ <!--TODO(DVR): decide if translation needed Name of DVR service [CHAR LIMIT=NONE] -->
+ <string name="dvr_service_name" translatable="false">DVR Service</string>
+
+ <!-- DVR Menu strings. -->
+ <eat-comment />
+ <string name="dvr_main_current_recordings" translatable="false">Current Recordings</string>
+ <string name="dvr_main_scheduled_recordings" translatable="false">Scheduled Recordings</string>
+ <string name="dvr_main_recorded_programs" translatable="false">Recorded Programs</string>
+ <string name="dvr_main_settings" translatable="false">Settings</string>
+ <string name="dvr_msg_no_recording_on_the_row" translatable="false">None</string>
+ <string name="dvr_msg_program_title_unknown" translatable="false">Unknown</string>
+ <string name="dvr_msg_channel_unknown" translatable="false">Channel unknown</string>
+
+ <!-- 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>
+ <string name="dvr_detail_play" translatable="false">Play recording</string>
+ <string name="dvr_detail_delete" translatable="false">Delete recording</string>
+
+ <!-- DVR epg strings -->
+ <eat-comment />
+ <string name="dvr_epg_record" translatable="false">Record</string>
+ <string name="dvr_epg_do_not_record" translatable="false">Do not record</string>
+ <string name="dvr_epg_conflict_dialog_title" translatable="false">Recording this program will
+ prevent the recording of the following programs:</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index b6b0b2d9..04a7d422 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -84,4 +84,8 @@
<item name="android:windowEnterAnimation">@anim/select_input_activity_enter</item>
<item name="android:windowExitAnimation">@anim/select_input_activity_exit</item>
</style>
+
+ <style name="TV.DoneButtonContainerStyle" parent="DoneButtonContainerStyle">
+ <item name="android:background">@color/setup_done_button_container_background</item>
+ </style>
</resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 6600f8ec..23b59a27 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -47,4 +47,10 @@
<item name="android:windowAnimationStyle">@style/Animation.SelectInputActivity</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
+
+ <style name="Theme.TV.GuidedStep" parent="Theme.Setup.GuidedStep">
+ <item name="setupCommonGuidanceBackground">@color/setup_background</item>
+ <item name="guidedActionsBackground">@color/setup_actions_background</item>
+ <item name="doneButtonContainerStyle">@style/TV.DoneButtonContainerStyle</item>
+ </style>
</resources>
diff --git a/src/com/android/tv/ApplicationSingletons.java b/src/com/android/tv/ApplicationSingletons.java
index 0ef61e72..5198f7fd 100644
--- a/src/com/android/tv/ApplicationSingletons.java
+++ b/src/com/android/tv/ApplicationSingletons.java
@@ -17,7 +17,6 @@
package com.android.tv;
import com.android.tv.analytics.Analytics;
-import com.android.tv.analytics.OptOutPreferenceHelper;
import com.android.tv.analytics.Tracker;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
@@ -41,11 +40,11 @@ public interface ApplicationSingletons {
DvrSessionManager getDvrSessionManger();
- OptOutPreferenceHelper getOptPreferenceHelper();
-
ProgramDataManager getProgramDataManager();
Tracker getTracker();
TvInputManagerHelper getTvInputManagerHelper();
+
+ MainActivityWrapper getMainActivityWrapper();
}
diff --git a/src/com/android/tv/ChannelTuner.java b/src/com/android/tv/ChannelTuner.java
index 0195249b..0a000e9b 100644
--- a/src/com/android/tv/ChannelTuner.java
+++ b/src/com/android/tv/ChannelTuner.java
@@ -20,12 +20,13 @@ import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.net.Uri;
import android.os.Handler;
+import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.Log;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.util.CollectionUtils;
import com.android.tv.util.SoftPreconditions;
import com.android.tv.util.TvInputManagerHelper;
@@ -40,6 +41,7 @@ import java.util.Set;
* It manages the current tuned channel among browsable channels. And it determines the next channel
* by channel up/down. But, it doesn't actually tune through TvView.
*/
+@MainThread
public class ChannelTuner {
private static final String TAG = "ChannelTuner";
diff --git a/src/com/android/tv/Features.java b/src/com/android/tv/Features.java
index 9564afaa..1a665506 100644
--- a/src/com/android/tv/Features.java
+++ b/src/com/android/tv/Features.java
@@ -16,21 +16,21 @@
package com.android.tv;
-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 static com.android.tv.common.feature.TestableFeature.createTestableFeature;
-import static com.android.tv.util.EngOnlyFeature.ENG_ONLY_FEATURE;
-
import android.support.annotation.VisibleForTesting;
import com.android.tv.common.feature.Feature;
import com.android.tv.common.feature.GServiceFeature;
+import com.android.tv.common.feature.PackageVersionFeature;
import com.android.tv.common.feature.PropertyFeature;
import com.android.tv.common.feature.SharedPreferencesFeature;
import com.android.tv.common.feature.TestableFeature;
+import static com.android.tv.common.feature.FeatureUtils.AND;
+import static com.android.tv.common.feature.FeatureUtils.ON;
+import static com.android.tv.common.feature.FeatureUtils.OR;
+import static com.android.tv.common.feature.TestableFeature.createTestableFeature;
+import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
+
/**
* List of {@link Feature} for the Live TV App.
*
@@ -38,49 +38,48 @@ import com.android.tv.common.feature.TestableFeature;
*/
public final class Features {
/**
- * UI for opting out of analytics.
+ * UI for opting in to analytics.
*
- * <p>See <a href="http://b/20228119">b/20228119</a>
+ * <p>Do not turn this on until the splash screen asking existing users to opt-in is launched.
+ * See <a href="http://b/20228119">b/20228119</a>
*/
- public static Feature ANALYTICS_OPT_OUT = ENG_ONLY_FEATURE;
+ public static Feature ANALYTICS_OPT_IN = ENG_ONLY_FEATURE;
/**
* Analytics that include sensitive information such as channel or program identifiers.
*
* <p>See <a href="http://b/22062676">b/22062676</a>
*/
- public static Feature ANALYTICS_V2 = AND(ON, ANALYTICS_OPT_OUT);
-
- /**
- * DVR
- *
- * <p>See <a href="https://goto.google.com/atv-dvr-onepager">go/atv-dvr-onepager</a>
- * <p>Note: To make DVR work, DvrTvInputService.FEATURE_DVR should be {@code true}.
- */
- public static TestableFeature DVR = createTestableFeature(OFF);
+ public static Feature ANALYTICS_V2 = AND(ON, ANALYTICS_OPT_IN);
public static Feature EPG_SEARCH = new PropertyFeature("feature_tv_use_epg_search", false);
- public static SharedPreferencesFeature USB_TUNER = new SharedPreferencesFeature("usb_tuner",
- false, OR(ENG_ONLY_FEATURE, new GServiceFeature("usbtuner_enabled", false)));
+ public static SharedPreferencesFeature USB_TUNER = new SharedPreferencesFeature(
+ "usb_tuner", true,
+ OR(ENG_ONLY_FEATURE, new GServiceFeature("usbtuner_enabled", false)));
public static Feature DEVELOPER_OPTION = OR(ENG_ONLY_FEATURE,
new GServiceFeature("usbtuner_enabled", false));
- /**
- * A flag which indicates that LC app is unhidden even when there is no input.
- */
- public static Feature UNHIDE = OFF;
+ private static final String PLAY_STORE_PACKAGE_NAME = "com.android.vending";
+ private static final int PLAY_STORE_ZIMA_VERSION_CODE = 80441186;
+ private static Feature PLAY_STORE_LINK = new PackageVersionFeature(PLAY_STORE_PACKAGE_NAME,
+ PLAY_STORE_ZIMA_VERSION_CODE);
+
+ public static Feature ONBOARDING_PLAY_STORE = PLAY_STORE_LINK;
/**
* A flag which indicates that the on-boarding experience is used or not.
*
* <p>See <a href="http://b/24070322">b/24070322</a>
*/
- public static Feature ONBOARDING_EXPERIENCE = new PropertyFeature(
- "feature_tv_use_onboarding_exp", false);
+ public static Feature ONBOARDING_EXPERIENCE = ONBOARDING_PLAY_STORE;
- public static Feature ONBOARDING_PLAY_STORE = AND(ONBOARDING_EXPERIENCE, OFF);
- public static Feature ONBOARDING_USB_TUNER = AND(ONBOARDING_EXPERIENCE, USB_TUNER);
+ private static final String GSERVICE_KEY_UNHIDE = "live_channels_unhide";
+ /**
+ * A flag which indicates that LC app is unhidden even when there is no input.
+ */
+ public static Feature UNHIDE = AND(ONBOARDING_EXPERIENCE,
+ new GServiceFeature(GSERVICE_KEY_UNHIDE, false));
@VisibleForTesting
public static Feature TEST_FEATURE = new PropertyFeature("test_feature", false);
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index 6bb2995b..5ea23a79 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -17,7 +17,6 @@
package com.android.tv;
import android.app.Activity;
-import android.app.FragmentTransaction;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -68,11 +67,15 @@ 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;
+import com.android.tv.common.BuildConfig;
+import com.android.tv.common.MemoryManageable;
import com.android.tv.common.TvCommonUtils;
+import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.WeakHandler;
-import com.android.tv.common.dvr.DvrSessionClient;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
@@ -82,7 +85,10 @@ import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.SafeDismissDialogFragment;
+import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrPlayActivity;
+import com.android.tv.dvr.Recording;
import com.android.tv.menu.Menu;
import com.android.tv.onboarding.OnboardingActivity;
import com.android.tv.parental.ContentRatingsManager;
@@ -101,17 +107,16 @@ import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.OnTuneListener;
import com.android.tv.ui.TvOverlayManager;
import com.android.tv.ui.TvViewUiManager;
-import com.android.tv.ui.sidepanel.ChannelSourcesFragment;
import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.CustomizeChannelListFragment;
import com.android.tv.ui.sidepanel.DebugOptionFragment;
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.CaptionSettings;
import com.android.tv.util.ImageCache;
-import com.android.tv.util.MemoryManageable;
+import com.android.tv.util.ImageLoader;
import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.PermissionUtils;
import com.android.tv.util.PipInputManager;
@@ -230,18 +235,17 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private AccessibilityManager mAccessibilityManager;
private ChannelDataManager mChannelDataManager;
private ProgramDataManager mProgramDataManager;
- private WatchedHistoryManager mWatchedHistoryManager;
private TvInputManagerHelper mTvInputManagerHelper;
private ChannelTuner mChannelTuner;
private PipInputManager mPipInputManager;
private final TvOptionsManager mTvOptionsManager = new TvOptionsManager(this);
private TvViewUiManager mTvViewUiManager;
private TimeShiftManager mTimeShiftManager;
- private DvrManager mDvrManager;
private Tracker mTracker;
private final DurationTimer mMainDurationTimer = new DurationTimer();
private final DurationTimer mTuneDurationTimer = new DurationTimer();
- private DvrSessionClient mDvrSessionClientForDebug;
+ private DvrManager mDvrManager;
+ private DvrDataManager mDvrDataManager;
private TunableTvView mTvView;
private TunableTvView mPipView;
@@ -264,7 +268,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private int mNowPlayingCardHeight;
private String mInputIdUnderSetup;
- private boolean mIsSetupActivityCalledByDialog;
+ private boolean mIsSetupActivityCalledByPopup;
private AudioManager mAudioManager;
private int mAudioFocusStatus;
private boolean mTunePending;
@@ -282,6 +286,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private boolean mNeedShowBackKeyGuide;
private boolean mVisibleBehind;
private boolean mAc3PassthroughSupported;
+ private boolean mShowNewSourcesFragment = true;
+ private Uri mRecordingUri;
private boolean mIsFilmModeSet;
private float mDefaultRefreshRate;
@@ -310,6 +316,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
private RecurringRunner mSendConfigInfoRecurringRunner;
+ private RecurringRunner mChannelStatusRecurringRunner;
// A caller which started this activity. (e.g. TvSearch)
private String mSource;
@@ -373,7 +380,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
new ChannelTuner.Listener() {
@Override
public void onLoadFinished() {
- markNewChannelsBrowsable();
+ SetupUtils.getInstance(MainActivity.this).markNewChannelsBrowsable();
if (mActivityResumed) {
resumeTvIfNeeded();
resumePipIfNeeded();
@@ -416,15 +423,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
.isParentalControlsEnabled();
mTvView.onParentalControlChanged(parentalControlEnabled);
mPipView.onParentalControlChanged(parentalControlEnabled);
- mTvOptionsManager.onParentalControlChanged(parentalControlEnabled);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG,"onCreate()");
super.onCreate(savedInstanceState);
- TvApplication tvApplication = (TvApplication) getApplication();
- tvApplication.setMainActivity(this);
if (Features.ONBOARDING_EXPERIENCE.isEnabled(this)
&& OnboardingUtils.needToShowOnboarding(this)
@@ -436,6 +440,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return;
}
+ 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();
}
@@ -453,7 +459,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mPipInputManager.start();
mMemoryManageables.add(mProgramDataManager);
mMemoryManageables.add(ImageCache.getInstance());
- mDvrManager = tvApplication.getDvrManager();
+ mMemoryManageables.add(TvContentRatingCache.getInstance());
+ if(CommonFeatures.DVR.isEnabled(this)) {
+ mDvrManager = tvApplication.getDvrManager();
+ mDvrDataManager = tvApplication.getDvrDataManager();
+ }
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
@@ -518,9 +528,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
shrunkenTvViewHeight);
if (!PermissionUtils.hasAccessWatchedHistory(this)) {
- mWatchedHistoryManager = new WatchedHistoryManager(getApplicationContext());
- mWatchedHistoryManager.start();
- mTvView.setWatchedHistoryManager(mWatchedHistoryManager);
+ WatchedHistoryManager watchedHistoryManager = new WatchedHistoryManager(
+ getApplicationContext());
+ watchedHistoryManager.start();
+ mTvView.setWatchedHistoryManager(watchedHistoryManager);
}
mTvViewUiManager = new TvViewUiManager(this, mTvView, mPipView,
(FrameLayout) findViewById(android.R.id.content), mTvOptionsManager);
@@ -564,7 +575,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
}
});
mSearchFragment = new ProgramGuideSearchFragment();
@@ -607,8 +619,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mAccessibilityManager =
(AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
mSendConfigInfoRecurringRunner = new RecurringRunner(this, TimeUnit.DAYS.toMillis(1),
- new SendConfigInfoRunnable(mTracker, mTvInputManagerHelper));
+ new SendConfigInfoRunnable(mTracker, mTvInputManagerHelper), null);
mSendConfigInfoRecurringRunner.start();
+ mChannelStatusRecurringRunner = SendChannelStatusRunnable
+ .startChannelStatusRecurringRunner(this, mTracker, mChannelDataManager);
initForTest();
}
@@ -668,6 +682,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
return TunableTvView.BLOCK_SCREEN_TYPE_NO_UI;
}
+ if (mOverlayManager.isSetupFragmentActive()
+ || mOverlayManager.isNewSourcesFragmentActive()) {
+ return TunableTvView.BLOCK_SCREEN_TYPE_NO_UI;
+ }
return TunableTvView.BLOCK_SCREEN_TYPE_NORMAL;
}
@@ -720,6 +738,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
SystemProperties.updateSystemProperties();
mNeedShowBackKeyGuide = true;
mActivityResumed = true;
+ mShowNewSourcesFragment = true;
int result = mAudioManager.requestAudioFocus(MainActivity.this,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
mAudioFocusStatus = (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) ?
@@ -732,7 +751,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
requestVisibleBehind(true);
}
if (mChannelTuner.areAllChannelsLoaded()) {
- markNewChannelsBrowsable();
+ SetupUtils.getInstance(this).markNewChannelsBrowsable();
resumeTvIfNeeded();
resumePipIfNeeded();
}
@@ -862,32 +881,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- private void markNewChannelsBrowsable() {
- SetupUtils setupUtils = SetupUtils.getInstance(MainActivity.this);
- Set<String> newInputsWithChannels = new HashSet<>();
- for (TvInputInfo input : mTvInputManagerHelper.getTvInputInfos(true, true)) {
- String inputId = input.getId();
- if (!setupUtils.isSetupDone(inputId)
- && mChannelDataManager.getChannelCountForInput(inputId) > 0) {
- setupUtils.onSetupDone(inputId);
- newInputsWithChannels.add(inputId);
- if (DEBUG) {
- Log.d(TAG, "New input " + inputId + " has "
- + mChannelDataManager.getChannelCountForInput(inputId)
- + " channels");
- }
- }
- }
- if (!newInputsWithChannels.isEmpty()) {
- for (Channel channel : mChannelDataManager.getChannelList()) {
- if (newInputsWithChannels.contains(channel.getInputId())) {
- mChannelDataManager.updateBrowsable(channel.getId(), true);
- }
- }
- mChannelDataManager.applyUpdatedValuesToDb();
- }
- }
-
private void startTv(Uri channelUri) {
if (DEBUG) Log.d(TAG, "startTv Uri=" + channelUri);
if ((channelUri == null || !TvContract.isChannelUriForPassthroughInput(channelUri))
@@ -945,7 +938,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTvView.start(mTvInputManagerHelper);
setVolumeByAudioFocusStatus();
- tune();
+ if (mRecordingUri != null) {
+ playRecording(mRecordingUri);
+ mRecordingUri = null;
+ } else {
+ tune();
+ }
}
@Override
@@ -971,9 +969,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
/**
* Starts setup activity for the given input {@code input}.
*
- * @param calledByDialog If true, startSetupActivity is invoked from the setup dialog.
+ * @param calledByPopup If true, startSetupActivity is invoked from the setup fragment.
*/
- public void startSetupActivity(TvInputInfo input, boolean calledByDialog) {
+ public void startSetupActivity(TvInputInfo input, boolean calledByPopup) {
Intent intent = TvCommonUtils.createSetupIntent(input);
if (intent == null) {
Toast.makeText(this, R.string.msg_no_setup_activity, Toast.LENGTH_SHORT).show();
@@ -988,7 +986,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
SetupUtils.grantEpgPermission(this, input.getServiceInfo().packageName);
mInputIdUnderSetup = input.getId();
- mIsSetupActivityCalledByDialog = calledByDialog;
+ mIsSetupActivityCalledByPopup = calledByPopup;
// Call requestVisibleBehind(false) before starting other activity.
// In Activity.requestVisibleBehind(false), this activity is scheduled to be stopped
// immediately if other activity is about to start. And this activity is scheduled to
@@ -1001,9 +999,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
input.loadLabel(this)), Toast.LENGTH_SHORT).show();
return;
}
- if (calledByDialog) {
+ if (calledByPopup) {
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
} else {
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY);
@@ -1127,31 +1125,20 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
/**
- * Show channel sources fragment.
+ * Show settings fragment.
*/
- public void showChannelSourcesFragment() {
+ public void showSettingsFragment() {
if (!mChannelTuner.areAllChannelsLoaded()) {
// 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 ChannelSourcesFragment(channelId));
+ mOverlayManager.getSideFragmentManager().show(new SettingsFragment(channelId));
}
- // TODO: Refactor this.
- public void showParentalControlFragment() {
- mOverlayManager.showDialogFragment(PinDialogFragment.DIALOG_TAG,
- new PinDialogFragment(PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- mOverlayManager.getSideFragmentManager()
- .show(new ParentalControlsFragment());
- }
- }
- }), false);
+ public void showMerchantCollection() {
+ startActivitySafe(OnboardingUtils.PLAY_STORE_INTENT);
}
/**
@@ -1259,7 +1246,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
} else {
mInputIdUnderSetup = null;
}
- if (!mIsSetupActivityCalledByDialog) {
+ if (!mIsSetupActivityCalledByPopup) {
mOverlayManager.getSideFragmentManager().showSidePanel(false);
}
break;
@@ -1377,6 +1364,13 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
+ if (CommonFeatures.DVR.isEnabled(this)) {
+ mRecordingUri = intent.getParcelableExtra(Utils.EXTRA_KEY_RECORDING_URI);
+ if (mRecordingUri != null) {
+ return true;
+ }
+ }
+
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
try {
@@ -1502,6 +1496,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mMediaSession.setActive(false);
}
}
+ TvApplication.getSingletons(this).getMainActivityWrapper()
+ .notifyCurrentChannelChange(this, null);
mChannelTuner.resetCurrentChannel();
mTunePending = false;
}
@@ -1613,6 +1609,30 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
+ private void playRecording(Uri recordingUri) {
+ String inputId = recordingUri.getQueryParameter(Recording.PARAM_INPUT_ID);
+ SoftPreconditions.checkNotNull(inputId);
+ mTvView.playRecording(inputId, recordingUri, new OnTuneListener() {
+ @Override
+ public void onTuneFailed(Channel channel) { }
+
+ @Override
+ public void onUnexpectedStop(Channel channel) { }
+
+ @Override
+ public void onStreamInfoChanged(StreamInfo info) { }
+
+ @Override
+ public void onChannelRetuned(Uri channel) { }
+
+ @Override
+ public void onContentBlocked() { }
+
+ @Override
+ public void onContentAllowed() { }
+ });
+ }
+
private void tune() {
if (DEBUG) Log.d(TAG, "tune()");
mTuneDurationTimer.start();
@@ -1641,11 +1661,27 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
if (mChannelDataManager.getChannelCount() > 0) {
mOverlayManager.showIntroDialog();
- } else {
- mOverlayManager.showSetupDialog();
+ } else if (!Features.ONBOARDING_EXPERIENCE.isEnabled(this)) {
+ 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();
+ }
+ });
+ }
+ });
+ }
+ mShowNewSourcesFragment = false;
if (!mChannelTuner.isCurrentChannelPassthrough()
&& mChannelTuner.getBrowsableChannelCount() == 0
&& mChannelDataManager.getChannelCount() > 0
@@ -1656,7 +1692,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mTvInputManagerHelper.getTunerTvInputSize() == 1) {
mOverlayManager.getSideFragmentManager().show(new CustomizeChannelListFragment());
} else {
- showChannelSourcesFragment();
+ showSettingsFragment();
}
return;
}
@@ -1673,7 +1709,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mOverlayManager.getSideFragmentManager().isActive()) {
return;
}
- mOverlayManager.showSetupDialog();
+ mOverlayManager.showSetupFragment();
return;
}
@@ -1828,6 +1864,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
addToRecentChannels(channel.getId());
}
Utils.setLastWatchedChannel(this, channel);
+ TvApplication.getSingletons(this).getMainActivityWrapper()
+ .notifyCurrentChannelChange(this, channel);
}
checkChannelLockNeeded(mTvView);
updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_TUNE);
@@ -1840,6 +1878,23 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
updateMediaSession();
}
+ private void runAfterAttachedToWindow(final Runnable runnable) {
+ if (mOverlayRootView.isLaidOut()) {
+ runnable.run();
+ } else {
+ mOverlayRootView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mOverlayRootView.removeOnAttachStateChangeListener(this);
+ runnable.run();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) { }
+ });
+ }
+ }
+
private void updateMediaSession() {
if (getCurrentChannel() == null) {
mMediaSession.setActive(false);
@@ -1858,7 +1913,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return;
}
- Program program = getCurrentProgram();
+ final Program program = getCurrentProgram();
String cardTitleText = program == null ? null : program.getTitle();
if (TextUtils.isEmpty(cardTitleText)) {
cardTitleText = getCurrentChannel().getDisplayName();
@@ -1868,24 +1923,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (program != null && program.getPosterArtUri() != null) {
program.loadPosterArt(MainActivity.this, mNowPlayingCardWidth, mNowPlayingCardHeight,
- new Program.LoadPosterArtCallback() {
- @Override
- public void onLoadPosterArtFinished(Program program, Bitmap posterArt) {
- if (program != getCurrentProgram() || getCurrentChannel() == null) {
- return;
- }
-
- if (posterArt != null) {
- String cardTitleText = program == null ? null : program.getTitle();
- if (TextUtils.isEmpty(cardTitleText)) {
- cardTitleText = getCurrentChannel().getDisplayName();
- }
- updateMediaMetadata(cardTitleText, posterArt);
- } else {
- updateMediaMetadataWithAlternativeArt(program);
- }
- }
- });
+ createProgramPosterArtCallback(MainActivity.this, program));
} else {
updateMediaMetadataWithAlternativeArt(program);
}
@@ -1893,6 +1931,32 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mMediaSession.setActive(true);
}
+ private static ImageLoader.ImageLoaderCallback<MainActivity> createProgramPosterArtCallback(
+ MainActivity mainActivity, final Program program) {
+ return new ImageLoader.ImageLoaderCallback<MainActivity>(mainActivity) {
+ @Override
+ public void onBitmapLoaded(MainActivity mainActivity, @Nullable Bitmap posterArt) {
+ if (program != mainActivity.getCurrentProgram()
+ || mainActivity.getCurrentChannel() == null) {
+ return;
+ }
+ mainActivity.updateProgramPosterArt(program, posterArt);
+ }
+ };
+ }
+
+ private void updateProgramPosterArt(Program program, @Nullable Bitmap posterArt) {
+ if (posterArt != null) {
+ String cardTitleText = program == null ? null : program.getTitle();
+ if (TextUtils.isEmpty(cardTitleText)) {
+ cardTitleText = getCurrentChannel().getDisplayName();
+ }
+ updateMediaMetadata(cardTitleText, posterArt);
+ } else {
+ updateMediaMetadataWithAlternativeArt(program);
+ }
+ }
+
private void updateMediaMetadata(String title, Bitmap posterArt) {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder.putString(MediaMetadata.METADATA_KEY_TITLE, title);
@@ -2027,7 +2091,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
boolean noOverlayUiWhenResume =
mInputToSetUp == null && !mShowProgramGuide && !mShowSelectInputView;
if (needToShowBanner && noOverlayUiWhenResume
- && mOverlayManager.getCurrentDialog() == null) {
+ && mOverlayManager.getCurrentDialog() == null
+ && !mOverlayManager.isSetupFragmentActive()
+ && !mOverlayManager.isNewSourcesFragmentActive()) {
if (mChannelTuner.getCurrentChannel() == null) {
mChannelBannerHiddenBySideFragment = false;
} else if (mOverlayManager.getSideFragmentManager().isActive()) {
@@ -2047,8 +2113,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SCENE);
}
- public boolean needToKeepDialogWhenHidingOverlay() {
- return mInputIdUnderSetup != null && mIsSetupActivityCalledByDialog;
+ public boolean needToKeepSetupScreenWhenHidingOverlay() {
+ return mInputIdUnderSetup != null && mIsSetupActivityCalledByPopup;
}
// For now, this only takes care of 24fps.
@@ -2180,10 +2246,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
public void showProgramGuideSearchFragment() {
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.replace(R.id.search, mSearchFragment);
- ft.addToBackStack(null);
- ft.commit();
+ getFragmentManager().beginTransaction().replace(R.id.fragment_container, mSearchFragment)
+ .addToBackStack(null).commit();
}
@Override
@@ -2204,7 +2268,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mProgramDataManager != null) {
mProgramDataManager.removeOnCurrentProgramUpdatedListener(
Channel.INVALID_ID, mOnCurrentProgramUpdatedListener);
- if (application.isCurrentMainActivity(this)) {
+ if (application.getMainActivityWrapper().isCurrent(this)) {
mProgramDataManager.setPrefetchEnabled(false);
}
}
@@ -2225,13 +2289,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mAudioCapabilitiesReceiver.unregister();
}
mHandler.removeCallbacksAndMessages(null);
- if (application.isCurrentMainActivity(this)) {
- application.setMainActivity(null);
- }
+ application.getMainActivityWrapper().onMainActivityDestroyed(this);
if (mSendConfigInfoRecurringRunner != null) {
mSendConfigInfoRecurringRunner.stop();
mSendConfigInfoRecurringRunner = null;
}
+ if (mChannelStatusRecurringRunner != null) {
+ mChannelStatusRecurringRunner.stop();
+ mChannelStatusRecurringRunner = null;
+ }
super.onDestroy();
}
@@ -2295,11 +2361,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
* I KEYCODE_TV_INPUT
* O debug: show display mode option
* P debug: togglePipView
- * R KEYCODE_MEDIA_STOP debug: dvr stop recording
* S KEYCODE_CAPTIONS: select subtitle
- * V KEYCODE_MEDIA_RECORD debug: dvr start recording
* W debug: toggle screen size
- * Z KEYCODE_PROG_RED debug: create program data for current channel
+ * V KEYCODE_MEDIA_RECORD debug: record the current channel for 30 sec
+ * X KEYCODE_BUTTON_X KEYCODE_PROG_BLUE debug: record current channel for a few minutes
+ * Y KEYCODE_BUTTON_Y KEYCODE_PROG_GREEN debug: Play a recording
*/
if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "onKeyUp(" + keyCode + ", " + event + ")");
@@ -2348,7 +2414,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_E:
case KeyEvent.KEYCODE_MENU:
- showChannelSourcesFragment();
+ showSettingsFragment();
return true;
}
} else {
@@ -2487,51 +2553,48 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
case KeyEvent.KEYCODE_MEDIA_RECORD: // TODO(DVR) handle with debug_keys set
case KeyEvent.KEYCODE_V: {
- if (mDvrSessionClientForDebug != null) {
- mDvrSessionClientForDebug.release();
- mDvrSessionClientForDebug = null;
- }
- mDvrSessionClientForDebug = new DvrSessionClient(MainActivity.this);
- Channel dvrChannel = null;
- for (Channel channel : mChannelDataManager.getBrowsableChannelList()) {
- if (channel.getInputId().equals(DVR_TEST_INPUT_ID)) {
- dvrChannel = channel;
- break;
+ DvrManager dvrManager = TvApplication.getSingletons(this).getDvrManager();
+ long startTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(5);
+ long endTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(35);
+ dvrManager.addSchedule(getCurrentChannel(), startTime, endTime);
+ return true;
+ }
+ case KeyEvent.KEYCODE_PROG_BLUE:
+ case KeyEvent.KEYCODE_BUTTON_X:
+ case KeyEvent.KEYCODE_X: {
+ if (CommonFeatures.DVR.isEnabled(this)) {
+ Channel channel = mTvView.getCurrentChannel();
+ long channelId = channel.getId();
+ Program p = mProgramDataManager.getCurrentProgram(channelId);
+ if (p == null) {
+ long now = System.currentTimeMillis();
+ mDvrManager
+ .addSchedule(channel, now, now + TimeUnit.MINUTES.toMillis(1));
+ } else {
+ mDvrManager.addSchedule(p,
+ mDvrManager.getScheduledRecordingsThatConflict(p));
}
- }
- if (dvrChannel == null) {
return true;
}
- final Channel channel = dvrChannel;
- mDvrSessionClientForDebug.connect(DVR_TEST_INPUT_ID, new DvrSessionClient.Callback() {
- @Override
- public void onConnected() {
- mDvrSessionClientForDebug.startRecord(channel.getUri(), channel.getUri());
- }
- });
- return true;
}
- case KeyEvent.KEYCODE_MEDIA_STOP: // TODO(DVR) handle with debug_keys set
- case KeyEvent.KEYCODE_R:
- if (mDvrSessionClientForDebug == null) {
+ case KeyEvent.KEYCODE_PROG_YELLOW:
+ case KeyEvent.KEYCODE_BUTTON_Y:
+ case KeyEvent.KEYCODE_Y: {
+ if (CommonFeatures.DVR.isEnabled(this)) {
+ // TODO(DVR) only get finished recordings.
+ List<Recording> recordings = mDvrDataManager.getRecordings();
+ Log.d(TAG, "Found " + recordings.size() + " recordings");
+ if (recordings.isEmpty()) {
+ Toast.makeText(this, "No finished recording to play", Toast.LENGTH_LONG)
+ .show();
+ } else {
+ Recording r = recordings.get(0);
+ Intent intent = new Intent(this, DvrPlayActivity.class);
+ intent.putExtra(Recording.RECORDING_ID_EXTRA, r.getId());
+ startActivity(intent);
+ }
return true;
}
- mDvrSessionClientForDebug.stopRecord();
- mDvrSessionClientForDebug.release();
- mDvrSessionClientForDebug = null;
- return true;
- case KeyEvent.KEYCODE_PROG_RED:
- case KeyEvent.KEYCODE_Z: {
- Channel channel = mTvView.getCurrentChannel();
- long channelId = channel.getId();
- Program p = mProgramDataManager.getCurrentProgram(channelId);
- if (p == null) {
- long now = System.currentTimeMillis();
- mDvrManager.addSchedule(channel, now, now + TimeUnit.MINUTES.toMillis(5));
- } else {
- mDvrManager.addSchedule(p);
- }
- return true;
}
}
}
@@ -2657,7 +2720,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
tuneToChannel(mChannelTuner.getCurrentChannel());
} else {
- showChannelSourcesFragment();
+ showSettingsFragment();
}
}
@@ -2722,7 +2785,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
// Channel banner would be updated inside of tune.
tune();
} else {
- showChannelSourcesFragment();
+ showSettingsFragment();
}
}
}
@@ -2730,7 +2793,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
/**
* This method just moves the channel in the channel map and updates the channel banner,
* but doesn't actually tune to the channel.
- * The caller of this method should call tune() in the end.
+ * The caller of this method should call {@link #tune} in the end.
*
* @param channelUp {@code true} for channel up, and {@code false} for channel down.
* @param fastTuning {@code true} if fast tuning is requested.
diff --git a/src/com/android/tv/MainActivityWrapper.java b/src/com/android/tv/MainActivityWrapper.java
new file mode 100644
index 00000000..94f11864
--- /dev/null
+++ b/src/com/android/tv/MainActivityWrapper.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;
+
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+
+import com.android.tv.common.CollectionUtils;
+import com.android.tv.data.Channel;
+
+import java.util.Set;
+
+/**
+ * A wrapper for safely getting the current {@link MainActivity}.
+ * Note that this class is not thread-safe. All the public methods should be called on main thread.
+ */
+@MainThread
+public final class MainActivityWrapper {
+ private MainActivity mActivity;
+
+ private final Set<OnCurrentChannelChangeListener> mListeners = CollectionUtils.createSmallSet();
+
+ /**
+ * Returns the current main activity.
+ * <b>WARNING</b> do not keep a reference to MainActivity, leaking activities is expensive.
+ */
+ MainActivity getMainActivity() {
+ return mActivity;
+ }
+
+ /**
+ * Checks if the given {@code activity} is the current main activity.
+ */
+ boolean isCurrent(MainActivity activity) {
+ return activity != null && mActivity == activity;
+ }
+
+ /**
+ * Sets the currently created main activity instance.
+ */
+ @UiThread
+ public void onMainActivityCreated(@NonNull MainActivity activity) {
+ mActivity = activity;
+ }
+
+ /**
+ * Unsets the main activity instance.
+ */
+ @UiThread
+ public void onMainActivityDestroyed(@NonNull MainActivity activity) {
+ if (mActivity != activity) {
+ mActivity = null;
+ }
+ }
+
+ /**
+ * Notifies the current channel change.
+ */
+ void notifyCurrentChannelChange(@NonNull MainActivity caller, @Nullable Channel channel) {
+ if (mActivity == caller) {
+ for (OnCurrentChannelChangeListener listener : mListeners) {
+ listener.onCurrentChannelChange(channel);
+ }
+ }
+ }
+
+ /**
+ * Checks if the main activity is created.
+ */
+ public boolean isCreated() {
+ return mActivity != null;
+ }
+
+ /**
+ * Checks if the main activity is started.
+ */
+ public boolean isStarted() {
+ return mActivity != null && mActivity.isActivityStarted();
+ }
+
+ /**
+ * Checks if the main activity is resumed.
+ */
+ public boolean isResumed() {
+ return mActivity != null && mActivity.isActivityResumed();
+ }
+
+ /**
+ * Adds OnCurrentChannelChangeListener.
+ */
+ @UiThread
+ public void addOnCurrentChannelChangeListener(OnCurrentChannelChangeListener listener) {
+ mListeners.add(listener);
+ }
+
+ /**
+ * Removes OnCurrentChannelChangeListener.
+ */
+ @UiThread
+ public void removeOnCurrentChannelChangeListener(OnCurrentChannelChangeListener listener) {
+ mListeners.remove(listener);
+ }
+
+ /**
+ * Listener for the current channel change in main activity.
+ */
+ public interface OnCurrentChannelChangeListener {
+ /**
+ * Called when the current channel changes.
+ */
+ void onCurrentChannelChange(@Nullable Channel channel);
+ }
+}
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 0c7a5d65..bdabf25b 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -79,7 +79,9 @@ public class SetupPassthroughActivity extends Activity {
@Override
public void onActivityResult(int requestCode, final int resultCode, final Intent data) {
- if (requestCode != REQUEST_START_SETUP_ACTIVITY || resultCode != Activity.RESULT_OK) {
+ boolean setupComplete = requestCode == REQUEST_START_SETUP_ACTIVITY
+ && resultCode == Activity.RESULT_OK;
+ if (!setupComplete) {
setResult(resultCode, data);
finish();
return;
diff --git a/src/com/android/tv/TimeShiftManager.java b/src/com/android/tv/TimeShiftManager.java
index 5a7b51c1..f96464e3 100644
--- a/src/com/android/tv/TimeShiftManager.java
+++ b/src/com/android/tv/TimeShiftManager.java
@@ -86,9 +86,9 @@ public class TimeShiftManager {
public static final int PLAY_DIRECTION_BACKWARD = 1;
@Retention(RetentionPolicy.SOURCE)
- @IntDef({TIME_SHIFT_ACTION_ID_PLAY, TIME_SHIFT_ACTION_ID_PAUSE, TIME_SHIFT_ACTION_ID_REWIND,
- TIME_SHIFT_ACTION_ID_FAST_FORWARD, TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS,
- TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT})
+ @IntDef(flag = true, value = {TIME_SHIFT_ACTION_ID_PLAY, TIME_SHIFT_ACTION_ID_PAUSE,
+ TIME_SHIFT_ACTION_ID_REWIND, TIME_SHIFT_ACTION_ID_FAST_FORWARD,
+ TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS, TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT})
public @interface TimeShiftActionId{}
public static final int TIME_SHIFT_ACTION_ID_PLAY = 1;
public static final int TIME_SHIFT_ACTION_ID_PAUSE = 1 << 1;
@@ -103,6 +103,7 @@ public class TimeShiftManager {
private static final long MAX_DUMMY_PROGRAM_DURATION = TimeUnit.MINUTES.toMillis(30);
@VisibleForTesting
static final long INVALID_TIME = -1;
+ static final long CURRENT_TIME = -2;
private static final long PREFETCH_TIME_OFFSET_FROM_PROGRAM_END = TimeUnit.MINUTES.toMillis(1);
private static final long PREFETCH_DURATION_FOR_NEXT = TimeUnit.HOURS.toMillis(2);
@@ -218,6 +219,22 @@ public class TimeShiftManager {
}
/**
+ * Returns the end time of the recording in milliseconds.
+ */
+ public long getRecordEndTimeMs() {
+ if (mPlayController.mRecordEndTimeMs == CURRENT_TIME) {
+ return System.currentTimeMillis();
+ } else {
+ return mPlayController.mRecordEndTimeMs;
+ }
+ }
+
+ public boolean isPlayForRecording() {
+ // TODO: need to find better way to check if it's for recording playback.
+ return mPlayController.mRecordEndTimeMs != CURRENT_TIME;
+ }
+
+ /**
* Plays the media.
*
* @throws IllegalStateException if the trick play is not available.
@@ -419,7 +436,7 @@ public class TimeShiftManager {
// Fast forward action and jump to next action
threshold = isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD)
? DISABLE_ACTION_THRESHOLD : ENABLE_ACTION_THRESHOLD;
- enabled = System.currentTimeMillis() - mCurrentPositionMediator.mCurrentPositionMs
+ enabled = getRecordEndTimeMs() - mCurrentPositionMediator.mCurrentPositionMs
> threshold;
enableAction(TIME_SHIFT_ACTION_ID_FAST_FORWARD, enabled);
enableAction(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT, enabled);
@@ -495,13 +512,14 @@ public class TimeShiftManager {
}
}
- void onRecordStartTimeChanged() {
+ void onRecordTimeRangeChanged() {
if (mPlayController.isAvailable()) {
- mProgramManager.onRecordStartTimeChanged(mPlayController.mRecordStartTimeMs);
+ mProgramManager.onRecordTimeRangeChanged(mPlayController.mRecordStartTimeMs,
+ mPlayController.mRecordEndTimeMs);
}
updateActions();
if (mNotificationEnabled && mListener != null) {
- mListener.onRecordStartTimeChanged();
+ mListener.onRecordTimeRangeChanged();
}
}
@@ -574,6 +592,7 @@ public class TimeShiftManager {
private long mPossibleStartTimeMs;
private long mRecordStartTimeMs;
+ private long mRecordEndTimeMs;
@PlayStatus private int mPlayStatus = PLAY_STATUS_PAUSED;
@PlaySpeed private int mDisplayedPlaySpeed = PLAY_SPEED_1X;
@@ -604,6 +623,7 @@ public class TimeShiftManager {
mIsPlayOffsetChanged = false;
mPossibleStartTimeMs = System.currentTimeMillis();
mRecordStartTimeMs = mPossibleStartTimeMs;
+ mRecordEndTimeMs = CURRENT_TIME;
mCurrentPositionMediator.initialize(mPossibleStartTimeMs);
mHandler.removeMessages(MSG_GET_CURRENT_POSITION);
@@ -622,7 +642,8 @@ public class TimeShiftManager {
@Override
public void onRecordStartTimeChanged(long recordStartTimeMs) {
- if (recordStartTimeMs < mPossibleStartTimeMs) {
+ if (mRecordEndTimeMs == CURRENT_TIME &&
+ recordStartTimeMs < mPossibleStartTimeMs) {
// Do not warn in this case because it can happen in normal cases.
if (DEBUG) {
Log.d(TAG, "Record start time is less then the time when it became "
@@ -637,7 +658,7 @@ public class TimeShiftManager {
return;
}
mRecordStartTimeMs = recordStartTimeMs;
- TimeShiftManager.this.onRecordStartTimeChanged();
+ TimeShiftManager.this.onRecordTimeRangeChanged();
// According to the UX guidelines, the stream should be resumed if the
// recording buffer fills up while paused, which means that the current time
@@ -654,6 +675,21 @@ public class TimeShiftManager {
TimeShiftManager.this.play();
}
}
+
+ @Override
+ public void onRecordEndTimeChanged(long recordEndTimeMs) {
+ if (mRecordEndTimeMs == recordEndTimeMs) {
+ return;
+ }
+ mRecordEndTimeMs = recordEndTimeMs;
+ TimeShiftManager.this.onRecordTimeRangeChanged();
+
+ if (mPlayStatus == PLAY_STATUS_PLAYING &&
+ mRecordEndTimeMs - getCurrentPositionMs()
+ < RECORDING_BOUNDARY_THRESHOLD) {
+ TimeShiftManager.this.pause();
+ }
+ }
});
}
@@ -663,7 +699,8 @@ public class TimeShiftManager {
void handleGetCurrentPosition() {
if (mIsPlayOffsetChanged) {
- long currentTimeMs = System.currentTimeMillis();
+ long currentTimeMs = mRecordEndTimeMs == CURRENT_TIME ? System.currentTimeMillis()
+ : mRecordEndTimeMs;
long currentPositionMs = Math.max(
Math.min(mTvView.timeshiftGetCurrentPositionMs(), currentTimeMs),
mRecordStartTimeMs);
@@ -755,8 +792,9 @@ public class TimeShiftManager {
* Moves to the specified time.
*/
void seekTo(long timeMs) {
- mTvView.timeshiftSeekTo(Math.min(System.currentTimeMillis(),
- Math.max(mRecordStartTimeMs, timeMs)));
+ mTvView.timeshiftSeekTo(Math.min(mRecordEndTimeMs == CURRENT_TIME
+ ? System.currentTimeMillis() : mRecordEndTimeMs,
+ Math.max(mRecordStartTimeMs, timeMs)));
mIsPlayOffsetChanged = true;
}
@@ -851,17 +889,19 @@ public class TimeShiftManager {
}
}
- void onRecordStartTimeChanged(long startTimeMs) {
+ void onRecordTimeRangeChanged(long startTimeMs, long endTimeMs) {
if (mChannel == null || mChannel.isPassthrough()) {
return;
}
- long currentMs = System.currentTimeMillis();
+ if (endTimeMs == CURRENT_TIME) {
+ endTimeMs = System.currentTimeMillis();
+ }
long fetchStartTimeMs = Utils.floorTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
boolean needToLoad = addDummyPrograms(fetchStartTimeMs,
- currentMs + PREFETCH_DURATION_FOR_NEXT);
+ endTimeMs + PREFETCH_DURATION_FOR_NEXT);
if (needToLoad) {
- Range<Long> period = Range.create(fetchStartTimeMs, currentMs);
+ Range<Long> period = Range.create(fetchStartTimeMs, endTimeMs);
mProgramLoadQueue.add(period);
startTaskIfNeeded();
}
@@ -1274,7 +1314,7 @@ public class TimeShiftManager {
/**
* Called when the recordStartTime has been changed.
*/
- void onRecordStartTimeChanged();
+ void onRecordTimeRangeChanged();
/**
* Called when the current position is changed.
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index e710026f..0cac4a3b 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -26,23 +26,28 @@ import android.content.pm.PackageManager;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
import android.util.Log;
import android.view.KeyEvent;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.StubAnalytics;
-import com.android.tv.analytics.OptOutPreferenceHelper;
import com.android.tv.analytics.StubAnalytics;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.BuildConfig;
+import com.android.tv.common.SharedPreferencesUtils;
import com.android.tv.common.TvCommonUtils;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManagerImpl;
+import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrRecordingService;
import com.android.tv.dvr.DvrSessionManager;
@@ -56,7 +61,6 @@ import java.util.List;
public class TvApplication extends Application implements ApplicationSingletons {
private static final String TAG = "TvApplication";
private static final boolean DEBUG = false;
- private static String versionName = "";
/**
* Returns the @{@link ApplicationSingletons} using the application context.
@@ -64,29 +68,31 @@ public class TvApplication extends Application implements ApplicationSingletons
public static ApplicationSingletons getSingletons(Context context) {
return (ApplicationSingletons) context.getApplicationContext();
}
+ private String mVersionName = "";
+
+ private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
- private MainActivity mMainActivity;
private SelectInputActivity mSelectInputActivity;
private Analytics mAnalytics;
private Tracker mTracker;
private TvInputManagerHelper mTvInputManagerHelper;
private ChannelDataManager mChannelDataManager;
private ProgramDataManager mProgramDataManager;
- private OptOutPreferenceHelper mOptPreferenceHelper;
private DvrManager mDvrManager;
- private DvrDataManagerImpl mDvrDataManager;
+ private DvrDataManager mDvrDataManager;
@Nullable
private DvrSessionManager mDvrSessionManager;
@Override
public void onCreate() {
super.onCreate();
+ SharedPreferencesUtils.initialize(this);
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
- versionName = pInfo.versionName;
+ mVersionName = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to get version name.", e);
- versionName = "";
+ Log.w(TAG, "Unable to find package '" + getPackageName() + "'.", e);
+ mVersionName = "";
}
Log.i(TAG, "Starting Live TV " + getVersionName());
// Only set StrictMode for ENG builds because the build server only produces userdebug
@@ -102,33 +108,12 @@ public class TvApplication extends Application implements ApplicationSingletons
}
StrictMode.setVmPolicy(vmPolicyBuilder.build());
}
-
if (BuildConfig.ENG && !SystemProperties.ALLOW_ANALYTICS_IN_ENG.getValue()) {
mAnalytics = StubAnalytics.getInstance(this);
} else {
mAnalytics = StubAnalytics.getInstance(this);
}
mTracker = mAnalytics.getDefaultTracker();
- if(Features.ANALYTICS_OPT_OUT.isEnabled(this)) {
- mOptPreferenceHelper = new OptOutPreferenceHelper(this);
- mOptPreferenceHelper.registerChangeListener(mAnalytics,
- OptOutPreferenceHelper.ANALYTICS_OPT_OUT_DEFAULT_VALUE);
- // always start with analytics off
- mAnalytics.setAppOptOut(true);
- // then update with the saved preference in an AsyncTask.
- new AsyncTask<Void, Void, Boolean>() {
- @Override
- protected Boolean doInBackground(Void... voids) {
- return mOptPreferenceHelper.getOptOutPreference(
- OptOutPreferenceHelper.ANALYTICS_OPT_OUT_DEFAULT_VALUE);
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- mAnalytics.setAppOptOut(result);
- }
- }.execute();
- }
mTvInputManagerHelper = new TvInputManagerHelper(this);
mTvInputManagerHelper.start();
mTvInputManagerHelper.addCallback(new TvInputCallback() {
@@ -142,12 +127,16 @@ public class TvApplication extends Application implements ApplicationSingletons
handleInputCountChanged();
}
});
- if (DEBUG) Log.i(TAG, "Started Live TV " + versionName);
- if (Features.DVR.isEnabled(this)) {
+ if (CommonFeatures.DVR.isEnabled(this)) {
mDvrManager = new DvrManager(this);
//NOTE: DvrRecordingService just keeps running.
DvrRecordingService.startService(this);
}
+ // 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);
+ if (DEBUG) Log.i(TAG, "Started Live TV " + mVersionName);
}
/**
@@ -182,10 +171,6 @@ public class TvApplication extends Application implements ApplicationSingletons
return mTracker;
}
- @Override
- public OptOutPreferenceHelper getOptPreferenceHelper(){
- return mOptPreferenceHelper;
- }
/**
* Returns {@link ChannelDataManager}.
@@ -193,7 +178,7 @@ public class TvApplication extends Application implements ApplicationSingletons
@Override
public ChannelDataManager getChannelDataManager() {
if (mChannelDataManager == null) {
- mChannelDataManager = new ChannelDataManager(this, mTvInputManagerHelper, mTracker);
+ mChannelDataManager = new ChannelDataManager(this, mTvInputManagerHelper);
mChannelDataManager.start();
}
return mChannelDataManager;
@@ -217,8 +202,13 @@ public class TvApplication extends Application implements ApplicationSingletons
@Override
public DvrDataManager getDvrDataManager() {
if (mDvrDataManager == null) {
- mDvrDataManager = new DvrDataManagerImpl(this);
- mDvrDataManager.start();
+ if(SystemProperties.USE_IN_MEMORY_DVR_DB.getValue()){
+ mDvrDataManager = new DvrDataManagerInMemoryImpl(this);
+ } else {
+ DvrDataManagerImpl dvrDataManager = new DvrDataManagerImpl(this);
+ mDvrDataManager = dvrDataManager;
+ dvrDataManager.start();
+ }
}
return mDvrDataManager;
}
@@ -232,11 +222,11 @@ public class TvApplication extends Application implements ApplicationSingletons
}
/**
- * MainActivity is set in {@link MainActivity#onCreate} and cleared in
- * {@link MainActivity#onDestroy}.
+ * Returns the main activity information.
*/
- public void setMainActivity(MainActivity activity) {
- mMainActivity = activity;
+ @Override
+ public MainActivityWrapper getMainActivityWrapper() {
+ return mMainActivityWrapper;
}
/**
@@ -248,27 +238,10 @@ public class TvApplication extends Application implements ApplicationSingletons
}
/**
- * Checks if MainActivity is set or not.
- */
- public boolean hasMainActivity() {
- return (mMainActivity != null);
- }
-
- /**
- * Returns true, if {@code activity} is the current activity.
- *
- * Note: MainActivity can start while another MainActivity destroys. In this case, the current
- * activity is the newly created activity.
- */
- public boolean isCurrentMainActivity(MainActivity activity) {
- return mMainActivity == activity;
- }
-
- /**
* Handles the global key KEYCODE_TV.
*/
public void handleTvKey() {
- if (mMainActivity == null || !mMainActivity.isActivityResumed()) {
+ if (!mMainActivityWrapper.isResumed()) {
startMainActivity(null);
}
}
@@ -292,8 +265,8 @@ public class TvApplication extends Application implements ApplicationSingletons
if (inputCount < 2) {
return;
}
- Activity activityToHandle = mMainActivity != null && mMainActivity.isActivityResumed()
- ? mMainActivity : mSelectInputActivity;
+ Activity activityToHandle = mMainActivityWrapper.isResumed()
+ ? mMainActivityWrapper.getMainActivity() : mSelectInputActivity;
if (activityToHandle != null) {
// If startActivity is called, MainActivity.onPause is unnecessarily called. To
// prevent it, MainActivity.dispatchKeyEvent is directly called.
@@ -301,7 +274,7 @@ public class TvApplication extends Application implements ApplicationSingletons
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_TV_INPUT));
activityToHandle.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_TV_INPUT));
- } else if (mMainActivity != null && mMainActivity.isActivityStarted()) {
+ } else if (mMainActivityWrapper.isStarted()) {
Bundle extras = new Bundle();
extras.putString(Utils.EXTRA_KEY_ACTION, Utils.EXTRA_ACTION_SHOW_TV_INPUT);
startMainActivity(extras);
@@ -323,8 +296,13 @@ public class TvApplication extends Application implements ApplicationSingletons
startActivity(intent);
}
- public static String getVersionName() {
- return versionName;
+ /**
+ * Returns the version name of the live channels.
+ *
+ * @see PackageInfo#versionName
+ */
+ public String getVersionName() {
+ return mVersionName;
}
/**
@@ -333,23 +311,26 @@ public class TvApplication extends Application implements ApplicationSingletons
*/
public void handleInputCountChanged() {
TvInputManager inputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
- if (!Features.UNHIDE.isEnabled(TvApplication.this)) {
+ boolean enable = false;
+ if (Features.UNHIDE.isEnabled(TvApplication.this)) {
+ enable = true;
+ } else {
List<TvInputInfo> inputs = inputManager.getTvInputList();
// Enable the TvActivity only if there is at least one tuner type input.
- boolean enable = false;
for (TvInputInfo input : inputs) {
if (input.getType() == TvInputInfo.TYPE_TUNER) {
enable = true;
break;
}
}
- PackageManager packageManager = getPackageManager();
- ComponentName name = new ComponentName(this, TvActivity.class);
- int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
- if (packageManager.getComponentEnabledSetting(name) != newState) {
- packageManager.setComponentEnabledSetting(name, newState, 0);
- }
+ if (DEBUG) Log.d(TAG, "Enable MainActivity: " + enable);
+ }
+ PackageManager packageManager = getPackageManager();
+ ComponentName name = new ComponentName(this, TvActivity.class);
+ int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ if (packageManager.getComponentEnabledSetting(name) != newState) {
+ packageManager.setComponentEnabledSetting(name, newState, 0);
}
SetupUtils.getInstance(TvApplication.this).onInputListUpdated(inputManager);
}
diff --git a/src/com/android/tv/TvOptionsManager.java b/src/com/android/tv/TvOptionsManager.java
index 8af35fae..97b9d5fa 100644
--- a/src/com/android/tv/TvOptionsManager.java
+++ b/src/com/android/tv/TvOptionsManager.java
@@ -37,9 +37,8 @@ public class TvOptionsManager {
public static final int OPTION_DISPLAY_MODE = 1;
public static final int OPTION_PIP = 2;
public static final int OPTION_MULTI_AUDIO = 3;
- public static final int OPTION_CHANNEL_SOURCES = 4;
- public static final int OPTION_PARENTAL_CONTROLS = 5;
- public static final int OPTION_ABOUT = 6;
+ public static final int OPTION_MORE_CHANNELS = 4;
+ public static final int OPTION_SETTINGS = 5;
public static final int OPTION_PIP_INPUT = 100;
public static final int OPTION_PIP_SWAP = 101;
@@ -54,7 +53,6 @@ public class TvOptionsManager {
private int mDisplayMode;
private boolean mPip;
private String mMultiAudio;
- private boolean mIsParentalControlEnabled;
private String mPipInput;
private boolean mPipSwap;
@PipSound private int mPipSound;
@@ -82,10 +80,6 @@ public class TvOptionsManager {
mPip ? R.string.options_item_pip_on : R.string.options_item_pip_off);
case OPTION_MULTI_AUDIO:
return mMultiAudio;
- case OPTION_PARENTAL_CONTROLS:
- return mContext.getString(
- mIsParentalControlEnabled ? R.string.option_toggle_parental_controls_on
- : R.string.option_toggle_parental_controls_off);
case OPTION_PIP_INPUT:
return mPipInput;
case OPTION_PIP_SWAP:
@@ -144,11 +138,6 @@ public class TvOptionsManager {
notifyOptionChanged(OPTION_MULTI_AUDIO);
}
- public void onParentalControlChanged(boolean isParentalControlEnabled) {
- mIsParentalControlEnabled = isParentalControlEnabled;
- notifyOptionChanged(OPTION_PARENTAL_CONTROLS);
- }
-
public void onPipInputChanged(String pipInput) {
mPipInput = pipInput;
notifyOptionChanged(OPTION_PIP_INPUT);
diff --git a/src/com/android/tv/analytics/OptOutPreferenceHelper.java b/src/com/android/tv/analytics/OptOutPreferenceHelper.java
deleted file mode 100644
index 7fefaa46..00000000
--- a/src/com/android/tv/analytics/OptOutPreferenceHelper.java
+++ /dev/null
@@ -1,112 +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.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.preference.PreferenceManager;
-
-/**
- * Handles the opt out preference for analytics, including updating {@link Analytics} with the
- * preference changes.
- */
-public final class OptOutPreferenceHelper {
- /**
- * The {@link SharedPreferences SharedPreferences} key
- * "{@value #ANALYTICS_OPT_OUT_KEY}", true means the user has chosen NOT to send
- * analytics.
- */
- public static final String ANALYTICS_OPT_OUT_KEY = "analytics_opt_out";
-
- /**
- * The default value for the {@link SharedPreferences SharedPreferences} key
- * "{@value #ANALYTICS_OPT_OUT_KEY}" is
- * {@value #ANALYTICS_OPT_OUT_DEFAULT_VALUE}
- */
- public static final boolean ANALYTICS_OPT_OUT_DEFAULT_VALUE = false;
-
- private final SharedPreferences userPrefs;
-
- public OptOutPreferenceHelper(Context context) {
- userPrefs = PreferenceManager.getDefaultSharedPreferences(context);
- }
-
- /**
- * Creates and registers a change listener that will update analytics.
- *
- * @param analytics the analytics to update when opt out settings change.
- * @param defaultValue the default opt out values
- * @return the newly created OptOutChangeListener, keep this pass to
- * {@link #unRegisterChangeListener(OptOutChangeListener)}
- */
- public OptOutChangeListener registerChangeListener(Analytics analytics, boolean defaultValue) {
- OptOutChangeListener changeListener = new OptOutChangeListener(analytics, defaultValue);
- userPrefs.registerOnSharedPreferenceChangeListener(changeListener);
- return changeListener;
- }
-
- /**
- * Unregister a {@link OptOutChangeListener} created by
- * {@link #registerChangeListener(Analytics, boolean)}
- */
- public void unRegisterChangeListener(OptOutChangeListener changeListener) {
- userPrefs.registerOnSharedPreferenceChangeListener(changeListener);
- }
-
- /**
- * Returns the saved opt out preference or {@code defaultValue} if it has been set.
- */
- public boolean getOptOutPreference(boolean defaultValue) {
- return userPrefs.getBoolean(ANALYTICS_OPT_OUT_KEY, defaultValue);
- }
-
- /**
- * Sets the opt out preference.
- */
- public void setOptOutPreference(boolean optOut) {
- userPrefs.edit().putBoolean(ANALYTICS_OPT_OUT_KEY, optOut).apply();
- }
-
- /**
- * Updates Analytics when opt out preference is changed.
- *
- * <p>{@link OnSharedPreferenceChangeListener} is used so the {@code analytics} object is
- * updated even if the preference are modified directly and not by
- * {@link OptOutPreferenceHelper}.
- */
- public static final class OptOutChangeListener implements OnSharedPreferenceChangeListener {
- private final Analytics mAnalytics;
- private final boolean mDefaultValue;
-
- private OptOutChangeListener(Analytics analytics, boolean defaultValue) {
- mAnalytics = analytics;
- mDefaultValue = defaultValue;
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- switch (key) {
- case ANALYTICS_OPT_OUT_KEY:
- mAnalytics.setAppOptOut(
- sharedPreferences.getBoolean(ANALYTICS_OPT_OUT_KEY, mDefaultValue));
- break;
- default:
- }
- }
- }
-}
diff --git a/src/com/android/tv/analytics/SendChannelStatusRunnable.java b/src/com/android/tv/analytics/SendChannelStatusRunnable.java
new file mode 100644
index 00000000..b5b5805c
--- /dev/null
+++ b/src/com/android/tv/analytics/SendChannelStatusRunnable.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.analytics;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.MainThread;
+
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.util.RecurringRunner;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Periodically sends analytics data with the channel count.
+ *
+ * <p>
+ * <p>This should only be started from a user activity
+ * like {@link com.android.tv.MainActivity}.
+ */
+@MainThread
+public class SendChannelStatusRunnable implements Runnable {
+ private static final long SEND_CHANNEL_STATUS_INTERVAL_MS = TimeUnit.DAYS.toMillis(1);
+
+ public static RecurringRunner startChannelStatusRecurringRunner(Context context,
+ Tracker tracker, ChannelDataManager channelDataManager) {
+
+ final SendChannelStatusRunnable sendChannelStatusRunnable = new SendChannelStatusRunnable(
+ channelDataManager, tracker);
+
+ Runnable onStopRunnable = new Runnable() {
+ @Override
+ public void run() {
+ sendChannelStatusRunnable.setDbLoadListener(null);
+ }
+ };
+ final RecurringRunner recurringRunner = new RecurringRunner(context,
+ SEND_CHANNEL_STATUS_INTERVAL_MS, sendChannelStatusRunnable, onStopRunnable);
+
+ if (channelDataManager.isDbLoadFinished()) {
+ sendChannelStatusRunnable.setDbLoadListener(null);
+ recurringRunner.start();
+ } else {
+ //Start the recurring runnable after the channel DB is finished loading.
+ sendChannelStatusRunnable.setDbLoadListener(new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ // This is called inside an iterator of Listeners so the remove step is done
+ // via a post on the main thread
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ sendChannelStatusRunnable.setDbLoadListener(null);
+ }
+ });
+ recurringRunner.start();
+ }
+
+ @Override
+ public void onChannelListUpdated() { }
+
+ @Override
+ public void onChannelBrowsableChanged() { }
+ });
+ }
+ return recurringRunner;
+ }
+
+ private final ChannelDataManager mChannelDataManager;
+ private final Tracker mTracker;
+ private ChannelDataManager.Listener mListener;
+
+ private SendChannelStatusRunnable(ChannelDataManager channelDataManager, Tracker tracker) {
+ mChannelDataManager = channelDataManager;
+ mTracker = tracker;
+ }
+
+ @Override
+ public void run() {
+ int browsableChannelCount = 0;
+ List<Channel> channelList = mChannelDataManager.getChannelList();
+ for (Channel channel : channelList) {
+ if (channel.isBrowsable()) {
+ ++browsableChannelCount;
+ }
+ }
+ mTracker.sendChannelCount(browsableChannelCount, channelList.size());
+ }
+
+ private void setDbLoadListener(ChannelDataManager.Listener listener) {
+ if (mListener != null) {
+ mChannelDataManager.removeListener(mListener);
+ }
+ mListener = listener;
+ if (listener != null) {
+ mChannelDataManager.addListener(listener);
+ }
+ }
+}
diff --git a/src/com/android/tv/analytics/StubAnalytics.java b/src/com/android/tv/analytics/StubAnalytics.java
index ae4cdafa..99c10d94 100644
--- a/src/com/android/tv/analytics/StubAnalytics.java
+++ b/src/com/android/tv/analytics/StubAnalytics.java
@@ -28,7 +28,7 @@ public final class StubAnalytics implements Analytics {
}
private final Tracker mTracker = new StubTracker();
- private boolean mOptOut = OptOutPreferenceHelper.ANALYTICS_OPT_OUT_DEFAULT_VALUE;
+ private boolean mOptOut = true;
private StubAnalytics(Context context) {
}
diff --git a/src/com/android/tv/data/Channel.java b/src/com/android/tv/data/Channel.java
index 7411d297..ba3c59ba 100644
--- a/src/com/android/tv/data/Channel.java
+++ b/src/com/android/tv/data/Channel.java
@@ -16,11 +16,11 @@
package com.android.tv.data;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.net.Uri;
@@ -31,6 +31,7 @@ import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.common.TvCommonConstants;
import com.android.tv.dvr.provider.DvrContract;
import com.android.tv.util.ImageLoader;
@@ -38,8 +39,6 @@ import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -90,6 +89,7 @@ public final class Channel {
};
// Additional fields added in MNC.
+ @SuppressLint("InlinedApi")
private static final String[] PROJECTION_ADDED_IN_MNC = {
// Columns should match what is read in Channel.fromCursor()
TvContract.Channels.COLUMN_APP_LINK_TEXT,
@@ -102,12 +102,8 @@ public final class Channel {
public static final String[] PROJECTION = createProjection();
private static String[] createProjection() {
- if (Build.VERSION.SDK_INT >= 23) {
- ArrayList<String> temp = new ArrayList<>(
- PROJECTION_BASE.length + PROJECTION_ADDED_IN_MNC.length);
- temp.addAll(Arrays.asList(PROJECTION_BASE));
- temp.addAll(Arrays.asList(PROJECTION_ADDED_IN_MNC));
- return temp.toArray(new String[temp.size()]);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return CollectionUtils.concatAll(PROJECTION_BASE, PROJECTION_ADDED_IN_MNC);
} else {
return PROJECTION_BASE;
}
@@ -142,7 +138,7 @@ public final class Channel {
channel.mVideoFormat = Utils.intern(cursor.getString(index++));
channel.mBrowsable = cursor.getInt(index++) == 1;
channel.mLocked = cursor.getInt(index++) == 1;
- if (Build.VERSION.SDK_INT >= 23) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
channel.mAppLinkText = cursor.getString(index++);
channel.mAppLinkColor = cursor.getInt(index++);
channel.mAppLinkIconUri = cursor.getString(index++);
@@ -190,10 +186,6 @@ public final class Channel {
*/
private boolean mRecordable;
- public interface LoadImageCallback {
- void onLoadImageFinished(Channel channel, int type, Bitmap logo);
- }
-
private Channel() {
// Do nothing.
}
@@ -523,7 +515,6 @@ public final class Channel {
/**
* Prefetches the images for this channel.
*/
- @UiThread
public void prefetchImage(Context context, int type, int maxWidth, int maxHeight) {
String uriString = getImageUriString(type);
if (!TextUtils.isEmpty(uriString)) {
@@ -547,17 +538,9 @@ public final class Channel {
*/
@UiThread
public void loadBitmap(Context context, final int type, int maxWidth, int maxHeight,
- final LoadImageCallback callback) {
+ ImageLoader.ImageLoaderCallback callback) {
String uriString = getImageUriString(type);
- ImageLoader.loadBitmap(context, uriString, maxWidth, maxHeight,
- new ImageLoader.ImageLoaderCallback() {
- @Override
- public void onBitmapLoaded(Bitmap bitmap) {
- if (callback != null) {
- callback.onLoadImageFinished(Channel.this, type, bitmap);
- }
- }
- });
+ ImageLoader.loadBitmap(context, uriString, maxWidth, maxHeight, callback);
}
/**
diff --git a/src/com/android/tv/data/ChannelDataManager.java b/src/com/android/tv/data/ChannelDataManager.java
index 067f2583..82ac4b5a 100644
--- a/src/com/android/tv/data/ChannelDataManager.java
+++ b/src/com/android/tv/data/ChannelDataManager.java
@@ -28,17 +28,18 @@ import android.media.tv.TvInputManager.TvInputCallback;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.MutableInt;
-import com.android.tv.analytics.Tracker;
+import com.android.tv.common.CollectionUtils;
+import com.android.tv.common.SharedPreferencesUtils;
import com.android.tv.common.WeakHandler;
import com.android.tv.util.AsyncDbTask;
-import com.android.tv.util.CollectionUtils;
import com.android.tv.util.PermissionUtils;
-import com.android.tv.util.RecurringRunner;
+import com.android.tv.util.SoftPreconditions;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
@@ -49,7 +50,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
/**
* The class to manage channel data.
@@ -58,13 +58,12 @@ import java.util.concurrent.TimeUnit;
* This class is not thread-safe and under an assumption that its public methods are called in
* only the main thread.
*/
+@MainThread
public class ChannelDataManager {
private static final String TAG = "ChannelDataManager";
private static final boolean DEBUG = false;
private static final int MSG_UPDATE_CHANNELS = 1000;
- private static final long SEND_CHANNEL_STATUS_INTERVAL_MS = TimeUnit.DAYS.toMillis(1);
- private static final String SHARED_PREF_BROWSABLE = "browsable_shared_preference";
private final Context mContext;
private final TvInputManagerHelper mInputManager;
@@ -72,9 +71,6 @@ public class ChannelDataManager {
private boolean mDbLoadFinished;
private QueryAllChannelsTask mChannelsUpdateTask;
private final List<Runnable> mPostRunnablesAfterChannelUpdate = new ArrayList<>();
- // TODO: move ChannelDataManager to TvApplication to consistently run mRecurringRunner.
- private RecurringRunner mRecurringRunner;
- private final Tracker mTracker;
private final Set<Listener> mListeners = CollectionUtils.createSmallSet();
private final Map<Long, ChannelWrapper> mChannelWrapperMap = new HashMap<>();
@@ -104,9 +100,7 @@ public class ChannelDataManager {
}
if (channelAdded) {
Collections.sort(mChannels, mChannelComparator);
- for (Listener l : mListeners) {
- l.onChannelListUpdated();
- }
+ notifyChannelListUpdated();
}
}
@@ -129,9 +123,7 @@ public class ChannelDataManager {
}
}
Collections.sort(mChannels, mChannelComparator);
- for (Listener l : mListeners) {
- l.onChannelListUpdated();
- }
+ notifyChannelListUpdated();
for (ChannelWrapper channel : removedChannels) {
channel.notifyChannelRemoved();
}
@@ -139,13 +131,12 @@ public class ChannelDataManager {
}
};
- public ChannelDataManager(Context context, TvInputManagerHelper inputManager,
- Tracker tracker) {
- this(context, inputManager, tracker, context.getContentResolver());
+ public ChannelDataManager(Context context, TvInputManagerHelper inputManager) {
+ this(context, inputManager, context.getContentResolver());
}
@VisibleForTesting
- ChannelDataManager(Context context, TvInputManagerHelper inputManager, Tracker tracker,
+ ChannelDataManager(Context context, TvInputManagerHelper inputManager,
ContentResolver contentResolver) {
mContext = context;
mInputManager = inputManager;
@@ -162,12 +153,9 @@ public class ChannelDataManager {
}
}
};
- mTracker = tracker;
- mRecurringRunner = new RecurringRunner(mContext, SEND_CHANNEL_STATUS_INTERVAL_MS,
- new SendChannelStatusRunnable());
mStoreBrowsableInSharedPreferences = !PermissionUtils.hasAccessAllEpg(mContext);
- mBrowsableSharedPreferences = context.getSharedPreferences(SHARED_PREF_BROWSABLE,
- Context.MODE_PRIVATE);
+ mBrowsableSharedPreferences = context.getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_BROWSABLE, Context.MODE_PRIVATE);
}
@VisibleForTesting
@@ -186,8 +174,8 @@ public class ChannelDataManager {
// Should be called directly instead of posting MSG_UPDATE_CHANNELS message to the handler.
// If not, other DB tasks can be executed before channel loading.
handleUpdateChannels();
- mContentResolver.registerContentObserver(
- TvContract.Channels.CONTENT_URI, true, mChannelObserver);
+ mContentResolver.registerContentObserver(TvContract.Channels.CONTENT_URI, true,
+ mChannelObserver);
mInputManager.addCallback(mTvInputCallback);
}
@@ -202,7 +190,6 @@ public class ChannelDataManager {
}
mStarted = false;
mDbLoadFinished = false;
- mRecurringRunner.stop();
ChannelLogoFetcher.stopFetchingChannelLogos();
mInputManager.removeCallback(mTvInputCallback);
@@ -223,14 +210,22 @@ public class ChannelDataManager {
* Adds a {@link Listener}.
*/
public void addListener(Listener listener) {
- mListeners.add(listener);
+ if (DEBUG) Log.d(TAG, "addListener " + listener);
+ SoftPreconditions.checkNotNull(listener);
+ if (listener != null) {
+ mListeners.add(listener);
+ }
}
/**
* Removes a {@link Listener}.
*/
public void removeListener(Listener listener) {
- mListeners.remove(listener);
+ if (DEBUG) Log.d(TAG, "removeListener " + listener);
+ SoftPreconditions.checkNotNull(listener);
+ if (listener != null) {
+ mListeners.remove(listener);
+ }
}
/**
@@ -365,11 +360,26 @@ public class ChannelDataManager {
}
public void notifyChannelBrowsableChanged() {
- for (Listener l : mListeners) {
+ // Copy the original collection to allow the callee to modify the listeners.
+ for (Listener l : mListeners.toArray(new Listener[mListeners.size()])) {
l.onChannelBrowsableChanged();
}
}
+ private void notifyChannelListUpdated() {
+ // Copy the original collection to allow the callee to modify the listeners.
+ for (Listener l : mListeners.toArray(new Listener[mListeners.size()])) {
+ l.onChannelListUpdated();
+ }
+ }
+
+ private void notifyLoadFinished() {
+ // Copy the original collection to allow the callee to modify the listeners.
+ for (Listener l : mListeners.toArray(new Listener[mListeners.size()])) {
+ l.onLoadFinished();
+ }
+ }
+
/**
* Updates channels from DB. Once the update is done, {@code postRunnable} will
* be called.
@@ -652,14 +662,9 @@ public class ChannelDataManager {
if (!mDbLoadFinished) {
mDbLoadFinished = true;
- mRecurringRunner.start();
- for (Listener l : mListeners) {
- l.onLoadFinished();
- }
+ notifyLoadFinished();
} else if (channelAdded || channelUpdated || channelRemoved) {
- for (Listener l : mListeners) {
- l.onChannelListUpdated();
- }
+ notifyChannelListUpdated();
}
for (ChannelWrapper channelWrapper : removedChannelWrappers) {
channelWrapper.notifyChannelRemoved();
@@ -713,17 +718,4 @@ public class ChannelDataManager {
}
}
}
-
- private class SendChannelStatusRunnable implements Runnable {
- @Override
- public void run() {
- int browsableChannelCount = 0;
- for (Channel channel : mChannels) {
- if (channel.isBrowsable()) {
- ++browsableChannelCount;
- }
- }
- mTracker.sendChannelCount(browsableChannelCount, mChannels.size());
- }
- }
}
diff --git a/src/com/android/tv/data/GenreItems.java b/src/com/android/tv/data/GenreItems.java
index b12fd1aa..92e38809 100644
--- a/src/com/android/tv/data/GenreItems.java
+++ b/src/com/android/tv/data/GenreItems.java
@@ -16,10 +16,14 @@
package com.android.tv.data;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Context;
import android.media.tv.TvContract.Programs.Genres;
+import android.os.Build;
import com.android.tv.R;
+import com.android.tv.common.CollectionUtils;
public class GenreItems {
/**
@@ -27,7 +31,7 @@ public class GenreItems {
*/
public static final int ID_ALL_CHANNELS = 0;
- private static final String[] CANONICAL_GENRES = {
+ private static final String[] CANONICAL_GENRES_BASE = {
null, // All channels
Genres.FAMILY_KIDS,
Genres.SPORTS,
@@ -39,15 +43,30 @@ public class GenreItems {
Genres.EDUCATION,
Genres.ANIMAL_WILDLIFE,
Genres.NEWS,
- Genres.GAMING,
- Genres.ARTS,
- Genres.ENTERTAINMENT,
- Genres.LIFE_STYLE,
- Genres.MUSIC,
- Genres.PREMIER,
- Genres.TECH_SCIENCE
+ Genres.GAMING
};
+ @SuppressLint("InlinedApi")
+ private static final String[] CANONICAL_GENRES_ADDED_IN_L_MR1 = {
+ Genres.ARTS,
+ Genres.ENTERTAINMENT,
+ Genres.LIFE_STYLE,
+ Genres.MUSIC,
+ Genres.PREMIER,
+ Genres.TECH_SCIENCE
+ };
+
+ private static final String[] CANONICAL_GENRES = createGenres();
+
+ private static String[] createGenres() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
+ return CANONICAL_GENRES_BASE;
+ } else {
+ return CollectionUtils
+ .concatAll(CANONICAL_GENRES_BASE, CANONICAL_GENRES_ADDED_IN_L_MR1);
+ }
+ }
+
private GenreItems() { }
/**
diff --git a/src/com/android/tv/data/Program.java b/src/com/android/tv/data/Program.java
index a0a5c090..b9c54aac 100644
--- a/src/com/android/tv/data/Program.java
+++ b/src/com/android/tv/data/Program.java
@@ -18,7 +18,6 @@ package com.android.tv.data;
import android.content.Context;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.support.annotation.NonNull;
@@ -27,6 +26,8 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.tv.R;
+import com.android.tv.common.BuildConfig;
+import com.android.tv.common.TvContentRatingCache;
import com.android.tv.dvr.provider.DvrContract;
import com.android.tv.util.ImageLoader;
import com.android.tv.util.Utils;
@@ -87,7 +88,8 @@ public final class Program implements Comparable<Program> {
builder.setPosterArtUri(cursor.getString(index++));
builder.setThumbnailUri(cursor.getString(index++));
builder.setCanonicalGenres(cursor.getString(index++));
- builder.setContentRatings(Utils.stringToContentRatings(cursor.getString(index++)));
+ builder.setContentRatings(TvContentRatingCache.getInstance()
+ .getRatings(cursor.getString(index++)));
builder.setStartTimeUtcMillis(cursor.getLong(index++));
builder.setEndTimeUtcMillis(cursor.getLong(index++));
builder.setVideoWidth((int) cursor.getLong(index++));
@@ -128,10 +130,6 @@ public final class Program implements Comparable<Program> {
private boolean mRecordable;
private boolean mRecordingScheduled;
- public interface LoadPosterArtCallback {
- void onLoadPosterArtFinished(Program program, Bitmap posterArt);
- }
-
private Program() {
// Do nothing.
}
@@ -296,7 +294,8 @@ public final class Program implements Comparable<Program> {
.append(", endTimeUtcSec=").append(Utils.toTimeString(mEndTimeUtcMillis))
.append(", videoWidth=").append(mVideoWidth)
.append(", videoHeight=").append(mVideoHeight)
- .append(", contentRatings=").append(Utils.contentRatingsToString(mContentRatings))
+ .append(", contentRatings=")
+ .append(TvContentRatingCache.contentRatingsToString(mContentRatings))
.append(", posterArtUri=").append(mPosterArtUri)
.append(", thumbnailUri=").append(mThumbnailUri)
.append(", canonicalGenres=").append(Arrays.toString(mCanonicalGenreIds));
@@ -446,7 +445,6 @@ public final class Program implements Comparable<Program> {
/**
* Prefetches the program poster art.<p>
*/
- @UiThread
public void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight) {
if (mPosterArtUri == null) {
return;
@@ -461,21 +459,25 @@ public final class Program implements Comparable<Program> {
*/
@UiThread
public void loadPosterArt(Context context, int posterArtWidth, int posterArtHeight,
- final LoadPosterArtCallback callback) {
+ ImageLoader.ImageLoaderCallback callback) {
if (mPosterArtUri == null) {
return;
}
- ImageLoader.loadBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight,
- new ImageLoader.ImageLoaderCallback() {
- @Override
- public void onBitmapLoaded(Bitmap bitmap) {
- if (DEBUG) {
- Log.i(TAG, "Loaded poster art for " + Program.this + ": " + bitmap);
- }
- if (callback != null) {
- callback.onLoadPosterArtFinished(Program.this, bitmap);
- }
- }
- });
+ ImageLoader.loadBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
+ }
+
+ public static boolean isDuplicate(Program p1, Program p2) {
+ if (p1 == null || p2 == null) {
+ return false;
+ }
+ boolean isDuplicate = p1.getChannelId() == p2.getChannelId()
+ && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
+ && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
+ if (BuildConfig.ENG && isDuplicate) {
+ Log.w(TAG, "Duplicate programs detected! - \"" + p1.getTitle() + "\" and \""
+ + p2.getTitle() + "\"");
+ }
+ return isDuplicate;
}
+
}
diff --git a/src/com/android/tv/data/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index 3f527433..6c167238 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -26,16 +26,16 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.LruCache;
-import com.android.tv.BuildConfig;
+import com.android.tv.common.CollectionUtils;
+import com.android.tv.common.MemoryManageable;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.Clock;
-import com.android.tv.util.CollectionUtils;
-import com.android.tv.util.MemoryManageable;
import com.android.tv.util.MultiLongSparseArray;
import com.android.tv.util.SoftPreconditions;
import com.android.tv.util.Utils;
@@ -51,6 +51,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+@MainThread
public class ProgramDataManager implements MemoryManageable {
private static final String TAG = "ProgramDataManager";
private static final boolean DEBUG = false;
@@ -454,7 +455,7 @@ public class ProgramDataManager implements MemoryManageable {
return null;
}
Program program = Program.fromCursor(c);
- if (isDuplicateProgram(program, lastReadProgram)) {
+ if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
} else {
@@ -537,7 +538,7 @@ public class ProgramDataManager implements MemoryManageable {
return programs;
}
Program program = Program.fromCursor(c);
- if (isDuplicateProgram(program, lastReadProgram)) {
+ if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
} else {
@@ -712,20 +713,6 @@ public class ProgramDataManager implements MemoryManageable {
.setEndTimeUtcMillis(endTimeMs).build();
}
- private static boolean isDuplicateProgram(Program p1, Program p2) {
- if (p1 == null || p2 == null) {
- return false;
- }
- boolean isDuplicate = p1.getChannelId() == p2.getChannelId()
- && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
- && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
- if (BuildConfig.ENG && isDuplicate) {
- Log.w(TAG, "Duplicate programs detected! - \"" + p1.getTitle() + "\" and \""
- + p2.getTitle() + "\"");
- }
- return isDuplicate;
- }
-
@Override
public void performTrimMemory(int level) {
mChannelId2ProgramUpdatedListeners.clearEmptyCache();
diff --git a/src/com/android/tv/data/TvInputNewComparator.java b/src/com/android/tv/data/TvInputNewComparator.java
index 11993d00..acc3e38a 100644
--- a/src/com/android/tv/data/TvInputNewComparator.java
+++ b/src/com/android/tv/data/TvInputNewComparator.java
@@ -40,8 +40,18 @@ public class TvInputNewComparator implements Comparator<TvInputInfo> {
boolean lhsIsNewInput = mSetupUtils.isNewInput(lhs.getId());
boolean rhsIsNewInput = mSetupUtils.isNewInput(rhs.getId());
if (lhsIsNewInput != rhsIsNewInput) {
+ // New input first.
return lhsIsNewInput ? -1 : 1;
}
+ if (!lhsIsNewInput) {
+ // Checks only when the inputs are not new.
+ boolean lhsSetupDone = mSetupUtils.isSetupDone(lhs.getId());
+ boolean rhsSetupDone = mSetupUtils.isSetupDone(rhs.getId());
+ if (lhsSetupDone != rhsSetupDone) {
+ // An input which has not been setup comes first.
+ return lhsSetupDone ? 1 : -1;
+ }
+ }
return mInputManager.getDefaultTvInputInfoComparator().compare(lhs, rhs);
}
}
diff --git a/src/com/android/tv/data/WatchedHistoryManager.java b/src/com/android/tv/data/WatchedHistoryManager.java
index 13707ae6..cff8cd5c 100644
--- a/src/com/android/tv/data/WatchedHistoryManager.java
+++ b/src/com/android/tv/data/WatchedHistoryManager.java
@@ -10,6 +10,8 @@ import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
+import com.android.tv.common.SharedPreferencesUtils;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -30,7 +32,6 @@ public class WatchedHistoryManager {
private final boolean DEBUG = false;
private static final int MAX_HISTORY_SIZE = 10000;
- private static final String SHARED_PREF_WATCHED_HISTORY = "watched_history_shared_preference";
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);
@@ -108,7 +109,7 @@ public class WatchedHistoryManager {
@Override
protected Void doInBackground(Void... params) {
mSharedPreferences = mContext.getSharedPreferences(
- SHARED_PREF_WATCHED_HISTORY, Context.MODE_PRIVATE);
+ 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) {
diff --git a/src/com/android/tv/dialog/FullscreenDialogFragment.java b/src/com/android/tv/dialog/FullscreenDialogFragment.java
index 75539f51..eb84aaf9 100644
--- a/src/com/android/tv/dialog/FullscreenDialogFragment.java
+++ b/src/com/android/tv/dialog/FullscreenDialogFragment.java
@@ -32,25 +32,34 @@ import com.android.tv.R;
*/
public class FullscreenDialogFragment extends SafeDismissDialogFragment {
public static final String DIALOG_TAG = FullscreenDialogFragment.class.getSimpleName();
-
- private final int mViewLayoutResId;
- private final String mTrackerLabel;
- private DialogView mDialogView;
+ public static final String VIEW_LAYOUT_ID = "viewLayoutId";
+ public static final String TRACKER_LABEL = "trackerLabel";
/**
- * Constructor of FullscreenDialogFragment. View class of viewLayoutResId should
+ * Creates a FullscreenDialogFragment. View class of viewLayoutResId should
* implement {@link DialogView}.
*/
- public FullscreenDialogFragment(int viewLayoutResId, String trackerLabel) {
- mViewLayoutResId = viewLayoutResId;
- mTrackerLabel = trackerLabel;
+ public static FullscreenDialogFragment newInstance(int viewLayoutResId, String trackerLabel) {
+ FullscreenDialogFragment f = new FullscreenDialogFragment();
+ Bundle args = new Bundle();
+ args.putInt(VIEW_LAYOUT_ID, viewLayoutResId);
+ args.putString(TRACKER_LABEL, trackerLabel);
+ f.setArguments(args);
+ return f;
}
+ private int mViewLayoutResId;
+ private String mTrackerLabel;
+ private DialogView mDialogView;
+
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
FullscreenDialog dialog =
new FullscreenDialog(getActivity(), R.style.Theme_TV_dialog_Fullscreen);
LayoutInflater inflater = LayoutInflater.from(getActivity());
+ Bundle args = getArguments();
+ mViewLayoutResId = args.getInt(VIEW_LAYOUT_ID);
+ mTrackerLabel = args.getString(TRACKER_LABEL);
View v = inflater.inflate(mViewLayoutResId, null);
dialog.setContentView(v);
mDialogView = (DialogView) v;
diff --git a/src/com/android/tv/dvr/BaseDvrDataManager.java b/src/com/android/tv/dvr/BaseDvrDataManager.java
index 0ce5d787..a98b5fa0 100644
--- a/src/com/android/tv/dvr/BaseDvrDataManager.java
+++ b/src/com/android/tv/dvr/BaseDvrDataManager.java
@@ -17,10 +17,11 @@
package com.android.tv.dvr;
import android.content.Context;
+import android.support.annotation.MainThread;
import android.util.Log;
-import com.android.tv.Features;
-import com.android.tv.util.CollectionUtils;
+import com.android.tv.common.CollectionUtils;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.util.SoftPreconditions;
import java.util.Set;
@@ -28,6 +29,7 @@ import java.util.Set;
/**
* Base implementation of @{link DataManagerInternal}.
*/
+@MainThread
public abstract class BaseDvrDataManager implements WritableDvrDataManager {
private final static String TAG = "BaseDvrDataManager";
private final static boolean DEBUG = false;
@@ -35,7 +37,7 @@ public abstract class BaseDvrDataManager implements WritableDvrDataManager {
private final Set<DvrDataManager.Listener> mListeners = CollectionUtils.createSmallSet();
BaseDvrDataManager (Context context){
- SoftPreconditions.checkFeatureEnabled(context,Features.DVR, TAG);
+ SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG);
}
@Override
diff --git a/src/com/android/tv/dvr/DvrDataManager.java b/src/com/android/tv/dvr/DvrDataManager.java
index bed3ed80..4f8b0525 100644
--- a/src/com/android/tv/dvr/DvrDataManager.java
+++ b/src/com/android/tv/dvr/DvrDataManager.java
@@ -16,6 +16,8 @@
package com.android.tv.dvr;
+import android.support.annotation.MainThread;
+import android.support.annotation.Nullable;
import android.util.Range;
import java.util.List;
@@ -23,6 +25,7 @@ import java.util.List;
/**
* Read only data manager.
*/
+@MainThread
public interface DvrDataManager {
long NEXT_START_TIME_NOT_FOUND = -1;
@@ -82,6 +85,12 @@ public interface DvrDataManager {
*/
void removeListener(Listener listener);
+ /**
+ * Returns the recording with the given recordingId or null if is not found
+ */
+ @Nullable
+ Recording getRecording(long recordingId);
+
interface Listener {
void onRecordingAdded(Recording recording);
void onRecordingRemoved(Recording recording);
diff --git a/src/com/android/tv/dvr/DvrDataManagerImpl.java b/src/com/android/tv/dvr/DvrDataManagerImpl.java
index d1c590af..647d9bd7 100644
--- a/src/com/android/tv/dvr/DvrDataManagerImpl.java
+++ b/src/com/android/tv/dvr/DvrDataManagerImpl.java
@@ -17,23 +17,32 @@
package com.android.tv.dvr;
import android.content.Context;
+import android.support.annotation.MainThread;
+import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
+import android.util.Log;
import android.util.Range;
import com.android.tv.dvr.Recording.RecordingState;
+import com.android.tv.dvr.provider.AsyncDvrDbTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncDvrQueryTask;
+import com.android.tv.util.SoftPreconditions;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
/**
* DVR Data manager to handle recordings and schedules.
*/
+@MainThread
public class DvrDataManagerImpl extends BaseDvrDataManager {
+ private static final String TAG = "DvrDataManagerImpl";
+
private Context mContext;
private boolean mLoadFinished;
- private final List<Recording> mRecordings = new ArrayList<>();
+ private final HashMap<Long, Recording> mRecordings = new HashMap<>();
private AsyncDvrQueryTask mQueryTask;
public DvrDataManagerImpl(Context context) {
@@ -47,8 +56,9 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
protected void onPostExecute(List<Recording> result) {
mQueryTask = null;
mLoadFinished = true;
- mRecordings.addAll(result);
- Collections.sort(mRecordings, Recording.START_TIME_COMPARATOR);
+ for (Recording r : result) {
+ mRecordings.put(r.getId(), r);
+ }
}
};
mQueryTask.executeOnDbThread();
@@ -71,7 +81,10 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (!mLoadFinished) {
return Collections.emptyList();
}
- return Collections.unmodifiableList(mRecordings);
+ ArrayList<Recording> list = new ArrayList<>(mRecordings.size());
+ list.addAll(mRecordings.values());
+ Collections.sort(list, Recording.START_TIME_COMPARATOR);
+ return Collections.unmodifiableList(list);
}
@Override
@@ -91,7 +104,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
private List<Recording> getRecordingsWithState(@RecordingState int state) {
List<Recording> result = new ArrayList<>();
- for (Recording r : mRecordings) {
+ for (Recording r : mRecordings.values()) {
if (r.getState() == state) {
result.add(r);
}
@@ -107,7 +120,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
@Override
public long getNextScheduledStartTimeAfter(long startTime) {
- return getNextStartTimeAfter(mRecordings, startTime);
+ return getNextStartTimeAfter(getRecordings(), startTime);
}
@VisibleForTesting
@@ -129,7 +142,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
@Override
public List<Recording> getRecordingsThatOverlapWith(Range<Long> period) {
List<Recording> result = new ArrayList<>();
- for (Recording r : mRecordings) {
+ for (Recording r : mRecordings.values()) {
if (r.isOverLapping(period)) {
result.add(r);
}
@@ -137,18 +150,80 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
return result;
}
+ @Nullable
+ @Override
+ public Recording getRecording(long recordingId) {
+ if (mLoadFinished) {
+ return mRecordings.get(recordingId);
+ }
+ return null;
+ }
+
@Override
- public void addRecording(Recording recording) { }
+ public void addRecording(final Recording recording) {
+ new AsyncDvrDbTask.AsyncAddRecordingTask(mContext) {
+ @Override
+ protected void onPostExecute(List<Recording> recordings) {
+ super.onPostExecute(recordings);
+ SoftPreconditions.checkArgument(recordings.size() == 1);
+ for (Recording r : recordings) {
+ if (r.getId() != -1) {
+ mRecordings.put(r.getId(), r);
+ notifyRecordingAdded(r);
+ } else {
+ Log.w(TAG, "Error adding " + r);
+ }
+ }
+
+ }
+ }.executeOnDbThread(recording);
+ }
@Override
public void addSeasonRecording(SeasonRecording seasonRecording) { }
@Override
- public void removeRecording(Recording recording) { }
+ public void removeRecording(final Recording recording) {
+ new AsyncDvrDbTask.AsyncDeleteRecordingTask(mContext) {
+ @Override
+ protected void onPostExecute(List<Integer> counts) {
+ super.onPostExecute(counts);
+ SoftPreconditions.checkArgument(counts.size() == 1);
+ for (Integer c : counts) {
+ if (c == 1) {
+ mRecordings.remove(recording.getId());
+ //TODO change to notifyRecordingUpdated
+ notifyRecordingRemoved(recording);
+ } else {
+ Log.w(TAG, "Error removing " + recording);
+ }
+ }
+
+ }
+ }.executeOnDbThread(recording);
+ }
@Override
public void removeSeasonSchedule(SeasonRecording seasonSchedule) { }
@Override
- public void updateRecording(Recording r) { }
+ public void updateRecording(final Recording recording) {
+ new AsyncDvrDbTask.AsyncUpdateRecordingTask(mContext) {
+ @Override
+ protected void onPostExecute(List<Integer> counts) {
+ super.onPostExecute(counts);
+ SoftPreconditions.checkArgument(counts.size() == 1);
+ for (Integer c : counts) {
+ if (c == 1) {
+ mRecordings.put(recording.getId(), recording);
+ //TODO change to notifyRecordingUpdated
+ notifyRecordingStatusChanged(recording);
+ } else {
+ Log.w(TAG, "Error updating " + recording);
+ }
+ }
+
+ }
+ }.executeOnDbThread(recording);
+ }
}
diff --git a/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java b/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
index 5dbdaac3..8a19cb29 100644
--- a/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
+++ b/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
@@ -17,25 +17,33 @@
package com.android.tv.dvr;
import android.content.Context;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Range;
+import com.android.tv.util.SoftPreconditions;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
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.
*/
@VisibleForTesting // TODO(DVR): move to testing dir.
+@MainThread
public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
+ private final static String TAG = "DvrDataManagerInMemory";
+ private final AtomicLong mNextId = new AtomicLong(1);
private final Map<Long, Recording> mRecordings = new HashMap<>();
private List<SeasonRecording> mSeasonSchedule = new ArrayList<>();
- DvrDataManagerInMemoryImpl(Context context) {
+ public DvrDataManagerInMemoryImpl(Context context) {
super(context);
}
@@ -51,19 +59,17 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
@Override
public List<Recording> getFinishedRecordings() {
- //TODO filter
- return new ArrayList(mRecordings.values());
+ return getRecordingsWithState(Recording.STATE_RECORDING_FINISHED);
}
@Override
public List<Recording> getStartedRecordings() {
- return null;
+ return getRecordingsWithState(Recording.STATE_RECORDING_IN_PROGRESS);
}
@Override
public List<Recording> getScheduledRecordings() {
- //TODO filter
- return new ArrayList(mRecordings.values());
+ return getRecordingsWithState(Recording.STATE_RECORDING_NOT_STARTED);
}
@Override
@@ -101,8 +107,16 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
*/
@Override
public void addRecording(Recording recording) {
+ addRecordingInternal(recording);
+ }
+
+ public Recording addRecordingInternal(Recording recording) {
+ SoftPreconditions.checkState(recording.getId() == Recording.ID_NOT_SET, TAG,
+ "expected id of " + Recording.ID_NOT_SET + " but was " + recording);
+ recording = Recording.buildFrom(recording).setId(mNextId.incrementAndGet()).build();
mRecordings.put(recording.getId(), recording);
notifyRecordingAdded(recording);
+ return recording;
}
@Override
@@ -133,7 +147,19 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
}
@Nullable
+ @Override
public Recording getRecording(long id) {
return mRecordings.get(id);
}
+
+ @NonNull
+ private List<Recording> getRecordingsWithState(int state) {
+ ArrayList<Recording> result = new ArrayList<>();
+ for (Recording r : mRecordings.values()) {
+ if(r.getState() == state){
+ result.add(r);
+ }
+ }
+ return result;
+ }
}
diff --git a/src/com/android/tv/dvr/DvrManager.java b/src/com/android/tv/dvr/DvrManager.java
index 35b367ba..c62c564b 100644
--- a/src/com/android/tv/dvr/DvrManager.java
+++ b/src/com/android/tv/dvr/DvrManager.java
@@ -17,43 +17,58 @@
package com.android.tv.dvr;
import android.content.Context;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
import android.util.Log;
+import android.util.Range;
import com.android.tv.ApplicationSingletons;
-import com.android.tv.Features;
import com.android.tv.TvApplication;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.recording.RecordingCapability;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
import com.android.tv.util.SoftPreconditions;
import com.android.tv.util.Utils;
+import java.util.Collections;
import java.util.List;
/**
* DVR manager class to add and remove recordings. UI can modify recording list through this class,
* instead of modifying them directly through {@link DvrDataManager}.
*/
+@MainThread
public class DvrManager {
private final static String TAG = "DvrManager";
private final WritableDvrDataManager mDataManager;
private final ChannelDataManager mChannelDataManager;
+ private final DvrSessionManager mDvrSessionManager;
public DvrManager(Context context) {
- SoftPreconditions.checkFeatureEnabled(context, Features.DVR, TAG);
+ SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG);
ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
mDataManager = (WritableDvrDataManager) appSingletons.getDvrDataManager();
mChannelDataManager = appSingletons.getChannelDataManager();
+ mDvrSessionManager = appSingletons.getDvrSessionManger();
}
/**
- * Adds a recording schedule for {@code program}.
+ * Schedules a recording for {@code program} instead of the list of recording that conflict.
+ * @param program the program to record
+ * @param recordingsToOverride the possible empty list of recordings that will not be recorded
*/
- public void addSchedule(Program program) {
- Log.i(TAG, "Adding scheduled recording of " + program);
- //TODO: handle error cases
+ public void addSchedule(Program program, List<Recording> recordingsToOverride) {
+ Log.i(TAG,
+ "Adding scheduled recording of " + program + " instead of " + recordingsToOverride);
+ Collections.sort(recordingsToOverride, Recording.PRIORITY_COMPARATOR);
Channel c = mChannelDataManager.getChannel(program.getChannelId());
- Recording r = Recording.builder(c, program).build();
+ long priority = recordingsToOverride.isEmpty() ? Long.MAX_VALUE
+ : recordingsToOverride.get(0).getPriority() - 1;
+ Recording r = Recording.builder(c, program)
+ .setPriority(priority)
+ .build();
mDataManager.addRecording(r);
}
@@ -81,16 +96,40 @@ public class DvrManager {
*/
public void removeRecording(Recording recording) {
Log.i(TAG, "Removing " + recording);
+ // TODO(DVR): ask the TIS to delete the recording and respond to the result.
mDataManager.removeRecording(recording);
}
/**
- * Checks whether {@code program} can be recorded without any conflict. If there is any
- * conflict, {@code outConflictRecordings} will be filled.
+ * Returns priority ordered list of all scheduled recording that will not be recorded if
+ * this program is.
+ *
+ * <p>Any empty list means there is no conflicts. If there is conflict the program must be
+ * scheduled to record with a Priority lower than the first Recording in the list returned.
*/
- public boolean canAddSchedule(Program program, List<Recording> outConflictRecordings) {
- // TODO: implement
- return true;
+ public List<Recording> getScheduledRecordingsThatConflict(Program program) {
+ //TODO(DVR): move to scheduler.
+ //TODO(DVR): deal with more than one DvrInputService
+ List<Recording> overLap = mDataManager.getRecordingsThatOverlapWith(getPeriod(program));
+ if (!overLap.isEmpty()) {
+ // TODO(DVR): ignore shows that already won't record.
+ Channel channel = mChannelDataManager.getChannel(program.getChannelId());
+ if (channel != null) {
+ RecordingCapability recordingCapability = mDvrSessionManager
+ .getRecordingCapability(channel.getInputId());
+ int remove = Math.max(0, recordingCapability.maxConcurrentTunedSessions - 1);
+ if (remove >= overLap.size()) {
+ return Collections.EMPTY_LIST;
+ }
+ overLap = overLap.subList(remove, overLap.size() - 1);
+ }
+ }
+ return overLap;
+ }
+
+ @NonNull
+ private static Range getPeriod(Program program) {
+ return new Range(program.getStartTimeUtcMillis(), program.getEndTimeUtcMillis());
}
/**
@@ -101,4 +140,13 @@ public class DvrManager {
// TODO: implement
return true;
}
+
+ /**
+ * Returns true is the inputId supports recording.
+ */
+ public boolean canRecord(String inputId) {
+ RecordingCapability recordingCapability = mDvrSessionManager
+ .getRecordingCapability(inputId);
+ return recordingCapability != null && recordingCapability.maxConcurrentTunedSessions > 0;
+ }
}
diff --git a/src/com/android/tv/dvr/DvrPlayActivity.java b/src/com/android/tv/dvr/DvrPlayActivity.java
new file mode 100644
index 00000000..872e05bd
--- /dev/null
+++ b/src/com/android/tv/dvr/DvrPlayActivity.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+
+/**
+ * Simple Activity to play a {@link Recording}.
+ */
+public class DvrPlayActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dvr_play);
+
+ DvrDataManager dvrDataManager = TvApplication.getSingletons(this).getDvrDataManager();
+ // TODO(DVR) handle errors.
+ long recordingId = getIntent().getLongExtra(Recording.RECORDING_ID_EXTRA, 0);
+ Recording recording = dvrDataManager.getRecording(recordingId);
+ TextView textView = (TextView) findViewById(R.id.placeHolderText);
+ if (recording != null) {
+ textView.setText(recording.toString());
+ } else {
+ textView.setText(R.string.ut_result_not_found_title); // TODO(DVR) update error text
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/DvrRecordingService.java b/src/com/android/tv/dvr/DvrRecordingService.java
index d7a044ab..d0e86d50 100644
--- a/src/com/android/tv/dvr/DvrRecordingService.java
+++ b/src/com/android/tv/dvr/DvrRecordingService.java
@@ -21,14 +21,15 @@ import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
+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.Features;
import com.android.tv.TvApplication;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.util.Clock;
import com.android.tv.util.SoftPreconditions;
@@ -49,12 +50,13 @@ import com.android.tv.util.SoftPreconditions;
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 DvrSessionManager mSessionManager;
private WritableDvrDataManager mDataManager;
/**
@@ -71,20 +73,24 @@ public class DvrRecordingService extends Service {
private final IBinder mBinder = new SchedulerBinder();
private Scheduler mScheduler;
+ private HandlerThread mHandlerThread;
@Override
public void onCreate() {
if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate();
- SoftPreconditions.checkFeatureEnabled(this, Features.DVR, TAG);
+ SoftPreconditions.checkFeatureEnabled(this, CommonFeatures.DVR, TAG);
ApplicationSingletons singletons = TvApplication.getSingletons(this);
mDataManager = (WritableDvrDataManager) singletons.getDvrDataManager();
- mSessionManager = singletons.getDvrSessionManger();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// mScheduler may have been set for testing.
if (mScheduler == null) {
- mScheduler = new Scheduler(mSessionManager, mDataManager, this, Clock.SYSTEM,
+ DvrSessionManager sessionManager = singletons.getDvrSessionManger();
+ mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+ mHandlerThread.start();
+ mScheduler = new Scheduler(mHandlerThread.getLooper(), sessionManager, mDataManager,
+ this, Clock.SYSTEM,
alarmManager);
}
mDataManager.addListener(mScheduler);
@@ -102,6 +108,10 @@ public class DvrRecordingService extends Service {
if (DEBUG) Log.d(TAG, "onDestroy");
mDataManager.removeListener(mScheduler);
mScheduler = null;
+ if (mHandlerThread != null) {
+ mHandlerThread.quit();
+ mHandlerThread = null;
+ }
super.onDestroy();
}
diff --git a/src/com/android/tv/dvr/DvrSessionManager.java b/src/com/android/tv/dvr/DvrSessionManager.java
index 815dfeb1..553001e2 100644
--- a/src/com/android/tv/dvr/DvrSessionManager.java
+++ b/src/com/android/tv/dvr/DvrSessionManager.java
@@ -16,12 +16,18 @@
package com.android.tv.dvr;
+import android.content.ComponentName;
import android.content.Context;
+import android.media.tv.TvContract;
+import android.support.annotation.Nullable;
+import android.support.v4.util.ArrayMap;
-import com.android.tv.Features;
-import com.android.tv.common.dvr.DvrSessionClient;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.recording.RecordingCapability;
+import com.android.tv.common.recording.TvRecording;
import com.android.tv.data.Channel;
import com.android.tv.util.SoftPreconditions;
+import com.android.usbtuner.tvinput.UsbTunerTvInputService;
/**
* Manages Dvr Sessions.
@@ -33,19 +39,55 @@ import com.android.tv.util.SoftPreconditions;
*/
public class DvrSessionManager {
private final static String TAG = "DvrSessionManager";
+ private final Context mContext;
+ private TvRecording.TvRecordingClient mRecordingClient;
+ private ArrayMap<String, RecordingCapability> mCapabilityMap = new ArrayMap<>();
public DvrSessionManager(Context context) {
- SoftPreconditions.checkFeatureEnabled(context, Features.DVR, TAG);
+ SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG);
+ mContext = context.getApplicationContext();
+ // TODO(DVR): get a session to all clients, for now just get USB a TestInput
+ final String inputId = TvContract
+ .buildInputId(new ComponentName(context, UsbTunerTvInputService.class));
+ mRecordingClient = acquireDvrSession(inputId, null);
+ mRecordingClient.connect(inputId, new TvRecording.ClientCallback() {
+ @Override
+ public void onCapabilityReceived(RecordingCapability capability) {
+ mCapabilityMap.put(inputId, capability);
+ mRecordingClient.release();
+ mRecordingClient = null;
+ }
+ });
+ if (CommonFeatures.DVR.isEnabled(context)) { // STOPSHIP(DVR)
+ String testInputId = "com.android.tv.testinput/.TestTvInputService";
+ mCapabilityMap.put(testInputId,
+ RecordingCapability.builder()
+ .setInputId(testInputId)
+ .setMaxConcurrentPlayingSessions(2)
+ .setMaxConcurrentTunedSessions(2)
+ .setMaxConcurrentSessionsOfAllTypes(3)
+ .build());
+
+ }
}
- public DvrSessionClient acquireDvrSession(String inputId, Channel channel) {
- return null;
+ public TvRecording.TvRecordingClient acquireDvrSession(String inputId, Channel channel) {
+ // TODO(DVR): use input and channel or change API
+ TvRecording.TvRecordingClient sessionClient = new TvRecording.TvRecordingClient(mContext);
+ return sessionClient;
}
public boolean canAcquireDvrSession(String inputId, Channel channel) {
- return false;
+ // TODO(DVR): implement
+ return true;
+ }
+
+ public void releaseDvrSession(TvRecording.TvRecordingClient session) {
+ session.release();
}
- public void releaseDvrSession(DvrSessionClient session) {
+ @Nullable
+ public RecordingCapability getRecordingCapability(String inputId) {
+ return mCapabilityMap.get(inputId);
}
}
diff --git a/src/com/android/tv/dvr/Recording.java b/src/com/android/tv/dvr/Recording.java
index 9695d268..9ecda4da 100644
--- a/src/com/android/tv/dvr/Recording.java
+++ b/src/com/android/tv/dvr/Recording.java
@@ -44,6 +44,11 @@ import java.util.List;
public final class Recording {
private static final String TAG = "Recording";
+ public static final String RECORDING_ID_EXTRA = "extra.dvr.recording.id";
+ public static final String PARAM_INPUT_ID = "input_id";
+
+ public static final long ID_NOT_SET = -1;
+
public static final Comparator<Recording> START_TIME_COMPARATOR = new Comparator<Recording>() {
@Override
public int compare(Recording lhs, Recording rhs) {
@@ -51,6 +56,29 @@ public final class Recording {
}
};
+ public static final Comparator<Recording> PRIORITY_COMPARATOR = new Comparator<Recording>() {
+ @Override
+ public int compare(Recording lhs, Recording rhs) {
+ int value = Long.compare(lhs.mPriority, rhs.mPriority);
+ if (value == 0) {
+ value = Long.compare(lhs.mId, rhs.mId);
+ }
+ return value;
+ }
+ };
+
+ public static final Comparator<Recording> START_TIME_THEN_PRIORITY_COMPARATOR
+ = new Comparator<Recording>() {
+ @Override
+ public int compare(Recording lhs, Recording rhs) {
+ int value = START_TIME_COMPARATOR.compare(lhs, rhs);
+ if (value == 0) {
+ value = PRIORITY_COMPARATOR.compare(lhs, rhs);
+ }
+ return value;
+ }
+ };
+
public static Builder builder(Channel c, Program p) {
return new Builder()
.setChannel(c)
@@ -64,11 +92,13 @@ public final class Recording {
return new Builder()
.setChannel(c)
.setStartTime(startTime)
- .setEndTime(endTime);
+ .setEndTime(endTime)
+ .setType(TYPE_TIMED);
}
public static final class Builder {
- private long mId;
+ private long mId = ID_NOT_SET;
+ private long mPriority = Long.MAX_VALUE;
private Uri mUri;
private Channel mChannel;
private List<Program> mPrograms;
@@ -86,7 +116,12 @@ public final class Recording {
return this;
}
- public Builder setUri(Uri uri) {
+ public Builder setPriority(long priority) {
+ mPriority = priority;
+ return this;
+ }
+
+ private Builder setUri(Uri uri) {
mUri = uri;
return this;
}
@@ -132,7 +167,8 @@ public final class Recording {
}
public Recording build() {
- return new Recording(mId, mUri, mChannel, mPrograms, mType, mStartTime, mEndTime, mSize,
+ return new Recording(mId, mPriority, mUri, mChannel, mPrograms, mType, mStartTime,
+ mEndTime, mSize,
mState, mParentSeasonRecording);
}
}
@@ -150,6 +186,7 @@ public final class Recording {
.setSize(orig.mMediaSize)
.setStartTime(orig.mStartTimeMs)
.setState(orig.mState)
+ .setType(orig.mType)
.setUri(orig.mUri);
}
@@ -169,11 +206,11 @@ public final class Recording {
/**
* Record with given time range.
*/
- private static final int TYPE_TIMED = 1;
+ static final int TYPE_TIMED = 1;
/**
* Record with a given program.
*/
- private static final int TYPE_PROGRAM = 2;
+ static final int TYPE_PROGRAM = 2;
@RecordingType private final int mType;
@@ -183,6 +220,7 @@ public final class Recording {
public static final String[] PROJECTION = {
// Columns must match what is read in Recording.fromCursor()
DvrContract.Recordings._ID,
+ DvrContract.Recordings.COLUMN_PRIORITY,
DvrContract.Recordings.COLUMN_TYPE,
DvrContract.Recordings.COLUMN_URI,
DvrContract.Recordings.COLUMN_CHANNEL_ID,
@@ -198,6 +236,14 @@ public final class Recording {
private final long mId;
/**
+ * The priority of this recording.
+ *
+ * <p> The lowest number is recorded first. If there is a tie in priority then the lower id
+ * wins.
+ */
+ private final long mPriority;
+
+ /**
* The {@link Uri} is used as its identifier with the TIS.
* Note: If the state is STATE_RECORDING_NOT_STARTED, this might be {@code null}.
*/
@@ -224,11 +270,19 @@ public final class Recording {
private final SeasonRecording mParentSeasonRecording;
-
- private Recording(long id, Uri uri, Channel channel, List<Program> programs,
+ private Recording(long id, long priority, Uri uri, Channel channel, List<Program> programs,
@RecordingType int type, long startTime, long endTime, long size,
@RecordingState int state, SeasonRecording parentSeasonRecording) {
mId = id;
+ mPriority = priority;
+ if (uri == null && id >= 0 && channel != null) {
+ uri = new Uri.Builder()
+ .scheme("record")
+ .authority("com.android.tv")
+ .appendPath(Long.toString(mId))
+ .appendQueryParameter(PARAM_INPUT_ID, channel.getInputId())
+ .build();
+ }
mUri = uri;
mChannel = channel;
mPrograms = programs == null ? Collections.EMPTY_LIST : new ArrayList<>(programs);
@@ -317,6 +371,10 @@ public final class Recording {
return mId;
}
+ public long getPriority() {
+ return mPriority;
+ }
+
/**
* Creates {@link Recording} object from the given {@link Cursor}.
*/
@@ -324,6 +382,7 @@ public final class Recording {
Builder builder = new Builder();
int index = -1;
builder.setId(c.getLong(++index));
+ builder.setPriority(c.getLong(++index));
builder.setType(recordingType(c.getString(++index)));
String uri = c.getString(++index);
if (uri != null) {
@@ -405,6 +464,7 @@ public final class Recording {
+ "(startTime=" + Utils.toIsoDateTimeString(mStartTimeMs)
+ ",endTime=" + Utils.toIsoDateTimeString(mEndTimeMs)
+ ",state=" + mState
+ + ",priority=" + mPriority
+ ")";
}
}
diff --git a/src/com/android/tv/dvr/RecordingTask.java b/src/com/android/tv/dvr/RecordingTask.java
index e4da5f19..3bed5e77 100644
--- a/src/com/android/tv/dvr/RecordingTask.java
+++ b/src/com/android/tv/dvr/RecordingTask.java
@@ -17,30 +17,65 @@
package com.android.tv.dvr;
import android.net.Uri;
+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 com.android.tv.common.dvr.DvrSessionClient;
+import com.android.tv.common.recording.TvRecording;
import com.android.tv.data.Channel;
import com.android.tv.util.Clock;
+import com.android.tv.util.SoftPreconditions;
+import com.android.tv.util.Utils;
import java.util.concurrent.TimeUnit;
/**
- * A runnable that actually starts on stop a recording at the right time.
+ * 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.
*/
-class RecordingTask extends DvrSessionClient.Callback implements Runnable {
+@WorkerThread
+class RecordingTask extends TvRecording.ClientCallback implements Handler.Callback {
private static final String TAG = "RecordingTask";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true; //STOPSHIP(DVR)
+
+ @VisibleForTesting
+ static final int MESSAGE_INIT = 1;
+ @VisibleForTesting
+ static final int MESSAGE_START_RECORDING = 2;
+ @VisibleForTesting
+ static final int MESSAGE_STOP_RECORDING = 3;
@VisibleForTesting
static long MS_BEFORE_START = TimeUnit.SECONDS.toMillis(5);
@VisibleForTesting
static long MS_AFTER_END = TimeUnit.SECONDS.toMillis(5);
+
+ //STOPSHIP(DVR) don't use enums.
+ @VisibleForTesting
+ enum State {
+ NOT_STARTED,
+ SESSION_ACQUIRED,
+ CONNECTION_PENDING,
+ CONNECTED,
+ RECORDING_START_REQUESTED,
+ RECORDING_STARTED,
+ ERROR,
+ RELEASED,
+ }
private final DvrSessionManager mSessionManager;
+
private final WritableDvrDataManager mDataManager;
- private final Clock mClock;
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+ private TvRecording.TvRecordingClient mSession;
+ private Handler mHandler;
private Recording mRecording;
+ private State mState = State.NOT_STARTED;
+ private final Clock mClock;
RecordingTask(Recording recording, DvrSessionManager sessionManager,
WritableDvrDataManager dataManager, Clock clock) {
@@ -48,68 +83,186 @@ class RecordingTask extends DvrSessionClient.Callback implements Runnable {
mSessionManager = sessionManager;
mDataManager = dataManager;
mClock = clock;
+
if (DEBUG) Log.d(TAG, "created recording task " + mRecording);
}
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "running recording task " + mRecording);
+ public void setHandler(Handler handler) {
+ mHandler = handler;
+ }
- //TODO check recording preconditions
- Channel channel = mRecording.getChannel();
- String inputId = channel.getInputId();
- DvrSessionClient session;
- if (mSessionManager.canAcquireDvrSession(inputId, channel)) {
- session = mSessionManager.acquireDvrSession(inputId, channel);
- } else {
- Log.w(TAG, "Unable to acquire a session for " + mRecording);
- updateRecordingState(Recording.STATE_RECORDING_FAILED);
- return;
- }
+ @Override
+ public boolean handleMessage(Message msg) {
+ if (DEBUG) Log.d(TAG, "handleMessage " + msg);
+ SoftPreconditions
+ .checkState(msg.what == Scheduler.HandlerWrapper.MESSAGE_REMOVE || mHandler != null,
+ TAG, "Null handler trying to handle " + msg);
try {
- session.connect(inputId, this);
-
- // TODO: use handler instead of sleep to respond to events and interrupts
- mClock.sleep(Math.max(0,
- (mRecording.getStartTimeMs() - mClock.currentTimeMillis()) - MS_BEFORE_START));
- if (DEBUG) Log.d(TAG, "Start recording " + mRecording);
-
- session.startRecord(channel.getUri(), getIdAsMediaUri(mRecording));
-
- mClock.sleep(Math.max(0,
- (mRecording.getEndTimeMs() - mClock.currentTimeMillis()) + MS_AFTER_END));
- session.stopRecord();
- if (DEBUG) Log.d(TAG, "Finished recording " + mRecording);
- } finally {
- //TODO Don't release until after onRecordStopped etc.
- mSessionManager.releaseDvrSession(session);
+ switch (msg.what) {
+ case MESSAGE_INIT:
+ handleInit();
+ break;
+ case MESSAGE_START_RECORDING:
+ handleStartRecording();
+ break;
+ case MESSAGE_STOP_RECORDING:
+ handleStopRecording();
+ break;
+ case Scheduler.HandlerWrapper.MESSAGE_REMOVE:
+ // Clear the handler
+ mHandler = null;
+ release();
+ return false;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "unexpected message type " + msg);
+ }
+ return true;
+ } catch (Exception e) {
+ Log.w(TAG, "Error processing message " + msg + " for " + mRecording, e);
+ failAndQuit();
}
+ return false;
+ }
+
+ @Override
+ public void onConnected() {
+ if (DEBUG) Log.d(TAG, "onConnected");
+ super.onConnected();
+ mState = State.CONNECTED;
+ }
+
+ @Override
+ public void onDisconnected() {
+ if (DEBUG) Log.d(TAG, "onDisconnected");
+ super.onDisconnected();
+ //Do nothing
+ }
+
+ @Override
+ public void onRecordDeleted(Uri mediaUri) {
+ if (DEBUG) Log.d(TAG, "onRecordDeleted " + mediaUri);
+ super.onRecordDeleted(mediaUri);
+ SoftPreconditions.checkState(false, TAG, "unexpected onRecordDeleted");
+
+ }
+
+ @Override
+ public void onRecordDeleteFailed(Uri mediaUri, int reason) {
+ if (DEBUG) Log.d(TAG, "onRecordDeleteFailed " + mediaUri + ", " + reason);
+ super.onRecordDeleteFailed(mediaUri, reason);
+ SoftPreconditions.checkState(false, TAG, "unexpected onRecordDeleteFailed");
}
@Override
public void onRecordStarted(Uri mediaUri) {
if (DEBUG) Log.d(TAG, "onRecordStarted " + mediaUri);
super.onRecordStarted(mediaUri);
+ mState = State.RECORDING_STARTED;
updateRecording(Recording.buildFrom(mRecording)
.setState(Recording.STATE_RECORDING_IN_PROGRESS)
- .setUri(mediaUri)
.build());
}
@Override
- public void onRecordStopped(Uri mediaUri, @DvrSessionClient.RecordStopReason int reason) {
+ public void onRecordStopped(Uri mediaUri, @TvRecording.RecordStopReason int reason) {
if (DEBUG) Log.d(TAG, "onRecordStopped " + mediaUri + " reason " + reason);
super.onRecordStopped(mediaUri, reason);
-
- //TODO need a success reason.
- switch (reason){
+ // TODO(dvr) handle success
+ switch (reason) {
default:
updateRecording(Recording.buildFrom(mRecording)
.setState(Recording.STATE_RECORDING_FAILED)
.build());
- }
+ }
+ release();
+ sendRemove();
}
+ private void handleInit() {
+ //TODO check recording preconditions
+ Channel channel = mRecording.getChannel();
+ if (channel == null) {
+ Log.w(TAG, "Null channel for " + mRecording);
+ failAndQuit();
+ return;
+ }
+
+ String inputId = channel.getInputId();
+ if (mSessionManager.canAcquireDvrSession(inputId, channel)) {
+ mSession = mSessionManager.acquireDvrSession(inputId, channel);
+ mState = State.SESSION_ACQUIRED;
+ } else {
+ Log.w(TAG, "Unable to acquire a session for " + mRecording);
+ failAndQuit();
+ return;
+ }
+
+ mSession.connect(inputId, this);
+ mState = State.CONNECTION_PENDING;
+
+ if (mHandler == null || !sendEmptyMessageAtAbsoluteTime(MESSAGE_START_RECORDING,
+ mRecording.getStartTimeMs() - MS_BEFORE_START)) {
+ mState = State.ERROR;
+ return;
+ }
+ }
+
+ private void failAndQuit() {
+ updateRecordingState(Recording.STATE_RECORDING_FAILED);
+ mState = State.ERROR;
+ sendRemove();
+ }
+
+ private void sendRemove() {
+ if (mHandler != null) {
+ mHandler.sendEmptyMessage(Scheduler.HandlerWrapper.MESSAGE_REMOVE);
+ }
+ }
+
+ private void handleStartRecording() {
+ if (DEBUG)Log.d(TAG, "handleStartRecording " + mRecording);
+ // TODO(DVR) handle errors
+ Channel channel = mRecording.getChannel();
+ mSession.startRecord(channel.getUri(), getIdAsMediaUri(mRecording));
+ mState= State.RECORDING_START_REQUESTED;
+ if (mHandler == null || !sendEmptyMessageAtAbsoluteTime(MESSAGE_STOP_RECORDING,
+ mRecording.getEndTimeMs() + MS_AFTER_END)) {
+ mState = State.ERROR;
+ return;
+ }
+ }
+
+ private void handleStopRecording() {
+ if (DEBUG)Log.d(TAG, "handleStopRecording " + mRecording);
+ mSession.stopRecord();
+ // TODO: once we add an API to notify successful completion of recording,
+ // the following parts need to be moved to the listener implementation.
+ updateRecording(Recording.buildFrom(mRecording)
+ .setState(Recording.STATE_RECORDING_FINISHED).build());
+ sendRemove();
+ }
+
+ @VisibleForTesting
+ State getState() {
+ return mState;
+ }
+
+ private void release() {
+ if (mSession != null) {
+ mSession.release();
+ mSessionManager.releaseDvrSession(mSession);
+ }
+ }
+
+ 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(@Recording.RecordingState int state) {
updateRecording(Recording.buildFrom(mRecording).setState(state).build());
@@ -123,7 +276,12 @@ class RecordingTask extends DvrSessionClient.Callback implements Runnable {
private void updateRecording(Recording updatedRecording) {
if (DEBUG) Log.d(TAG, "updateRecording " + updatedRecording);
mRecording = updatedRecording;
- mDataManager.updateRecording(mRecording);
+ mMainThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDataManager.updateRecording(mRecording);
+ }
+ });
}
@Override
diff --git a/src/com/android/tv/dvr/Scheduler.java b/src/com/android/tv/dvr/Scheduler.java
index 0787adc3..8070f8a6 100644
--- a/src/com/android/tv/dvr/Scheduler.java
+++ b/src/com/android/tv/dvr/Scheduler.java
@@ -20,18 +20,17 @@ import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Range;
import com.android.tv.util.Clock;
-import com.android.tv.util.NamedThreadFactory;
import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
/**
@@ -42,44 +41,46 @@ public class Scheduler implements DvrDataManager.Listener {
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);
+
/**
- * Wraps a RecordingTask removing it from {@link #mPendingRecordings} when it is done.
+ * Wraps a {@link RecordingTask} removing it from {@link #mPendingRecordings} when it is done.
*/
- private final class TaskWrapper extends FutureTask<Void> {
+ public final class HandlerWrapper extends Handler {
+ public static final int MESSAGE_REMOVE = 999;
private final long mId;
- TaskWrapper(Recording recording) {
- super(new RecordingTask(recording, mSessionManager, mDataManager, mClock), null);
+ HandlerWrapper(Looper looper, Recording recording, RecordingTask recordingTask) {
+ super(looper, recordingTask);
mId = recording.getId();
}
@Override
- public void done() {
- if (DEBUG) Log.d(TAG, "done " + mId);
- mPendingRecordings.remove(mId);
- super.done();
+ 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);
+ super.handleMessage(msg);
}
}
+ private final LongSparseArray<HandlerWrapper> mPendingRecordings = new LongSparseArray<>();
+ private final Looper mLooper;
+ private final DvrSessionManager mSessionManager;
private final WritableDvrDataManager mDataManager;
private final Context mContext;
- private final DvrSessionManager mSessionManager;
- private PendingIntent mAlarmIntent;
-
- private static final NamedThreadFactory sNamedThreadFactory = new NamedThreadFactory(
- "DVR-scheduler");
- @VisibleForTesting final static long MS_TO_WAKE_BEFORE_START = TimeUnit.MINUTES.toMillis(1);
- private final static long SOON_DURATION_IN_MS = TimeUnit.MINUTES.toMillis(5);
-
- private final ExecutorService mExecutorService = Executors
- .newCachedThreadPool(sNamedThreadFactory);
- private final LongSparseArray<TaskWrapper> mPendingRecordings = new LongSparseArray<>();
private final Clock mClock;
private final AlarmManager mAlarmManager;
- public Scheduler(DvrSessionManager sessionManager, WritableDvrDataManager dataManager,
- Context context, Clock clock,
+ public Scheduler(Looper looper, DvrSessionManager sessionManager,
+ WritableDvrDataManager dataManager, Context context, Clock clock,
AlarmManager alarmManager) {
+ mLooper = looper;
mSessionManager = sessionManager;
mDataManager = dataManager;
mContext = context;
@@ -106,7 +107,6 @@ public class Scheduler implements DvrDataManager.Listener {
updateNextAlarm();
}
-
@Override
public void onRecordingAdded(Recording recording) {
if (DEBUG) Log.d(TAG, "added " + recording);
@@ -120,9 +120,9 @@ public class Scheduler implements DvrDataManager.Listener {
@Override
public void onRecordingRemoved(Recording recording) {
long id = recording.getId();
- TaskWrapper task = mPendingRecordings.get(id);
- if (task != null) {
- task.cancel(true);
+ HandlerWrapper wrapper = mPendingRecordings.get(id);
+ if (wrapper != null) {
+ wrapper.removeCallbacksAndMessages(null);
mPendingRecordings.remove(id);
} else {
updateNextAlarm();
@@ -134,12 +134,13 @@ public class Scheduler implements DvrDataManager.Listener {
//TODO(DVR): implement
}
-
private void scheduleRecordingSoon(Recording recording) {
- // TODO(DVR) test match in mPendingRecordings recordings.
- TaskWrapper task = new TaskWrapper(recording);
- mPendingRecordings.put(recording.getId(), task);
- mExecutorService.submit(task);
+ RecordingTask recordingTask = new RecordingTask(recording, mSessionManager, mDataManager,
+ mClock);
+ HandlerWrapper handlerWrapper = new HandlerWrapper(mLooper, recording, recordingTask);
+ recordingTask.setHandler(handlerWrapper);
+ mPendingRecordings.put(recording.getId(), handlerWrapper);
+ handlerWrapper.sendEmptyMessage(RecordingTask.MESSAGE_INIT);
}
private void updateNextAlarm() {
@@ -149,9 +150,9 @@ public class Scheduler implements DvrDataManager.Listener {
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);
- mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+ PendingIntent alarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
//This will cancel the previous alarm.
- mAlarmManager.set(AlarmManager.RTC_WAKEUP, wakeAt, mAlarmIntent);
+ mAlarmManager.set(AlarmManager.RTC_WAKEUP, wakeAt, alarmIntent);
} else {
if (DEBUG) Log.d(TAG, "No future recording, alarm not set");
}
diff --git a/src/com/android/tv/dvr/WritableDvrDataManager.java b/src/com/android/tv/dvr/WritableDvrDataManager.java
index d1ba702e..87809701 100644
--- a/src/com/android/tv/dvr/WritableDvrDataManager.java
+++ b/src/com/android/tv/dvr/WritableDvrDataManager.java
@@ -16,12 +16,15 @@
package com.android.tv.dvr;
+import android.support.annotation.MainThread;
+
/**
* Full data manager.
*
* <p>The following operations need to be synced with permanent storage. The following commands are
* for internal use only. Do not call them from UI directly.
*/
+@MainThread
interface WritableDvrDataManager extends DvrDataManager {
/**
* Add a new recording.
diff --git a/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java b/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
index 55748937..3fc6e4a9 100644
--- a/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
+++ b/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
@@ -19,6 +19,7 @@ package com.android.tv.dvr.provider;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
+import android.support.annotation.Nullable;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
@@ -69,6 +70,71 @@ public abstract class AsyncDvrDbTask<Params, Progress, Result>
executeOnExecutor(DB_EXECUTOR, params);
}
+ @Override
+ protected final Result doInBackground(Params... params) {
+ initializeDbHelper(mContext);
+ return doInDvrBackground(params);
+ }
+
+ /**
+ * Executes in the background after {@link #initializeDbHelper(Context)}
+ */
+ @Nullable
+ protected abstract Result doInDvrBackground(Params... params);
+
+ /**
+ * Inserts recordings returning the list of recordings with id set.
+ * The id will be -1 if there was an error.
+ */
+ public abstract static class AsyncAddRecordingTask
+ extends AsyncDvrDbTask<Recording, Void, List<Recording>> {
+
+ public AsyncAddRecordingTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected final List<Recording> doInDvrBackground(Recording... params) {
+ return sDbHelper.insertRecordings(params);
+ }
+ }
+
+ /**
+ * Update recordings.
+ *
+ * @return list of row update counts. The count will be -1 if there was an error or 0
+ * if no match was found. The count is expected to be exactly 1 for each recording.
+ */
+ public abstract static class AsyncUpdateRecordingTask
+ extends AsyncDvrDbTask<Recording, Void, List<Integer>> {
+ public AsyncUpdateRecordingTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected final List<Integer> doInDvrBackground(Recording... params) {
+ return sDbHelper.updateRecordings(params);
+ }
+ }
+
+ /**
+ * Delete recordings.
+ *
+ * @return list of row delete counts. The count will be -1 if there was an error or 0
+ * if no match was found. The count is expected to be exactly 1 for each recording.
+ */
+ public abstract static class AsyncDeleteRecordingTask
+ extends AsyncDvrDbTask<Recording, Void, List<Integer>> {
+ public AsyncDeleteRecordingTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected final List<Integer> doInDvrBackground(Recording... params) {
+ return sDbHelper.deleteRecordings(params);
+ }
+ }
+
public abstract static class AsyncDvrQueryTask
extends AsyncDvrDbTask<Void, Void, List<Recording>> {
public AsyncDvrQueryTask(Context context) {
@@ -76,9 +142,8 @@ public abstract class AsyncDvrDbTask<Params, Progress, Result>
}
@Override
- protected List<Recording> doInBackground(Void... params) {
- initializeDbHelper(mContext);
-
+ @Nullable
+ protected final List<Recording> doInDvrBackground(Void... params) {
if (isCancelled()) {
return null;
}
@@ -116,6 +181,7 @@ public abstract class AsyncDvrDbTask<Params, Progress, Result>
List<Long> programList = recordingToProgramMap.get(recordingId);
if (programList == null) {
programList = new ArrayList<>();
+ recordingToProgramMap.put(recordingId, programList);
}
programList.add(c.getLong(1));
}
diff --git a/src/com/android/tv/dvr/provider/DvrContract.java b/src/com/android/tv/dvr/provider/DvrContract.java
index 650de2e4..e6ce4141 100644
--- a/src/com/android/tv/dvr/provider/DvrContract.java
+++ b/src/com/android/tv/dvr/provider/DvrContract.java
@@ -51,6 +51,16 @@ public final class DvrContract {
public static final String STATE_RECORDING_FINISHED = "STATE_RECORDING_FINISHED";
/**
+ * The priority of this recording.
+ *
+ * <p> The lowest number is recorded first. If there is a tie in priority then the lower id
+ * wins. Defaults to {@value Long#MAX_VALUE}
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_PRIORITY = "priority";
+
+ /**
* The type of this recording.
*
* <p>This value should be one of the followings: {@link #TYPE_PROGRAM},
diff --git a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
index e9bfc340..2445e935 100644
--- a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
+++ b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
@@ -16,6 +16,7 @@
package com.android.tv.dvr.provider;
+import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
@@ -23,11 +24,16 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;
+import com.android.tv.data.Channel;
+import com.android.tv.dvr.Recording;
import com.android.tv.dvr.provider.DvrContract.DvrChannels;
import com.android.tv.dvr.provider.DvrContract.DvrPrograms;
import com.android.tv.dvr.provider.DvrContract.RecordingToPrograms;
import com.android.tv.dvr.provider.DvrContract.Recordings;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A data class for one recorded contents.
*/
@@ -35,12 +41,13 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DvrDatabaseHelper";
private static final boolean DEBUG = true;
- private static final int DATABASE_VERSION = 1;
+ private static final int DATABASE_VERSION = 2;
private static final String DB_NAME = "dvr.db";
private static final String SQL_CREATE_RECORDINGS =
"CREATE TABLE " + Recordings.TABLE_NAME + "("
- + Recordings._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + Recordings._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + Recordings.COLUMN_PRIORITY
+ + " INTEGER DEFAULT " + Long.MAX_VALUE + ","
+ Recordings.COLUMN_TYPE + " TEXT NOT NULL,"
+ Recordings.COLUMN_URI + " TEXT,"
+ Recordings.COLUMN_CHANNEL_ID + " INTEGER NOT NULL,"
@@ -77,6 +84,7 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
+ DvrPrograms.TABLE_NAME;
private static final String SQL_DROP_RECORDING_PROGRAMS = "DROP TABLE IF EXISTS "
+ RecordingToPrograms.TABLE_NAME;
+ public static final String WHERE_RECORDING_ID_EQUALS = Recordings._ID + " = ?";
public DvrDatabaseHelper(Context context) {
super(context.getApplicationContext(), DB_NAME, null, DATABASE_VERSION);
@@ -121,4 +129,85 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
builder.setTables(tableName);
return builder.query(db, projections, null, null, null, null, null);
}
+
+ /**
+ * Inserts recordings.
+ *
+ * @return The list of recordings with id set. The id will be -1 if there was an error.
+ */
+ public List<Recording> insertRecordings(Recording... recordings) {
+ updateChannelsFromRecordings(recordings);
+
+ SQLiteDatabase db = getReadableDatabase();
+ List<Recording> results = new ArrayList<>();
+ for (Recording r : recordings) {
+ ContentValues values = getContentValues(r);
+ long id = db.insert(Recordings.TABLE_NAME, null, values);
+ results.add(Recording.buildFrom(r).setId(id).build());
+ }
+ return results;
+ }
+
+ /**
+ * Update recordings.
+ *
+ * @return The list of row update counts. The count will be -1 if there was an error or 0
+ * if no match was found. The count is expected to be exactly 1 for each recording.
+ */
+ public List<Integer> updateRecordings(Recording[] recordings) {
+ updateChannelsFromRecordings(recordings);
+ SQLiteDatabase db = getWritableDatabase();
+ List<Integer> results = new ArrayList<>();
+ long count = 0;
+ for (Recording r : recordings) {
+ ContentValues values = getContentValues(r);
+ int updated = db.update(Recordings.TABLE_NAME, values, Recordings._ID + " = ?",
+ new String[] {String.valueOf(r.getId())});
+ results.add(updated);
+ }
+ return results;
+ }
+
+ private void updateChannelsFromRecordings(Recording[] recordings) {
+ // TODO(DVR) implement/
+ // TODO(DVR) consider not deleting channels instead of keeping a separate table.
+ }
+
+ private ContentValues getContentValues(Recording r) {
+ ContentValues values = new ContentValues();
+ // TODO(DVR): use DVR channel id instead
+ Channel channel = r.getChannel();
+ if (channel != null) {
+ values.put(Recordings.COLUMN_CHANNEL_ID, channel.getId());
+ }
+ values.put(Recordings.COLUMN_PRIORITY, r.getPriority());
+ values.put(Recordings.COLUMN_START_TIME_UTC_MILLIS, r.getStartTimeMs());
+ values.put(Recordings.COLUMN_END_TIME_UTC_MILLIS, r.getEndTimeMs());
+ values.put(Recordings.COLUMN_STATE, r.getState());
+ values.put(Recordings.COLUMN_MEDIA_SIZE, r.getSize());
+ values.put(Recordings.COLUMN_TYPE, r.getType());
+ if (r.getUri() != null) {
+ values.put(Recordings.COLUMN_URI, r.getUri().toString());
+ }
+ return values;
+ }
+
+ /**
+ * Delete recordings.
+ *
+ * @return The list of row update counts. The count will be -1 if there was an error or 0
+ * if no match was found. The count is expected to be exactly 1 for each recording.
+ */
+ public List<Integer> deleteRecordings(Recording[] recordings) {
+ SQLiteDatabase db = getWritableDatabase();
+ List<Integer> results = new ArrayList<>();
+ long count = 0;
+ for (Recording r : recordings) {
+ ContentValues values = getContentValues(r);
+ int deleted = db.delete(Recordings.TABLE_NAME, WHERE_RECORDING_ID_EQUALS,
+ new String[] {String.valueOf(r.getId())});
+ results.add(deleted);
+ }
+ return results;
+ }
}
diff --git a/src/com/android/tv/util/CollectionUtils.java b/src/com/android/tv/dvr/ui/DvrActivity.java
index d1c50392..01f3fb9c 100644
--- a/src/com/android/tv/util/CollectionUtils.java
+++ b/src/com/android/tv/dvr/ui/DvrActivity.java
@@ -14,28 +14,20 @@
* limitations under the License
*/
-package com.android.tv.util;
+package com.android.tv.dvr.ui;
-import android.os.Build;
-import android.util.ArraySet;
+import android.app.Activity;
+import android.os.Bundle;
-import java.util.HashSet;
-import java.util.Set;
+import com.android.tv.R;
/**
- * Static utilities for collections
+ * {@link android.app.Activity} for DVR UI.
*/
-public class CollectionUtils {
- /**
- * Returns a new Set suitable for small data sets.
- *
- * <p>In M and above this is a ArraySet otherwise it is a HashSet
- */
- public static <T> Set<T> createSmallSet() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return new ArraySet<>();
- } else {
- return new HashSet<>();
- }
+public class DvrActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dvr_main);
}
}
diff --git a/src/com/android/tv/dvr/ui/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
new file mode 100644
index 00000000..87e47930
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
@@ -0,0 +1,119 @@
+/*
+ * 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.os.Bundle;
+import android.support.annotation.IntDef;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.util.Log;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.Recording;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * {@link BrowseFragment} for DVR functions.
+ */
+public class DvrBrowseFragment extends BrowseFragment {
+ private static final String TAG = "DvrBrowseFragment";
+
+ @IntDef({DVR_CURRENT_RECORDINGS, DVR_SCHEDULED_RECORDINGS, DVR_RECORDED_PROGRAMS, DVR_SETTINGS})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DVR_HEADERS_MODE {}
+ public static final int DVR_CURRENT_RECORDINGS = 0;
+ public static final int DVR_SCHEDULED_RECORDINGS = 1;
+ public static final int DVR_RECORDED_PROGRAMS = 2;
+ public static final int DVR_SETTINGS = 3;
+
+ private static LinkedHashMap<Integer, Integer> sHeaders =
+ new LinkedHashMap<Integer, Integer>() {{
+ put(DVR_CURRENT_RECORDINGS, R.string.dvr_main_current_recordings);
+ put(DVR_SCHEDULED_RECORDINGS, R.string.dvr_main_scheduled_recordings);
+ put(DVR_RECORDED_PROGRAMS, R.string.dvr_main_recorded_programs);
+ put(DVR_SETTINGS, R.string.dvr_main_settings);
+ }};
+
+ private DvrDataManager mDvrDataManager;
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ Log.d(TAG, "onCreate");
+ super.onActivityCreated(savedInstanceState);
+ setupUiElements();
+ setupAdapter();
+ prepareEntranceTransition();
+
+ // TODO: load asynchronously.
+ loadData();
+ }
+
+ private void setupUiElements() {
+ setHeadersState(HEADERS_ENABLED);
+ setHeadersTransitionOnBackEnabled(false);
+ }
+
+ private void setupAdapter() {
+ mDvrDataManager = TvApplication.getSingletons(getContext()).getDvrDataManager();
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ setAdapter(mRowsAdapter);
+ }
+
+ private void loadRow(ArrayObjectAdapter gridRowAdapter, List<Recording> recordings) {
+ if (recordings == null || recordings.size() == 0) {
+ gridRowAdapter.add(null);
+ return;
+ }
+ for (Recording r : recordings) {
+ gridRowAdapter.add(r);
+ }
+ }
+
+ private void loadData() {
+ for (@DVR_HEADERS_MODE int i : sHeaders.keySet()) {
+ HeaderItem gridHeader = new HeaderItem(i, getContext().getString(sHeaders.get(i)));
+ GridItemPresenter gridPresenter = new GridItemPresenter(this);
+ ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
+ switch (i) {
+ case DVR_CURRENT_RECORDINGS:
+ loadRow(gridRowAdapter, mDvrDataManager.getStartedRecordings());
+ break;
+ case DVR_SCHEDULED_RECORDINGS:
+ loadRow(gridRowAdapter, mDvrDataManager.getScheduledRecordings());
+ break;
+ case DVR_RECORDED_PROGRAMS:
+ loadRow(gridRowAdapter, mDvrDataManager.getFinishedRecordings());
+ break;
+ case DVR_SETTINGS:
+ // TODO: provide setup rows.
+ break;
+ }
+ mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
+ }
+ startEntranceTransition();
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/GridItemPresenter.java b/src/com/android/tv/dvr/ui/GridItemPresenter.java
new file mode 100644
index 00000000..099816d4
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/GridItemPresenter.java
@@ -0,0 +1,165 @@
+/*
+ * 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.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Color;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.tv.MainActivity;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Channel;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.Recording;
+import com.android.tv.util.Utils;
+
+import java.util.List;
+
+public class GridItemPresenter extends Presenter {
+ private static final int GRID_ITEM_WIDTH = 200;
+ private static final int GRID_ITEM_HEIGHT = 200;
+
+ private final DvrBrowseFragment mainFragment;
+
+ public GridItemPresenter(DvrBrowseFragment mainFragment) {
+ this.mainFragment = mainFragment;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ TextView view = new TextView(parent.getContext());
+ view.setLayoutParams(new ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT));
+ view.setFocusable(true);
+ view.setFocusableInTouchMode(true);
+ view.setBackgroundColor(
+ Utils.getColor(mainFragment.getResources(), R.color.setup_background));
+ view.setTextColor(Color.WHITE);
+ view.setGravity(Gravity.CENTER);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, Object recording) {
+ if (recording == null) {
+ ((TextView) viewHolder.view).setText(viewHolder.view.getContext()
+ .getString(R.string.dvr_msg_no_recording_on_the_row));
+ } else {
+ final Recording r = (Recording) recording;
+ StringBuilder sb = new StringBuilder();
+ List<Program> programs = r.getPrograms();
+ if (programs != null && programs.size() > 0) {
+ sb.append(programs.get(0).getTitle());
+ } else {
+ sb.append(viewHolder.view.getContext()
+ .getString(R.string.dvr_msg_program_title_unknown));
+ }
+ sb.append(" ");
+ Channel channel = r.getChannel();
+ if (channel != null) {
+ sb.append(channel.getDisplayName());
+ } else {
+ sb.append(viewHolder.view.getContext().getString(R.string.dvr_msg_channel_unknown));
+ }
+ sb.append(" ").append(Utils.toIsoDateTimeString(r.getStartTimeMs()));
+ ((TextView) viewHolder.view).setText(sb.toString());
+ final Context context = viewHolder.view.getContext();
+ viewHolder.view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ switch (r.getState()) {
+ case Recording.STATE_RECORDING_NOT_STARTED: {
+ new AlertDialog.Builder(context)
+ .setNegativeButton(R.string.dvr_detail_cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Toast.makeText(context, "Not implemented yet",
+ Toast.LENGTH_SHORT).show();
+ }
+ })
+ .show();
+ break;
+ }
+ case Recording.STATE_RECORDING_IN_PROGRESS: {
+ new AlertDialog.Builder(context)
+ .setNegativeButton(R.string.dvr_detail_stop_delete,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Toast.makeText(context, "Not implemented yet",
+ Toast.LENGTH_SHORT).show();
+ }
+ })
+ .setPositiveButton(R.string.dvr_detail_stop_keep,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Toast.makeText(context, "Not implemented yet",
+ Toast.LENGTH_SHORT).show();
+ }
+ })
+ .show();
+ break;
+ }
+ case Recording.STATE_RECORDING_FINISHED: {
+ new AlertDialog.Builder(context)
+ .setNegativeButton(R.string.dvr_detail_delete,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ DvrManager dvrManager = TvApplication
+ .getSingletons(mainFragment.getContext())
+ .getDvrManager();
+ // TODO(DVR) handle success/failure.
+ dvrManager.removeRecording(r);
+ }
+ })
+ .setPositiveButton(R.string.dvr_detail_play,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = new Intent(context, MainActivity.class);
+ intent.putExtra(Utils.EXTRA_KEY_RECORDING_URI,
+ r.getUri());
+ context.startActivity(intent);
+ ((Activity) context).finish();
+ }
+ })
+ .show();
+ break;
+ }
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onUnbindViewHolder(ViewHolder viewHolder) {
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index d4e4a99d..77a1146b 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -252,32 +252,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
// It is usually called when Genre is changed.
// Reset selection of ProgramGrid
resetRowSelection();
-
- // Align EPG at vertical center, if EPG table height is less than the screen size.
- Resources res = mActivity.getResources();
- int screenHeight = mContainer.getHeight();
- 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);
- }
+ updateGuidePosition();
}
});
@@ -399,6 +374,34 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
mShowGuidePartial = 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) {
@@ -510,18 +513,19 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
if (DEBUG) {
mContainer.getViewTreeObserver().addOnDrawListener(
new ViewTreeObserver.OnDrawListener() {
- long time = System.currentTimeMillis();
- int count = 0;
- @Override
- public void onDraw() {
- long curtime = System.currentTimeMillis();
- Log.d(TAG, "onDraw " + count++ + " " + (curtime - time) + "ms");
- time = curtime;
- if (count > 10) {
- mContainer.getViewTreeObserver().removeOnDrawListener(this);
- }
- }
- });
+ long time = System.currentTimeMillis();
+ int count = 0;
+
+ @Override
+ public void onDraw() {
+ long curtime = System.currentTimeMillis();
+ Log.d(TAG, "onDraw " + count++ + " " + (curtime - time) + "ms");
+ time = curtime;
+ if (count > 10) {
+ mContainer.getViewTreeObserver().removeOnDrawListener(this);
+ }
+ }
+ });
}
runnableAfterAnimatorReady.run();
if (mShowGuidePartial) {
@@ -529,6 +533,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
} else {
mShowAnimatorFull.start();
}
+ updateGuidePosition();
}
};
mContainer.getViewTreeObserver().addOnGlobalLayoutListener(mOnLayoutListenerForShow);
diff --git a/src/com/android/tv/guide/ProgramItemView.java b/src/com/android/tv/guide/ProgramItemView.java
index 2fd2dac7..09a93037 100644
--- a/src/com/android/tv/guide/ProgramItemView.java
+++ b/src/com/android/tv/guide/ProgramItemView.java
@@ -37,14 +37,15 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.android.tv.ApplicationSingletons;
-import com.android.tv.Features;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.Recording;
import com.android.tv.guide.ProgramManager.TableEntry;
import com.android.tv.util.Utils;
@@ -86,7 +87,7 @@ public class ProgramItemView extends TextView {
private static final View.OnClickListener ON_CLICKED = new View.OnClickListener() {
@Override
- public void onClick(View view) {
+ public void onClick(final View view) {
TableEntry entry = ((ProgramItemView) view).mTableEntry;
ApplicationSingletons singletons = TvApplication.getSingletons(view.getContext());
Tracker tracker = singletons.getTracker();
@@ -101,43 +102,82 @@ public class ProgramItemView extends TextView {
tvActivity.tuneToChannel(channel);
tvActivity.hideOverlaysForTune();
}
- }, entry.getWidth() > ((ProgramItemView) view).mMaxWidthForRipple ? 0 :
- view.getResources().getInteger(R.integer.program_guide_ripple_anim_duration));
- } else if (Features.DVR.isEnabled(view.getContext())) {
- List<CharSequence> items = new ArrayList<>();
- final List<Integer> actions = new ArrayList<>();
- // TODO: the items can be changed by the state of the program. For example,
- // if the program is already added in scheduler, we need to show an item to
- // delete the recording schedule.
- items.add(view.getResources().getString(R.string.epg_dvr_record_program));
- actions.add(ACTION_RECORD_PROGRAM);
- items.add(view.getResources().getString(R.string.epg_dvr_record_season));
- actions.add(ACTION_RECORD_SEASON);
+ }, entry.getWidth() > ((ProgramItemView) view).mMaxWidthForRipple ? 0
+ : view.getResources()
+ .getInteger(R.integer.program_guide_ripple_anim_duration));
+ } else if (CommonFeatures.DVR.isEnabled(view.getContext())) {
final MainActivity tvActivity = (MainActivity) view.getContext();
final DvrManager dvrManager = singletons.getDvrManager();
final Channel channel = tvActivity.getChannelDataManager()
.getChannel(entry.channelId);
- final Program program = entry.program;
- // TODO: it is a tentative UI. Don't publish the UI.
- new AlertDialog.Builder(view.getContext())
- .setItems(items.toArray(new CharSequence[items.size()]),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (actions.get(which) == ACTION_RECORD_PROGRAM) {
- dvrManager.addSchedule(program);
- } else if (actions.get(which) == ACTION_RECORD_SEASON) {
- dvrManager.addSeasonSchedule(program);
- }
- dialog.dismiss();
- }
- })
- .create()
- .show();
+ if (dvrManager.canRecord(channel.getInputId())) {
+ showDvrDialog(view, entry, dvrManager);
+ }
}
}
+
+ private void showDvrDialog(final View view, TableEntry entry, final DvrManager dvrManager) {
+ List<CharSequence> items = new ArrayList<>();
+ final List<Integer> actions = new ArrayList<>();
+ // TODO: the items can be changed by the state of the program. For example,
+ // if the program is already added in scheduler, we need to show an item to
+ // delete the recording schedule.
+ items.add(view.getResources().getString(R.string.epg_dvr_record_program));
+ actions.add(ACTION_RECORD_PROGRAM);
+ items.add(view.getResources().getString(R.string.epg_dvr_record_season));
+ actions.add(ACTION_RECORD_SEASON);
+
+ final Program program = entry.program;
+ final List<Recording> conflicts = dvrManager
+ .getScheduledRecordingsThatConflict(program);
+ // TODO: it is a tentative UI. Don't publish the UI.
+ DialogInterface.OnClickListener onClickListener
+ = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(final DialogInterface dialog, int which) {
+ if (actions.get(which) == ACTION_RECORD_PROGRAM) {
+ if (conflicts.isEmpty()) {
+ dvrManager.addSchedule(program, conflicts);
+ } else {
+ showConflictDialog(view, dvrManager, program, conflicts);
+ }
+ } else if (actions.get(which) == ACTION_RECORD_SEASON) {
+ dvrManager.addSeasonSchedule(program);
+ }
+ dialog.dismiss();
+ }
+ };
+ new AlertDialog.Builder(view.getContext())
+ .setItems(items.toArray(new CharSequence[items.size()]), onClickListener)
+ .create()
+ .show();
+ }
};
+ private static void showConflictDialog(final View view, final DvrManager dvrManager,
+ final Program program, final List<Recording> conflicts) {
+ DialogInterface.OnClickListener conflictClickListener
+ = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == AlertDialog.BUTTON_POSITIVE) {
+ dvrManager.addSchedule(program, conflicts);
+ dialog.dismiss();
+ }
+ }
+ };
+ StringBuilder sb = new StringBuilder();
+ for (Recording r : conflicts) {
+ sb.append(r.toString()).append('\n');
+ }
+ new AlertDialog.Builder(view.getContext()).setTitle(R.string.dvr_epg_conflict_dialog_title)
+ .setMessage(sb.toString())
+ .setPositiveButton(R.string.dvr_epg_record, conflictClickListener)
+ .setNegativeButton(R.string.dvr_epg_do_not_record, conflictClickListener)
+ .create()
+ .show();
+ }
+
private static final View.OnFocusChangeListener ON_FOCUS_CHANGED =
new View.OnFocusChangeListener() {
@Override
@@ -218,6 +258,7 @@ public class ProgramItemView extends TextView {
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
initIfNeeded();
}
diff --git a/src/com/android/tv/guide/ProgramManager.java b/src/com/android/tv/guide/ProgramManager.java
index 216fcf3c..df52abbe 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -16,14 +16,15 @@
package com.android.tv.guide;
+import android.support.annotation.MainThread;
import android.util.Log;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.GenreItems;
import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.util.CollectionUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
@@ -37,6 +38,7 @@ import java.util.concurrent.TimeUnit;
/**
* Manages the channels and programs for the program guide.
*/
+@MainThread
public class ProgramManager {
private static final String TAG = "ProgramManager";
private static final boolean DEBUG = false;
diff --git a/src/com/android/tv/guide/ProgramTableAdapter.java b/src/com/android/tv/guide/ProgramTableAdapter.java
index cd0e9611..a86c1332 100644
--- a/src/com/android/tv/guide/ProgramTableAdapter.java
+++ b/src/com/android/tv/guide/ProgramTableAdapter.java
@@ -16,6 +16,8 @@
package com.android.tv.guide;
+import static com.android.tv.util.ImageLoader.ImageLoaderCallback;
+
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
@@ -25,6 +27,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.tv.TvContentRating;
import android.os.Handler;
+import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.RecycledViewPool;
import android.text.Spannable;
@@ -177,9 +180,8 @@ public class ProgramTableAdapter extends
}
// TODO: make it static
- public class ProgramRowHolder extends RecyclerView.ViewHolder implements
- ProgramRow.ChildFocusListener, Program.LoadPosterArtCallback,
- Channel.LoadImageCallback {
+ public class ProgramRowHolder extends RecyclerView.ViewHolder
+ implements ProgramRow.ChildFocusListener {
private final ViewGroup mContainer;
private final ProgramRow mProgramRow;
@@ -288,8 +290,8 @@ public class ProgramTableAdapter extends
mChannelNumberView.setText(displayNumber);
mChannelNumberView.setVisibility(View.VISIBLE);
}
- mChannelNumberView.setTextColor(isChannelLocked(channel)
- ? mChannelBlockedTextColor : mChannelTextColor);
+ mChannelNumberView.setTextColor(
+ isChannelLocked(channel) ? mChannelBlockedTextColor : mChannelTextColor);
mChannelLogoView.setImageBitmap(null);
mChannelLogoView.setVisibility(View.GONE);
@@ -302,7 +304,8 @@ public class ProgramTableAdapter extends
mChannelBlockView.setVisibility(View.GONE);
mChannel.loadBitmap(itemView.getContext(), Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
- mChannelLogoWidth, mChannelLogoHeight, this);
+ mChannelLogoWidth, mChannelLogoHeight,
+ createChannelLogoLoadedCallback(this, channel.getId()));
}
}
@@ -386,10 +389,10 @@ public class ProgramTableAdapter extends
TvContentRating blockedRating = getProgramBlock(program);
- mImageView.setImageBitmap(null);
- mImageView.setVisibility(View.GONE);
+ updatePosterArt(null);
if (blockedRating == null) {
- program.loadPosterArt(context, mImageWidth, mImageHeight, this);
+ program.loadPosterArt(context, mImageWidth, mImageHeight,
+ createProgramPosterArtCallback(this, program));
}
if (TextUtils.isEmpty(program.getEpisodeTitle())) {
@@ -473,27 +476,12 @@ public class ProgramTableAdapter extends
}
}
- @Override
- public void onLoadPosterArtFinished(Program program, Bitmap posterArt) {
- if (posterArt == null || mSelectedEntry == null || mSelectedEntry.program == null) {
- return;
- }
-
- String posterArtUri = mSelectedEntry.program.getPosterArtUri();
- if (posterArtUri == null || !posterArtUri.equals(program.getPosterArtUri())) {
- return;
- }
-
+ private void updatePosterArt(@Nullable Bitmap posterArt) {
mImageView.setImageBitmap(posterArt);
- mImageView.setVisibility(View.VISIBLE);
+ mImageView.setVisibility(posterArt == null ? View.GONE : View.VISIBLE);
}
- @Override
- public void onLoadImageFinished(Channel channel, int type, Bitmap logo) {
- if (logo == null || mChannel == null || mChannel.getId() != channel.getId()) {
- return;
- }
-
+ private void updateChannelLogo(@Nullable Bitmap logo) {
mChannelLogoView.setImageBitmap(logo);
mChannelNameView.setVisibility(View.GONE);
mChannelLogoView.setVisibility(View.VISIBLE);
@@ -506,4 +494,36 @@ public class ProgramTableAdapter extends
}
}
}
+
+ private static ImageLoaderCallback<ProgramRowHolder> createProgramPosterArtCallback(
+ ProgramRowHolder holder, final Program program) {
+ return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ @Override
+ public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap posterArt) {
+ if (posterArt == null || holder.mSelectedEntry == null
+ || holder.mSelectedEntry.program == null) {
+ return;
+ }
+ String posterArtUri = holder.mSelectedEntry.program.getPosterArtUri();
+ if (posterArtUri == null || !posterArtUri.equals(program.getPosterArtUri())) {
+ return;
+ }
+ holder.updatePosterArt(posterArt);
+ }
+ };
+ }
+
+ private static ImageLoaderCallback<ProgramRowHolder> createChannelLogoLoadedCallback(
+ ProgramRowHolder holder, final long channelId) {
+ return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ @Override
+ public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap logo) {
+ if (logo == null || holder.mChannel == null
+ || holder.mChannel.getId() != channelId) {
+ return;
+ }
+ holder.updateChannelLogo(logo);
+ }
+ };
+ }
}
diff --git a/src/com/android/tv/menu/ActionCardView.java b/src/com/android/tv/menu/ActionCardView.java
index c4ddabe4..1848a3ce 100644
--- a/src/com/android/tv/menu/ActionCardView.java
+++ b/src/com/android/tv/menu/ActionCardView.java
@@ -53,6 +53,7 @@ public class ActionCardView extends FrameLayout implements ItemListRowView.CardV
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
mIconView = (ImageView) findViewById(R.id.action_card_icon);
mLabelView = (TextView) findViewById(R.id.action_card_label);
mStateView = (TextView) findViewById(R.id.action_card_state);
diff --git a/src/com/android/tv/menu/AppLinkCardView.java b/src/com/android/tv/menu/AppLinkCardView.java
index 60a4481e..74375da4 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.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -37,13 +38,14 @@ import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.data.Channel;
import com.android.tv.util.BitmapUtils;
+import com.android.tv.util.ImageLoader;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
/**
* A view to render an app link card.
*/
-public class AppLinkCardView extends BaseCardView<Channel> implements Channel.LoadImageCallback {
+public class AppLinkCardView extends BaseCardView<Channel> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
@@ -126,7 +128,8 @@ public class AppLinkCardView extends BaseCardView<Channel> implements Channel.Lo
mAppInfoView.setText(mPackageManager.getApplicationLabel(appInfo));
if (!TextUtils.isEmpty(mChannel.getAppLinkIconUri())) {
mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON,
- mIconWidth, mIconHeight, this);
+ 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);
@@ -156,7 +159,8 @@ public class AppLinkCardView extends BaseCardView<Channel> implements Channel.Lo
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, this);
+ mCardImageWidth, mCardImageHeight, createChannelLogoCallback(this, mChannel,
+ Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART));
} else {
setCardImageWithBanner(appInfo);
}
@@ -174,12 +178,21 @@ public class AppLinkCardView extends BaseCardView<Channel> implements Channel.Lo
super.onBind(channel, selected);
}
- @Override
- public void onLoadImageFinished(Channel channel, int type, Bitmap bitmap) {
- // mChannel can be changed before the image load finished.
- if (!mChannel.hasSameReadOnlyInfo(channel)) {
- return;
- }
+ private static ImageLoader.ImageLoaderCallback<AppLinkCardView> createChannelLogoCallback(
+ AppLinkCardView cardView, final Channel channel, final int type) {
+ return new ImageLoader.ImageLoaderCallback<AppLinkCardView>(cardView) {
+ @Override
+ public void onBitmapLoaded(AppLinkCardView cardView, @Nullable Bitmap bitmap) {
+ // mChannel can be changed before the image load finished.
+ if (!cardView.mChannel.hasSameReadOnlyInfo(channel)) {
+ return;
+ }
+ cardView.updateChannelLogo(bitmap, type);
+ }
+ };
+ }
+
+ private void updateChannelLogo(@Nullable Bitmap bitmap, int type) {
if (type == Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON) {
BitmapDrawable drawable = null;
if (bitmap != null) {
@@ -188,7 +201,8 @@ public class AppLinkCardView extends BaseCardView<Channel> implements Channel.Lo
drawable.setBounds(0, 0, mIconWidth,
mIconWidth * bitmap.getHeight() / bitmap.getWidth());
} else {
- drawable.setBounds(0, 0, mIconHeight * bitmap.getWidth() / bitmap.getHeight(),
+ drawable.setBounds(0, 0,
+ mIconHeight * bitmap.getWidth() / bitmap.getHeight(),
mIconHeight);
}
}
@@ -209,6 +223,7 @@ public class AppLinkCardView extends BaseCardView<Channel> implements Channel.Lo
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
mImageView = (ImageView) findViewById(R.id.image);
mGradientView = findViewById(R.id.image_gradient);
mAppInfoView = (TextView) findViewById(R.id.app_info);
diff --git a/src/com/android/tv/menu/ChannelCardView.java b/src/com/android/tv/menu/ChannelCardView.java
index ea4f31e9..860da224 100644
--- a/src/com/android/tv/menu/ChannelCardView.java
+++ b/src/com/android/tv/menu/ChannelCardView.java
@@ -18,6 +18,7 @@ package com.android.tv.menu;
import android.content.Context;
import android.graphics.Bitmap;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -32,12 +33,12 @@ import com.android.tv.R;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.parental.ParentalControlSettings;
+import com.android.tv.util.ImageLoader;
/**
* A view to render channel card.
*/
-public class ChannelCardView extends BaseCardView<Channel> implements
- Program.LoadPosterArtCallback {
+public class ChannelCardView extends BaseCardView<Channel> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
@@ -85,6 +86,7 @@ public class ChannelCardView extends BaseCardView<Channel> implements
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
mImageView = (ImageView) findViewById(R.id.image);
mGradientView = findViewById(R.id.image_gradient);
mChannelNumberNameView = (TextView) findViewById(R.id.channel_number_and_name);
@@ -136,13 +138,22 @@ public class ChannelCardView extends BaseCardView<Channel> implements
super.onBind(channel, selected);
}
- @Override
- public void onLoadPosterArtFinished(Program program, Bitmap posterArt) {
- if (posterArt == null || mProgram == null
- || program.getChannelId() != mProgram.getChannelId()
- || program.getChannelId() != mChannel.getId()) {
- return;
- }
+ private static ImageLoader.ImageLoaderCallback<ChannelCardView> createProgramPosterArtCallback(
+ ChannelCardView cardView, final Program program) {
+ return new ImageLoader.ImageLoaderCallback<ChannelCardView>(cardView) {
+ @Override
+ public void onBitmapLoaded(ChannelCardView cardView, @Nullable Bitmap posterArt) {
+ if (posterArt == null || cardView.mProgram == null
+ || program.getChannelId() != cardView.mProgram.getChannelId()
+ || program.getChannelId() != cardView.mChannel.getId()) {
+ return;
+ }
+ cardView.updatePosterArt(posterArt);
+ }
+ };
+ }
+
+ private void updatePosterArt(Bitmap posterArt) {
mImageView.setImageBitmap(posterArt);
mGradientView.setVisibility(View.VISIBLE);
}
@@ -208,7 +219,7 @@ public class ChannelCardView extends BaseCardView<Channel> implements
|| !parental.isRatingBlocked(mProgram.getContentRatings()))
&& !TextUtils.isEmpty(mProgram.getPosterArtUri())) {
mProgram.loadPosterArt(getContext(), mCardImageWidth, mCardImageHeight,
- ChannelCardView.this);
+ createProgramPosterArtCallback(this, mProgram));
}
}
diff --git a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
index d576342c..1e416e5b 100644
--- a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
+++ b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
@@ -18,7 +18,9 @@ package com.android.tv.menu;
import android.content.Context;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
+import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.util.Log;
@@ -49,7 +51,6 @@ public class ChannelsPosterPrefetcher {
private boolean isCanceled;
-
/**
* Create {@link ChannelsPosterPrefetcher} object with given parameters.
*/
@@ -72,16 +73,14 @@ public class ChannelsPosterPrefetcher {
if (isCanceled) {
return;
}
- if (DEBUG) {
- Log.d(TAG, "startPrefetching()");
- }
+ if (DEBUG) Log.d(TAG, "startPrefetching()");
/*
* When a user browse channels, this method could be called many times. We don't need to
* prefetch the intermediate channels. So ignore previous schedule.
*/
mHandler.removeMessages(MSG_PREFETCH_IMAGE);
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_PREFETCH_IMAGE), ONDEMAND_POSTER_PREFETCH_DELAY_MILLIS);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PREFETCH_IMAGE),
+ ONDEMAND_POSTER_PREFETCH_DELAY_MILLIS);
}
/**
@@ -92,11 +91,12 @@ public class ChannelsPosterPrefetcher {
mHandler.removeCallbacksAndMessages(null);
}
+ @MainThread // ProgramDataManager.getCurrentProgram must be called from the main thread
private void doPrefetchImages() {
- if (DEBUG) {
- Log.d(TAG, "doPrefetchImages()");
- }
+ if (DEBUG) Log.d(TAG, "doPrefetchImages() started");
+ // 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) {
@@ -114,14 +114,20 @@ public class ChannelsPosterPrefetcher {
}
}
}
+ if (DEBUG) {
+ Log.d(TAG, "doPrefetchImages() finished. ImageLoader may still have async tasks for "
+ + "channels " + channelList);
+ }
}
private static class PrefetchHandler extends WeakHandler<ChannelsPosterPrefetcher> {
public PrefetchHandler(ChannelsPosterPrefetcher ref) {
- super(ref);
+ // doPrefetchImages must be called from the main thread.
+ super(Looper.getMainLooper(), ref);
}
@Override
+ @MainThread
public void handleMessage(Message msg, @NonNull ChannelsPosterPrefetcher prefetcher) {
switch (msg.what) {
case MSG_PREFETCH_IMAGE:
diff --git a/src/com/android/tv/menu/ChannelsRowAdapter.java b/src/com/android/tv/menu/ChannelsRowAdapter.java
index 6cbd67ce..51867d0b 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -25,6 +25,7 @@ import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.recommendation.Recommender;
import com.android.tv.util.SetupUtils;
@@ -36,16 +37,16 @@ import java.util.List;
* An adapter of the Channels row.
*/
public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel> {
- private static final int POSITION_FIRST_CARD = 0;
- private static final int POSITION_SECOND_CARD = 1;
- private static final int POSITION_THIRD_CARD = 2;
+ // There are four special cards: guide, setup, dvr, applink.
+ private static final int SIZE_OF_VIEW_TYPE = 4;
+
private final Context mContext;
private final Tracker mTracker;
private final Recommender mRecommender;
private final int mMaxCount;
private final int mMinCount;
- private boolean mShowSetupCard;
- private boolean mShowAppLinkCard;
+ private boolean mShowDvrCard;
+ private int[] mViewType = new int[SIZE_OF_VIEW_TYPE];
private final View.OnClickListener mGuideOnClickListener = new View.OnClickListener() {
@Override
@@ -59,7 +60,15 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
@Override
public void onClick(View view) {
mTracker.sendMenuClicked(R.string.channels_item_setup);
- getMainActivity().getOverlayManager().showSetupDialog();
+ getMainActivity().getOverlayManager().showSetupFragment();
+ }
+ };
+
+ private final View.OnClickListener mDvrOnClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mTracker.sendMenuClicked(R.string.channels_item_dvr);
+ getMainActivity().getOverlayManager().showDvrManager();
}
};
@@ -93,26 +102,15 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
mRecommender = recommender;
mMinCount = minCount;
mMaxCount = maxCount;
+ mShowDvrCard = CommonFeatures.DVR.isEnabled(mContext);
}
@Override
public int getItemViewType(int position) {
- switch (position) {
- case POSITION_FIRST_CARD:
- return R.layout.menu_card_guide;
- case POSITION_SECOND_CARD:
- return mShowSetupCard
- ? R.layout.menu_card_setup
- : mShowAppLinkCard
- ? R.layout.menu_card_app_link
- : R.layout.menu_card_channel;
- case POSITION_THIRD_CARD:
- return (mShowSetupCard && mShowAppLinkCard)
- ? R.layout.menu_card_app_link
- : R.layout.menu_card_channel;
- default:
- return R.layout.menu_card_channel;
+ if (position >= SIZE_OF_VIEW_TYPE) {
+ return R.layout.menu_card_channel;
}
+ return mViewType[position];
}
@Override
@@ -131,6 +129,8 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
viewHolder.itemView.setOnClickListener(mSetupOnClickListener);
} else if (viewType == R.layout.menu_card_app_link) {
viewHolder.itemView.setOnClickListener(mAppLinkOnClickListener);
+ } else if (viewType == R.layout.menu_card_dvr) {
+ viewHolder.itemView.setOnClickListener(mDvrOnClickListener);
} else {
viewHolder.itemView.setTag(getItemList().get(position));
viewHolder.itemView.setOnClickListener(mChannelOnClickListener);
@@ -145,20 +145,30 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
// For guide item
channelList.add(dummyChannel);
// For setup item
- mShowSetupCard = SetupUtils.getInstance(mContext).hasNewInput(
- ((MainActivity) mContext).getTvInputManagerHelper());
- if (mShowSetupCard) {
+ boolean showSetupCard = SetupUtils.getInstance(mContext)
+ .hasNewInput(((MainActivity) mContext).getTvInputManagerHelper());
+ Channel currentChannel = ((MainActivity) mContext).getCurrentChannel();
+ boolean showAppLinkCard = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+ && currentChannel != null
+ && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE;
+
+ mViewType[0] = R.layout.menu_card_guide;
+ int index = 1;
+ if (showSetupCard) {
channelList.add(dummyChannel);
+ mViewType[index++] = R.layout.menu_card_setup;
}
- if (Build.VERSION.SDK_INT >= 23) {
- Channel currentChannel = ((MainActivity) mContext).getCurrentChannel();
- mShowAppLinkCard = currentChannel != null
- && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE;
- if (mShowAppLinkCard) {
- channelList.add(currentChannel);
- }
+ if (mShowDvrCard) {
+ 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);
}
diff --git a/src/com/android/tv/menu/MenuAction.java b/src/com/android/tv/menu/MenuAction.java
index 5ef714dd..b45e88c2 100644
--- a/src/com/android/tv/menu/MenuAction.java
+++ b/src/com/android/tv/menu/MenuAction.java
@@ -42,18 +42,13 @@ public class MenuAction {
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);
- public static final MenuAction CHANNEL_SOURCES_ACTION =
- new MenuAction(R.string.options_item_channel_sources,
- TvOptionsManager.OPTION_CHANNEL_SOURCES,
- R.drawable.ic_tvoption_channel_sources);
- public static final MenuAction PARENTAL_CONTROLS_ACTION =
- new MenuAction(R.string.options_item_parental_controls,
- TvOptionsManager.OPTION_PARENTAL_CONTROLS,
- R.drawable.ic_tvoption_parental);
- public static final MenuAction ABOUT_ACTION =
- new MenuAction(R.string.options_item_about,
- TvOptionsManager.OPTION_ABOUT,
- R.drawable.ic_tvoption_about);
+ public static final MenuAction MORE_CHANNELS_ACTION =
+ new MenuAction(R.string.options_item_more_channels,
+ TvOptionsManager.OPTION_MORE_CHANNELS, R.drawable.ic_store);
+ // 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,
diff --git a/src/com/android/tv/menu/MenuRowView.java b/src/com/android/tv/menu/MenuRowView.java
index 6b3b6b5f..7cdbfe9e 100644
--- a/src/com/android/tv/menu/MenuRowView.java
+++ b/src/com/android/tv/menu/MenuRowView.java
@@ -115,6 +115,7 @@ public abstract class MenuRowView extends LinearLayout {
@Override
protected void onFinishInflate() {
+ super.onFinishInflate();
mTitleView = (TextView) findViewById(R.id.title);
mContentsView = findViewById(getContentsViewId());
if (mContentsView.isFocusable()) {
diff --git a/src/com/android/tv/menu/PlayControlsRowView.java b/src/com/android/tv/menu/PlayControlsRowView.java
index d4ad7877..f0853c40 100644
--- a/src/com/android/tv/menu/PlayControlsRowView.java
+++ b/src/com/android/tv/menu/PlayControlsRowView.java
@@ -54,6 +54,7 @@ public class PlayControlsRowView extends MenuRowView {
private View mUnavailableMessageText;
private TimeShiftManager mTimeShiftManager;
+ private final java.text.DateFormat mTimeFormat;
private long mProgramStartTimeMs;
private long mProgramEndTimeMs;
@@ -78,6 +79,7 @@ public class PlayControlsRowView extends MenuRowView {
mTimeTextLeftMargin =
- res.getDimensionPixelOffset(R.dimen.play_controls_time_width) / 2;
mTimelineWidth = res.getDimensionPixelSize(R.dimen.play_controls_width);
+ mTimeFormat = DateFormat.getTimeFormat(context);
}
@Override
@@ -188,7 +190,7 @@ public class PlayControlsRowView extends MenuRowView {
}
@Override
- public void onRecordStartTimeChanged() {
+ public void onRecordTimeRangeChanged() {
if (!mTimeShiftManager.isAvailable()) {
return;
}
@@ -355,6 +357,14 @@ public class PlayControlsRowView extends MenuRowView {
mTimeIndicator.setVisibility(View.INVISIBLE);
return;
}
+ if (mTimeShiftManager.isPlayForRecording()) {
+ mProgramStartTimeMs = mTimeShiftManager.getRecordStartTimeMs();
+ mProgramEndTimeMs = Math.max(mProgramStartTimeMs,
+ mTimeShiftManager.getRecordEndTimeMs());
+ if (mProgramStartTimeMs > mProgramEndTimeMs) {
+ mProgramEndTimeMs = mProgramStartTimeMs;
+ }
+ }
long currentPositionMs = mTimeShiftManager.getCurrentPositionMs();
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams) mTimeText.getLayoutParams();
@@ -387,11 +397,11 @@ public class PlayControlsRowView extends MenuRowView {
}
long progressStartTimeMs = Math.min(mProgramEndTimeMs,
- Math.max(mProgramStartTimeMs, mTimeShiftManager.getRecordStartTimeMs()));
+ Math.max(mProgramStartTimeMs, mTimeShiftManager.getRecordStartTimeMs()));
long currentPlayingTimeMs = Math.min(mProgramEndTimeMs,
- Math.max(mProgramStartTimeMs, mTimeShiftManager.getCurrentPositionMs()));
+ Math.max(mProgramStartTimeMs, mTimeShiftManager.getCurrentPositionMs()));
long progressEndTimeMs = Math.min(mProgramEndTimeMs,
- Math.max(mProgramStartTimeMs, System.currentTimeMillis()));
+ Math.max(mProgramStartTimeMs, mTimeShiftManager.getRecordEndTimeMs()));
layoutProgress(mProgressEmptyBefore, mProgramStartTimeMs, progressStartTimeMs);
layoutProgress(mProgressWatched, progressStartTimeMs, currentPlayingTimeMs);
@@ -468,7 +478,7 @@ public class PlayControlsRowView extends MenuRowView {
}
private String getTimeString(long timeMs) {
- return DateFormat.getTimeFormat(getContext()).format(timeMs);
+ return mTimeFormat.format(timeMs);
}
private int convertDurationToPixel(long duration) {
diff --git a/src/com/android/tv/menu/GuideCardView.java b/src/com/android/tv/menu/SimpleCardView.java
index 94d625bd..24a44244 100644
--- a/src/com/android/tv/menu/GuideCardView.java
+++ b/src/com/android/tv/menu/SimpleCardView.java
@@ -25,20 +25,20 @@ import com.android.tv.data.Channel;
/**
* A view to render a guide card.
*/
-public class GuideCardView extends BaseCardView<Channel> {
+public class SimpleCardView extends BaseCardView<Channel> {
private static final String TAG = "GuideCardView";
private static final boolean DEBUG = false;
private final float mCardHeight;
- public GuideCardView(Context context) {
+ public SimpleCardView(Context context) {
this(context, null, 0);
}
- public GuideCardView(Context context, AttributeSet attrs) {
+ public SimpleCardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public GuideCardView(Context context, AttributeSet attrs, int defStyle) {
+ public SimpleCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mCardHeight = getResources().getDimension(R.dimen.card_layout_height);
}
diff --git a/src/com/android/tv/menu/TvOptionsRowAdapter.java b/src/com/android/tv/menu/TvOptionsRowAdapter.java
index 1977dde1..82525456 100644
--- a/src/com/android/tv/menu/TvOptionsRowAdapter.java
+++ b/src/com/android/tv/menu/TvOptionsRowAdapter.java
@@ -20,16 +20,15 @@ import android.content.Context;
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;
import com.android.tv.ui.TvViewUiManager;
-import com.android.tv.ui.sidepanel.AboutFragment;
import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
-import com.android.tv.util.PermissionUtils;
import com.android.tv.util.PipInputManager;
import java.util.ArrayList;
@@ -50,25 +49,18 @@ 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_ACTION);
+ setOptionChangedListener(MenuAction.PIP_ACTION);
mPositionPipAction = actionList.size() - 1;
actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
- actionList.add(MenuAction.CHANNEL_SOURCES_ACTION);
- if (PermissionUtils.hasModifyParentalControls(getMainActivity())) {
- actionList.add(MenuAction.PARENTAL_CONTROLS_ACTION);
- } else {
- // Note: parental control is turned off, when MODIFY_PARENTAL_CONTROLS is not granted.
- // But, we may be able to turn on channel lock feature regardless of the permission.
- // It's TBD.
- }
- actionList.add(MenuAction.ABOUT_ACTION);
-
- for (MenuAction action : actionList) {
- if (action.getType() != TvOptionsManager.OPTION_CHANNEL_SOURCES) {
- setOptionChangedListener(action);
- }
+ setOptionChangedListener(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
+ if (Features.ONBOARDING_PLAY_STORE.isEnabled(getMainActivity())) {
+ actionList.add(MenuAction.MORE_CHANNELS_ACTION);
}
+ actionList.add(MenuAction.SETTINGS_ACTION);
if (getCustomActions() != null) {
// Adjust Pip action position which will be changed by applying custom actions.
@@ -188,15 +180,11 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
getMainActivity().getOverlayManager().getSideFragmentManager().show(
new MultiAudioFragment());
break;
- case TvOptionsManager.OPTION_CHANNEL_SOURCES:
- getMainActivity().showChannelSourcesFragment();
- break;
- case TvOptionsManager.OPTION_PARENTAL_CONTROLS:
- getMainActivity().showParentalControlFragment();
+ case TvOptionsManager.OPTION_MORE_CHANNELS:
+ getMainActivity().showMerchantCollection();
break;
- case TvOptionsManager.OPTION_ABOUT:
- getMainActivity().getOverlayManager().getSideFragmentManager().show(
- new AboutFragment());
+ case TvOptionsManager.OPTION_SETTINGS:
+ getMainActivity().showSettingsFragment();
break;
}
}
diff --git a/src/com/android/tv/onboarding/AppOverviewFragment.java b/src/com/android/tv/onboarding/AppOverviewFragment.java
deleted file mode 100644
index a2f5d768..00000000
--- a/src/com/android/tv/onboarding/AppOverviewFragment.java
+++ /dev/null
@@ -1,110 +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.onboarding;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-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.Features;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
-import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
-
-import java.util.List;
-
-/**
- * A fragment for channel source info/setup.
- */
-public class AppOverviewFragment extends SetupMultiPaneFragment {
- public static final int ACTION_SETUP_SOURCE = 1;
- public static final int ACTION_GET_MORE_CHANNELS = 2;
- public static final int ACTION_SETUP_USB_TUNER = 3;
-
- public static final String KEY_AC3_SUPPORT = "key_ac3_support";
-
- private boolean mAc3Supported;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- Bundle bundle = getArguments();
- mAc3Supported = bundle.getBoolean(KEY_AC3_SUPPORT);
- return view;
- }
-
- @Override
- protected SetupGuidedStepFragment onCreateContentFragment() {
- return new ContentFragment();
- }
-
- @Override
- protected boolean needsDoneButton() {
- return false;
- }
-
- // AppOverviewFragment should inherit OnboardingPageFragment for animation and command execution
- // purpose. So child fragment which inherits GuidedStepFragment is needed.
- private class ContentFragment extends SetupGuidedStepFragment {
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getString(R.string.app_overview_text);
- String description = mAc3Supported
- ? getString(R.string.app_overview_description_has_ac3)
- : getString(R.string.app_overview_description_no_ac3);
- return new Guidance(title, description, null, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- boolean hasTvInput =
- TvApplication.getSingletons(getActivity()).getTvInputManagerHelper()
- .getTunerTvInputSize() > 0;
- Resources res = getResources();
- if (hasTvInput) {
- actions.add(new GuidedAction.Builder()
- .id(ACTION_SETUP_SOURCE)
- .title(res.getString(R.string.app_overview_action_text_setup_source))
- .description(res.getString(
- R.string.app_overview_action_description_setup_source))
- .build());
- }
- if (Features.ONBOARDING_PLAY_STORE.isEnabled(getActivity())) {
- actions.add(new GuidedAction.Builder()
- .id(ACTION_GET_MORE_CHANNELS)
- .title(res.getString(R.string.app_overview_action_text_play_store))
- .description(res.getString(
- R.string.app_overview_action_description_play_store))
- .build());
- }
- if (Features.ONBOARDING_USB_TUNER.isEnabled(getActivity()) && mAc3Supported) {
- actions.add(new GuidedAction.Builder()
- .id(ACTION_SETUP_USB_TUNER)
- .title(res.getString(R.string.app_overview_action_text_usb_tuner))
- .description(res.getString(
- R.string.app_overview_action_description_usb_tuner))
- .build());
- }
- }
- }
-}
diff --git a/src/com/android/tv/onboarding/NewSourcesFragment.java b/src/com/android/tv/onboarding/NewSourcesFragment.java
new file mode 100644
index 00000000..ebaf0b6c
--- /dev/null
+++ b/src/com/android/tv/onboarding/NewSourcesFragment.java
@@ -0,0 +1,82 @@
+/*
+ * 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.onboarding;
+
+import android.app.Fragment;
+import android.os.Build;
+import android.os.Bundle;
+import android.transition.Slide;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.ui.setup.OnActionClickListener;
+import com.android.tv.common.ui.setup.SetupActionHelper;
+import com.android.tv.util.SetupUtils;
+
+/**
+ * A fragment for new channel source info/setup.
+ */
+public class NewSourcesFragment extends Fragment {
+ public static final String ACTION_CATEOGRY = NewSourcesFragment.class.getCanonicalName();
+ public static final int ACTION_SETUP = 1;
+ public static final int ACTION_SKIP = 2;
+
+ private OnActionClickListener mOnActionClickListener;
+
+ public NewSourcesFragment() {
+ setAllowEnterTransitionOverlap(false);
+ setAllowReturnTransitionOverlap(false);
+ setEnterTransition(new Slide(Gravity.BOTTOM));
+ setExitTransition(new Slide(Gravity.BOTTOM));
+ setReenterTransition(new Slide(Gravity.BOTTOM));
+ setReturnTransition(new Slide(Gravity.BOTTOM));
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_new_sources, container, false);
+ initializeButton(view.findViewById(R.id.setup), ACTION_SETUP);
+ initializeButton(view.findViewById(R.id.skip), ACTION_SKIP);
+ SetupUtils.getInstance(getActivity()).markAllInputsRecognized(TvApplication
+ .getSingletons(getActivity()).getTvInputManagerHelper());
+ view.requestFocus();
+ return view;
+ }
+
+ /**
+ * Sets the {@link OnActionClickListener}. This method should be called before the views are
+ * created.
+ */
+ public void setOnActionClickListener(OnActionClickListener onActionClickListener) {
+ mOnActionClickListener = onActionClickListener;
+ }
+
+ private void initializeButton(View view, int actionId) {
+ view.setOnClickListener(SetupActionHelper.createOnClickListenerForAction(
+ mOnActionClickListener, ACTION_CATEOGRY, actionId));
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ // Prior to M, foreground ripple animation is not supported.
+ // Use background ripple drawable instead of drawing in the foreground manually.
+ view.setBackground(getActivity().getDrawable(R.drawable.setup_selector_background));
+ }
+ }
+}
diff --git a/src/com/android/tv/onboarding/OnboardingActivity.java b/src/com/android/tv/onboarding/OnboardingActivity.java
index 3717a611..3ae80597 100644
--- a/src/com/android/tv/onboarding/OnboardingActivity.java
+++ b/src/com/android/tv/onboarding/OnboardingActivity.java
@@ -17,48 +17,45 @@
package com.android.tv.onboarding;
import android.app.Fragment;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
-import android.media.tv.TvInputInfo;
-import android.net.Uri;
+import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.common.WeakHandler;
-import com.android.tv.common.ui.setup.SetupStep;
-import com.android.tv.common.ui.setup.SteppedSetupActivity;
+import com.android.tv.common.ui.setup.SetupActivity;
+import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.receiver.AudioCapabilitiesReceiver;
import com.android.tv.util.OnboardingUtils;
+import com.android.tv.util.PermissionUtils;
import com.android.tv.util.SetupUtils;
-import com.android.tv.util.SoftPreconditions;
-import com.android.tv.util.Utils;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
+public class OnboardingActivity extends SetupActivity {
+ private static final String KEY_INTENT_AFTER_COMPLETION = "key_intent_after_completion";
-public class OnboardingActivity extends SteppedSetupActivity {
- private static final String TAG = "OnboardingActivity";
+ private static final int PERMISSIONS_REQUEST_READ_TV_LISTINGS = 1;
+ private static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
- private static final String KEY_INTENT_AFTER_COMPLETION = "key_intent_after_completion";
+ private static final int SHOW_RIPPLE_DURATION_MS = 266;
- private static final int MSG_CHECK_RECEIVED_AC3_CAPABILITY_NOTIFICATION = 1;
- private static final long AC3_CHECK_WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(1);
+ private ChannelDataManager mChannelDataManager;
+ private final ChannelDataManager.Listener mChannelListener = new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ mChannelDataManager.removeListener(this);
+ SetupUtils.getInstance(OnboardingActivity.this).markNewChannelsBrowsable();
+ }
- private static final int REQUEST_CODE_SETUP_USB_TUNER = 1;
+ @Override
+ public void onChannelListUpdated() { }
- private Handler mHandler = new OnboardingActivityHandler(this);
- private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
- private Boolean mAc3Supported;
+ @Override
+ public void onChannelBrowsableChanged() { }
+ };
/**
* Returns an intent to start {@link OnboardingActivity}.
@@ -76,72 +73,51 @@ public class OnboardingActivity extends SteppedSetupActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // Register a receiver for HDMI audio plug and wait for the response.
- mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(this,
- new AudioCapabilitiesReceiver.OnAc3PassthroughCapabilityChangeListener() {
- @Override
- public void onAc3PassthroughCapabilityChange(boolean capability) {
- mAudioCapabilitiesReceiver.unregister();
- mAudioCapabilitiesReceiver = null;
- mHandler.removeMessages(MSG_CHECK_RECEIVED_AC3_CAPABILITY_NOTIFICATION);
- mAc3Supported = capability;
- startFirstStep();
- }
- });
- mAudioCapabilitiesReceiver.register();
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_RECEIVED_AC3_CAPABILITY_NOTIFICATION,
- AC3_CHECK_WAIT_TIMEOUT);
- }
-
- @Override
- protected SetupStep onCreateInitialStep() {
- if (mAc3Supported == null) {
- return null;
- }
- if (OnboardingUtils.isFirstRun(this)) {
- return new WelcomeStep(null);
+ // Make the channels of the new inputs which have been setup outside Live TV
+ // browsable.
+ mChannelDataManager = TvApplication.getSingletons(this).getChannelDataManager();
+ if (mChannelDataManager.isDbLoadFinished()) {
+ SetupUtils.getInstance(this).markNewChannelsBrowsable();
+ } else {
+ mChannelDataManager.addListener(mChannelListener);
}
- return new AppOverviewStep(null);
}
@Override
protected void onDestroy() {
- mHandler.removeCallbacksAndMessages(null);
- if (mAudioCapabilitiesReceiver != null) {
- mAudioCapabilitiesReceiver.unregister();
- mAudioCapabilitiesReceiver = null;
- }
+ mChannelDataManager.removeListener(mChannelListener);
super.onDestroy();
}
- void startFirstStep() {
- SoftPreconditions.checkNotNull(mAc3Supported, TAG,
- "AC3 passthrough support check hasn't been completed yet.");
- startInitialStep();
+ @Override
+ protected Fragment onCreateInitialFragment() {
+ return OnboardingUtils.isFirstRunWithCurrentVersion(this) ? new WelcomeFragment()
+ : new SetupSourcesFragment();
}
@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQUEST_CODE_SETUP_USB_TUNER && resultCode == RESULT_OK) {
- SetupUtils.getInstance(this).onTvInputSetupFinished(Utils.getUsbTunerInputId(this),
- null);
- return;
+ protected void onResume() {
+ super.onResume();
+ if (!PermissionUtils.hasAccessAllEpg(this)) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ Toast.makeText(this, R.string.msg_not_supported_device, Toast.LENGTH_LONG).show();
+ finish();
+ } else if (checkSelfPermission(PERMISSION_READ_TV_LISTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{PERMISSION_READ_TV_LISTINGS},
+ PERMISSIONS_REQUEST_READ_TV_LISTINGS);
+ }
}
- super.onActivityResult(requestCode, resultCode, data);
}
- private static class OnboardingActivityHandler extends WeakHandler<OnboardingActivity> {
- OnboardingActivityHandler(OnboardingActivity activity) {
- // Should run on main thread because onAc3SupportChanged will be called on main thread.
- super(Looper.getMainLooper(), activity);
- }
-
- @Override
- protected void handleMessage(Message msg, OnboardingActivity activity) {
- if (msg.what == MSG_CHECK_RECEIVED_AC3_CAPABILITY_NOTIFICATION) {
- activity.mAudioCapabilitiesReceiver.unregister();
- activity.mAudioCapabilitiesReceiver = null;
- activity.startFirstStep();
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_REQUEST_READ_TV_LISTINGS) {
+ if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
+ Toast.makeText(this, R.string.msg_read_tv_listing_permission_denied,
+ Toast.LENGTH_LONG).show();
+ finish();
}
}
}
@@ -155,112 +131,44 @@ public class OnboardingActivity extends SteppedSetupActivity {
finish();
}
- private class WelcomeStep extends SetupStep {
- public WelcomeStep(@Nullable SetupStep previousStep) {
- super(getFragmentManager(), previousStep);
- }
-
- @Override
- public Fragment onCreateFragment() {
- return new WelcomeFragment();
- }
-
- @Override
- public void executeAction(int actionId) {
- switch (actionId) {
- case WelcomeFragment.ACTION_NEXT:
- OnboardingUtils.setFirstRunCompleted(OnboardingActivity.this);
- if (!OnboardingUtils.areChannelsAvailable(OnboardingActivity.this)) {
- startStep(new AppOverviewStep(this), false);
- } else {
- // TODO: Go to the correct step.
- finishActivity();
- }
- break;
+ void showMerchantCollection() {
+ executeActionWithDelay(new Runnable() {
+ @Override
+ public void run() {
+ startActivity(OnboardingUtils.PLAY_STORE_INTENT);
}
- }
+ }, SHOW_RIPPLE_DURATION_MS);
}
- private class AppOverviewStep extends SetupStep {
- private static final String TV_MERCHANT_COLLECTION = "https://play.google.com/store/apps/"
- + "collection/promotion_3001bf9_ATV_livechannels?sticky_source_country=";
-
- public AppOverviewStep(@Nullable SetupStep previousStep) {
- super(getFragmentManager(), previousStep);
- }
-
- @Override
- public Fragment onCreateFragment() {
- Fragment fragment = new AppOverviewFragment();
- Bundle bundle = new Bundle();
- bundle.putBoolean(AppOverviewFragment.KEY_AC3_SUPPORT, mAc3Supported);
- fragment.setArguments(bundle);
- return fragment;
- }
-
- @Override
- public void executeAction(int actionId) {
- switch (actionId) {
- case AppOverviewFragment.ACTION_SETUP_SOURCE: {
- startStep(new SetupSourcesStep(this), true);
- break;
+ @Override
+ protected void executeAction(String category, int actionId) {
+ switch (category) {
+ case WelcomeFragment.ACTION_CATEGORY:
+ switch (actionId) {
+ case WelcomeFragment.ACTION_NEXT:
+ OnboardingUtils.setFirstRunWithCurrentVersionCompleted(
+ OnboardingActivity.this);
+ showFragment(new SetupSourcesFragment(), false);
+ break;
}
- case AppOverviewFragment.ACTION_GET_MORE_CHANNELS:
- startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse(TV_MERCHANT_COLLECTION + Locale.getDefault().getCountry())));
- break;
- case AppOverviewFragment.ACTION_SETUP_USB_TUNER: {
- Context context = OnboardingActivity.this;
- TvInputInfo input = Utils.getUsbTunerInputInfo(context);
- if (input != null) {
- SetupUtils.grantEpgPermission(context,
- input.getServiceInfo().packageName);
- Intent intent = input.createSetupIntent();
- try {
- startActivityForResult(intent, REQUEST_CODE_SETUP_USB_TUNER);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(context, getString(
- R.string.msg_unable_to_start_setup_activity,
- input.loadLabel(context)), Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Can't find activity: " + intent.getComponent(), e);
- break;
+ break;
+ case SetupSourcesFragment.ACTION_CATEGORY:
+ switch (actionId) {
+ case SetupSourcesFragment.ACTION_PLAY_STORE:
+ showMerchantCollection();
+ break;
+ case SetupMultiPaneFragment.ACTION_DONE: {
+ ChannelDataManager manager = TvApplication.getSingletons(
+ OnboardingActivity.this).getChannelDataManager();
+ if (manager.getChannelCount() == 0) {
+ finish();
+ } else {
+ finishActivity();
}
- // TODO: Add transition animation.
- } else {
- // TODO: Implement this.
- Toast.makeText(OnboardingActivity.this, "Not implemented yet.",
- Toast.LENGTH_SHORT).show();
+ break;
}
- break;
}
- }
- }
- }
-
- private class SetupSourcesStep extends SetupStep {
- public SetupSourcesStep(@Nullable SetupStep previousStep) {
- super(getFragmentManager(), previousStep);
- }
-
- @Override
- public Fragment onCreateFragment() {
- return new SetupSourcesFragment();
- }
-
- @Override
- public void executeAction(int actionId) {
- switch (actionId) {
- case SetupSourcesFragment.ACTION_DONE: {
- ChannelDataManager manager = TvApplication.getSingletons(
- OnboardingActivity.this).getChannelDataManager();
- if (manager.getChannelCount() == 0) {
- finish();
- } else {
- finishActivity();
- }
- break;
- }
- }
+ break;
}
}
}
diff --git a/src/com/android/tv/onboarding/PagingIndicator.java b/src/com/android/tv/onboarding/PagingIndicator.java
deleted file mode 100644
index 107b00f0..00000000
--- a/src/com/android/tv/onboarding/PagingIndicator.java
+++ /dev/null
@@ -1,235 +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.onboarding;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.DecelerateInterpolator;
-
-import com.android.tv.R;
-import com.android.tv.util.Utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A page indicator with dots.
- */
-public class PagingIndicator extends View {
- // attribute
- private final int mDotDiameter;
- private final int mDotRadius;
- private final int mDotGap;
- private int[] mDotCenterX;
- private int mDotCenterY;
-
- // state
- private int mPageCount;
- private int mCurrentPage;
- private int mPreviousPage;
-
- // drawing
- private final Paint mUnselectedPaint;
- private final Paint mSelectedPaint;
- private final Paint mUnselectingPaint;
- private final Paint mSelectingPaint;
- private final AnimatorSet mAnimator = new AnimatorSet();
-
- public PagingIndicator(Context context) {
- this(context, null, 0);
- }
-
- public PagingIndicator(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public PagingIndicator(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- Resources res = getResources();
- mDotRadius = res.getDimensionPixelSize(R.dimen.onboarding_dot_radius);
- mDotDiameter = mDotRadius * 2;
- mDotGap = res.getDimensionPixelSize(R.dimen.onboarding_dot_gap);
- mUnselectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- // Deprecated method is used because this code should run on L platform.
- int unselectedColor = Utils.getColor(res, R.color.onboarding_dot_unselected);
- int selectedColor = Utils.getColor(res, R.color.onboarding_dot_selected);
- mUnselectedPaint.setColor(unselectedColor);
- mSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mSelectedPaint.setColor(selectedColor);
- mUnselectingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mSelectingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- // Initialize animations.
- int duration = res.getInteger(R.integer.setup_fragment_transition_duration);
- List<Animator> animators = new ArrayList<>();
- animators.add(createColorAnimator(selectedColor, unselectedColor, duration,
- mUnselectingPaint));
- animators.add(createColorAnimator(unselectedColor, selectedColor, duration,
- mSelectingPaint));
- mAnimator.playTogether(animators);
- }
-
- private Animator createColorAnimator(int fromColor, int toColor, int duration,
- final Paint paint) {
- ValueAnimator animator = ValueAnimator.ofArgb(fromColor, toColor);
- animator.setDuration(duration);
- animator.setInterpolator(new DecelerateInterpolator());
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- invalidate();
- }
- });
- animator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animator) {
- paint.setColor((int) animator.getAnimatedValue());
- invalidate();
- }
- });
- return animator;
- }
-
- /**
- * Sets the page count.
- */
- public void setPageCount(int pages) {
- mPageCount = pages;
- calculateDotPositions();
- setSelectedPage(0);
- }
-
- /**
- * Called when the page has been selected.
- */
- public void onPageSelected(int pageIndex, boolean withAnimation) {
- if (mAnimator.isStarted()) {
- mAnimator.end();
- }
- if (withAnimation) {
- mPreviousPage = mCurrentPage;
- mAnimator.start();
- }
- setSelectedPage(pageIndex);
- }
-
- private void calculateDotPositions() {
- int left = getPaddingLeft();
- int top = getPaddingTop();
- int right = getWidth() - getPaddingRight();
- int requiredWidth = getRequiredWidth();
- int startLeft = left + ((right - left - requiredWidth) / 2) + mDotRadius;
- mDotCenterX = new int[mPageCount];
- for (int i = 0; i < mPageCount; i++) {
- mDotCenterX[i] = startLeft + i * (mDotDiameter + mDotGap);
- }
- mDotCenterY = top + mDotRadius;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int desiredHeight = getDesiredHeight();
- int height;
- switch (MeasureSpec.getMode(heightMeasureSpec)) {
- case MeasureSpec.EXACTLY:
- height = MeasureSpec.getSize(heightMeasureSpec);
- break;
- case MeasureSpec.AT_MOST:
- height = Math.min(desiredHeight, MeasureSpec.getSize(heightMeasureSpec));
- break;
- case MeasureSpec.UNSPECIFIED:
- default:
- height = desiredHeight;
- break;
- }
- int desiredWidth = getDesiredWidth();
- int width;
- switch (MeasureSpec.getMode(widthMeasureSpec)) {
- case MeasureSpec.EXACTLY:
- width = MeasureSpec.getSize(widthMeasureSpec);
- break;
- case MeasureSpec.AT_MOST:
- width = Math.min(desiredWidth, MeasureSpec.getSize(widthMeasureSpec));
- break;
- case MeasureSpec.UNSPECIFIED:
- default:
- width = desiredWidth;
- break;
- }
- setMeasuredDimension(width, height);
- calculateDotPositions();
- }
-
- @Override
- protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
- setMeasuredDimension(width, height);
- calculateDotPositions();
- }
-
- private int getDesiredHeight() {
- return getPaddingTop() + mDotDiameter + getPaddingBottom();
- }
-
- private int getRequiredWidth() {
- return mPageCount * mDotDiameter + (mPageCount - 1) * mDotGap;
- }
-
- private int getDesiredWidth() {
- return getPaddingLeft() + getRequiredWidth() + getPaddingRight();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- drawUnselected(canvas);
- if (mAnimator.isStarted()) {
- drawAnimator(canvas);
- } else {
- drawSelected(canvas);
- }
- }
-
- private void drawUnselected(Canvas canvas) {
- for (int page = 0; page < mPageCount; page++) {
- canvas.drawCircle(mDotCenterX[page], mDotCenterY, mDotRadius, mUnselectedPaint);
- }
- }
-
- private void drawSelected(Canvas canvas) {
- canvas.drawCircle(mDotCenterX[mCurrentPage], mDotCenterY, mDotRadius, mSelectedPaint);
- }
-
- private void drawAnimator(Canvas canvas) {
- canvas.drawCircle(mDotCenterX[mPreviousPage], mDotCenterY, mDotRadius, mUnselectingPaint);
- canvas.drawCircle(mDotCenterX[mCurrentPage], mDotCenterY, mDotRadius, mSelectingPaint);
- }
-
- private void setSelectedPage(int now) {
- if (now == mCurrentPage) {
- return;
- }
- mCurrentPage = now;
- invalidate();
- }
-}
diff --git a/src/com/android/tv/onboarding/SetupSourcesFragment.java b/src/com/android/tv/onboarding/SetupSourcesFragment.java
index ad49dc23..ebf32d00 100644
--- a/src/com/android/tv/onboarding/SetupSourcesFragment.java
+++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java
@@ -20,19 +20,26 @@ import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager.TvInputCallback;
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.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.tv.ApplicationSingletons;
+import com.android.tv.Features;
import com.android.tv.R;
import com.android.tv.SetupPassthroughActivity;
import com.android.tv.TvApplication;
@@ -43,6 +50,7 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.TvInputNewComparator;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
+import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.Collections;
@@ -52,70 +60,187 @@ import java.util.List;
* A fragment for channel source info/setup.
*/
public class SetupSourcesFragment extends SetupMultiPaneFragment {
+ public static final String ACTION_CATEGORY =
+ "com.android.tv.onboarding.SetupSourcesFragment";
+ public static final int ACTION_PLAY_STORE = 1;
+
+ public static final int DEFAULT_THEME = -1;
+
+ private static final String SETUP_TRACKER_LABEL = "Setup fragment";
+
+ private static int sTheme = DEFAULT_THEME;
+
+ private InputSetupRunnable mInputSetupRunnable;
+
+ private ContentFragment mContentFragment;
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- setOnClickAction(view.findViewById(R.id.button_done), ACTION_DONE);
+ LayoutInflater localInflater = inflater;
+ if (sTheme != -1) {
+ ContextThemeWrapper themeWrapper = new ContextThemeWrapper(getActivity(), sTheme);
+ localInflater = inflater.cloneInContext(themeWrapper);
+ }
+ View view = super.onCreateView(localInflater, container, savedInstanceState);
+ TvApplication.getSingletons(getActivity()).getTracker().sendScreenView(SETUP_TRACKER_LABEL);
return view;
}
@Override
+ protected void onEnterTransitionEnd() {
+ if (mContentFragment != null) {
+ mContentFragment.executePendingAction();
+ }
+ }
+
+ @Override
protected SetupGuidedStepFragment onCreateContentFragment() {
- SetupGuidedStepFragment fragment = new ContentFragment(getActivity());
+ mContentFragment = new ContentFragment();
Bundle arguments = new Bundle();
arguments.putBoolean(SetupGuidedStepFragment.KEY_THREE_PANE, true);
- fragment.setArguments(arguments);
- return fragment;
+ mContentFragment.setArguments(arguments);
+ mContentFragment.setParentFragment(this);
+ return mContentFragment;
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
}
- private class ContentFragment extends SetupGuidedStepFragment {
+ /**
+ * Sets the custom theme dynamically.
+ */
+ public static void setTheme(int theme) {
+ sTheme = theme;
+ }
+
+ /**
+ * Call this method to run customized input setup.
+ *
+ * @param runnable runnable to be called when the input setup is necessary.
+ */
+ public void setInputSetupRunnable(InputSetupRunnable runnable) {
+ mInputSetupRunnable = runnable;
+ }
+
+ /**
+ * Interface for the customized input setup.
+ */
+ public interface InputSetupRunnable {
+ /**
+ * Called for the input setup.
+ *
+ * @param input TV input for setup.
+ */
+ void runInputSetup(TvInputInfo input);
+ }
+
+ public static class ContentFragment extends SetupGuidedStepFragment {
private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
- private static final int ACTION_DIVIDER = ACTION_DONE + 1;
- private static final int ACTION_INPUT_START = ACTION_DONE + 2;
+ // ACTION_PLAY_STORE is defined in the outer class.
+ private static final int ACTION_DIVIDER = 2;
+ private static final int ACTION_HEADER = 3;
+ private static final int ACTION_INPUT_START = 4;
+
+ private static final int PENDING_ACTION_NONE = 0;
+ private static final int PENDING_ACTION_INPUT_CHANGED = 1;
+ private static final int PENDING_ACTION_CHANNEL_CHANGED = 2;
- private final TvInputManagerHelper mInputManager;
- private final ChannelDataManager mChannelDataManager;
- private final SetupUtils mSetupUtils;
- private List<TvInputInfo> mInputList;
- private SetupSourcesAdapter mAdapter;
+ private TvInputManagerHelper mInputManager;
+ private ChannelDataManager mChannelDataManager;
+ private SetupUtils mSetupUtils;
+ private List<TvInputInfo> mInputs;
private int mKnownInputStartIndex;
- private boolean mShowDivider;
+ private int mDoneInputStartIndex;
+
+ private SetupSourcesFragment mParentFragment;
+
+ private String mNewlyAddedInputId;
+
+ private int mPendingAction = PENDING_ACTION_NONE;
+
+ private final TvInputCallback mInputCallback = new TvInputCallback() {
+ @Override
+ public void onInputAdded(String inputId) {
+ handleInputChanged();
+ }
+
+ @Override
+ public void onInputRemoved(String inputId) {
+ handleInputChanged();
+ }
+
+ private void handleInputChanged() {
+ // The actions created while enter transition is running will not be included in the
+ // fragment transition.
+ if (mParentFragment.isEnterTransitionRunning()) {
+ mPendingAction = PENDING_ACTION_INPUT_CHANGED;
+ return;
+ }
+ buildInputs();
+ updateActions();
+ }
+ };
+
+ void setParentFragment(SetupSourcesFragment parentFragment) {
+ mParentFragment = parentFragment;
+ }
+
+ private final ChannelDataManager.Listener mChannelDataManagerListener
+ = new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ handleChannelChanged();
+ }
+
+ @Override
+ public void onChannelListUpdated() {
+ handleChannelChanged();
+ }
- ContentFragment(Context context) {
+ @Override
+ public void onChannelBrowsableChanged() {
+ handleChannelChanged();
+ }
+
+ private void handleChannelChanged() {
+ // The actions created while enter transition is running will not be included in the
+ // fragment transition.
+ if (mParentFragment.isEnterTransitionRunning()) {
+ if (mPendingAction != PENDING_ACTION_INPUT_CHANGED) {
+ mPendingAction = PENDING_ACTION_CHANNEL_CHANGED;
+ }
+ return;
+ }
+ updateActions();
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
// TODO: Handle USB TV tuner differently.
+ Context context = getActivity();
ApplicationSingletons app = TvApplication.getSingletons(context);
mInputManager = app.getTvInputManagerHelper();
mChannelDataManager = app.getChannelDataManager();
mSetupUtils = SetupUtils.getInstance(context);
- mInputList = mInputManager.getTvInputInfos(true, true);
- Collections.sort(mInputList, new TvInputNewComparator(mSetupUtils, mInputManager));
- mKnownInputStartIndex = 0;
- for (TvInputInfo input : mInputList) {
- if (mSetupUtils.isNewInput(input.getId())) {
- mSetupUtils.markAsKnownInput(input.getId());
- ++mKnownInputStartIndex;
- }
- }
- mShowDivider = mKnownInputStartIndex != 0 && mKnownInputStartIndex != mInputList.size();
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
+ buildInputs();
+ mInputManager.addCallback(mInputCallback);
+ mChannelDataManager.addListener(mChannelDataManagerListener);
+ super.onCreate(savedInstanceState);
}
- @SuppressWarnings("rawtypes")
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView();
- RecyclerView.Adapter adapter = gridView.getAdapter();
- mAdapter = new SetupSourcesAdapter(adapter);
- gridView.setAdapter(mAdapter);
- return view;
+ public void onDestroy() {
+ super.onDestroy();
+ mChannelDataManager.removeListener(mChannelDataManagerListener);
+ mInputManager.removeCallback(mInputCallback);
}
+ @NonNull
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
String title = getString(R.string.setup_sources_text);
@@ -124,22 +249,42 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
}
@Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- createActionsInternal(actions);
- if (!mChannelDataManager.isDbLoadFinished()) {
- mChannelDataManager.addListener(new ChannelDataManager.Listener() {
- @Override
- public void onLoadFinished() {
- mChannelDataManager.removeListener(this);
- updateActions();
- }
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new SetupSourceGuidedActionsStylist();
+ }
- @Override
- public void onChannelListUpdated() { }
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions,
+ Bundle savedInstanceState) {
+ createActionsInternal(actions);
+ }
- @Override
- public void onChannelBrowsableChanged() { }
- });
+ private void buildInputs() {
+ List<TvInputInfo> oldInputs = mInputs;
+ mInputs = mInputManager.getTvInputInfos(true, true);
+ // Get newly installed input ID.
+ if (oldInputs != null) {
+ List<TvInputInfo> newList = new ArrayList<>(mInputs);
+ for (TvInputInfo input : oldInputs) {
+ newList.remove(input);
+ }
+ if (newList.size() > 0 && mSetupUtils.isNewInput(newList.get(0).getId())) {
+ mNewlyAddedInputId = newList.get(0).getId();
+ } else {
+ mNewlyAddedInputId = null;
+ }
+ }
+ Collections.sort(mInputs, new TvInputNewComparator(mSetupUtils, mInputManager));
+ mKnownInputStartIndex = 0;
+ mDoneInputStartIndex = 0;
+ for (TvInputInfo input : mInputs) {
+ if (mSetupUtils.isNewInput(input.getId())) {
+ mSetupUtils.markAsKnownInput(input.getId());
+ ++mKnownInputStartIndex;
+ }
+ if (!mSetupUtils.isSetupDone(input.getId())) {
+ ++mDoneInputStartIndex;
+ }
}
}
@@ -147,39 +292,84 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
List<GuidedAction> actions = new ArrayList<>();
createActionsInternal(actions);
setActions(actions);
- mAdapter.notifyDataSetChanged();
}
private void createActionsInternal(List<GuidedAction> actions) {
- for (int i = 0; i < mInputList.size(); ++i) {
- if (mShowDivider && i == mKnownInputStartIndex) {
- actions.add(new GuidedAction.Builder().id(ACTION_DIVIDER).title(null)
- .description(null).build());
+ int newPosition = -1;
+ int position = 0;
+ if (mDoneInputStartIndex > 0) {
+ // Need a "New" category
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_HEADER)
+ .title(null).description(getString(R.string.setup_category_new))
+ .focusable(false).build());
+ }
+ for (int i = 0; i < mInputs.size(); ++i) {
+ if (i == mDoneInputStartIndex) {
+ ++position;
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_HEADER)
+ .title(null).description(getString(R.string.setup_category_done))
+ .focusable(false).build());
}
- TvInputInfo input = mInputList.get(i);
+ TvInputInfo input = mInputs.get(i);
+ String inputId = input.getId();
String description;
- int channelCount = mChannelDataManager.getChannelCountForInput(input.getId());
- if (mSetupUtils.isSetupDone(input.getId())) {
+ int channelCount = mChannelDataManager.getChannelCountForInput(inputId);
+ if (mSetupUtils.isSetupDone(inputId) || channelCount > 0) {
if (channelCount == 0) {
- description = getResources().getString(R.string.setup_input_no_channels);
+ description = getString(R.string.setup_input_no_channels);
} else {
description = getResources().getQuantityString(
R.plurals.setup_input_channels, channelCount, channelCount);
}
} else if (i >= mKnownInputStartIndex) {
- description = getResources().getString(R.string.channel_description_setup_now);
+ description = getString(R.string.setup_input_setup_now);
} else {
- description = getResources().getString(R.string.setup_input_new);
+ description = getString(R.string.setup_input_new);
}
- actions.add(new GuidedAction.Builder().id(ACTION_INPUT_START + i)
+ ++position;
+ if (input.getId().equals(mNewlyAddedInputId)) {
+ newPosition = position;
+ }
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_INPUT_START + i)
.title(input.loadLabel(getActivity()).toString()).description(description)
.build());
}
+ if (Features.ONBOARDING_PLAY_STORE.isEnabled(getActivity())) {
+ if (mInputs.size() > 0) {
+ // Divider
+ ++position;
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_DIVIDER)
+ .title(null).description(null).focusable(false).build());
+ }
+ // Play store action
+ ++position;
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_PLAY_STORE)
+ .title(getString(R.string.setup_play_store_action_title))
+ .description(getString(R.string.setup_play_store_action_description))
+ .icon(R.drawable.ic_playstore).build());
+ }
+ if (newPosition != -1) {
+ VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView();
+ gridView.setSelectedPosition(newPosition);
+ }
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
- TvInputInfo input = mInputList.get((int) action.getId() - ACTION_INPUT_START);
+ if (action.getId() == ACTION_PLAY_STORE) {
+ mParentFragment.onActionClick(ACTION_CATEGORY, (int) action.getId());
+ return;
+ }
+ TvInputInfo input = mInputs.get((int) action.getId() - ACTION_INPUT_START);
+ if (mParentFragment.mInputSetupRunnable != null) {
+ mParentFragment.mInputSetupRunnable.runInputSetup(input);
+ return;
+ }
Intent intent = TvCommonUtils.createSetupIntent(input);
if (intent == null) {
Toast.makeText(getActivity(), R.string.msg_no_setup_activity, Toast.LENGTH_SHORT)
@@ -190,14 +380,13 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
// should go through Live channels SetupPassthroughActivity.
intent.setComponent(new ComponentName(getActivity(), SetupPassthroughActivity.class));
try {
- // Now we know that the user intends to set up this input. Grant permission for writing
- // EPG data.
+ // Now we know that the user intends to set up this input. Grant permission for
+ // writing EPG data.
SetupUtils.grantEpgPermission(getActivity(), input.getServiceInfo().packageName);
startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), getString(R.string.msg_unable_to_start_setup_activity,
input.loadLabel(getActivity())), Toast.LENGTH_SHORT).show();
- return;
}
}
@@ -206,67 +395,78 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
updateActions();
}
- @SuppressWarnings("rawtypes")
- private class SetupSourcesAdapter extends RecyclerView.Adapter {
- private static final int VIEW_TYPE_INPUT = 1;
- private static final int VIEW_TYPE_DIVIDER = 2;
-
- private final RecyclerView.Adapter mGuidedActionAdapter;
+ @Override
+ public int onProvideTheme() {
+ return sTheme == DEFAULT_THEME ? super.onProvideTheme() : sTheme;
+ }
- SetupSourcesAdapter(RecyclerView.Adapter adapter) {
- mGuidedActionAdapter = adapter;
+ void executePendingAction() {
+ switch (mPendingAction) {
+ case PENDING_ACTION_INPUT_CHANGED:
+ buildInputs();
+ // Fall through
+ case PENDING_ACTION_CHANNEL_CHANGED:
+ updateActions();
+ break;
}
+ mPendingAction = PENDING_ACTION_NONE;
+ }
+
+ private class SetupSourceGuidedActionsStylist extends GuidedActionsStylist {
+ private static final int VIEW_TYPE_DIVIDER = 1;
+
+ private static final float ALPHA_CATEGORY = 1.0f;
+ private static final float ALPHA_INPUT_DESCRIPTION = 0.5f;
@Override
- public int getItemViewType(int position) {
- if (mShowDivider && position == mKnownInputStartIndex) {
+ public int getItemViewType(GuidedAction action) {
+ if (action.getId() == ACTION_DIVIDER) {
return VIEW_TYPE_DIVIDER;
}
- return VIEW_TYPE_INPUT;
+ return super.getItemViewType(action);
}
@Override
- public int getItemCount() {
- if (mInputList == null) {
- return 0;
+ public int onProvideItemLayoutId(int viewType) {
+ if (viewType == VIEW_TYPE_DIVIDER) {
+ return R.layout.onboarding_item_divider;
}
- return mInputList.size() + (mShowDivider ? 1 : 0);
+ return super.onProvideItemLayoutId(viewType);
}
@Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- if (viewType == VIEW_TYPE_INPUT) {
- return mGuidedActionAdapter.onCreateViewHolder(parent, viewType);
+ public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
+ super.onBindViewHolder(vh, action);
+ TextView descriptionView = vh.getDescriptionView();
+ if (descriptionView != null) {
+ if (action.getId() == ACTION_HEADER) {
+ descriptionView.setAlpha(ALPHA_CATEGORY);
+ descriptionView.setTextColor(Utils.getColor(getResources(),
+ R.color.setup_category));
+ descriptionView.setTypeface(Typeface.create(
+ getString(R.string.condensed_font), 0));
+ } else {
+ descriptionView.setAlpha(ALPHA_INPUT_DESCRIPTION);
+ descriptionView.setTextColor(Utils.getColor(getResources(),
+ R.color.common_setup_input_description));
+ descriptionView.setTypeface(Typeface.create(getString(R.string.font), 0));
+ }
}
- View itemView = LayoutInflater.from(parent.getContext()).inflate(
- R.layout.onboarding_item_divider, parent, false);
- return new MyViewHolder(itemView);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void onBindViewHolder(ViewHolder viewHolder, int position) {
- if (mShowDivider && position == mKnownInputStartIndex) {
- return;
+ // Workaround for b/26473407.
+ ImageView iconView = vh.getIconView();
+ if (iconView != null) {
+ Drawable icon = action.getIcon();
+ if (icon != null) {
+ // setImageDrawable resets the drawable's level unless we set the view level
+ // first.
+ iconView.setImageLevel(icon.getLevel());
+ iconView.setImageDrawable(icon);
+ iconView.setVisibility(View.VISIBLE);
+ } else {
+ iconView.setVisibility(View.GONE);
+ }
}
- mGuidedActionAdapter.onBindViewHolder(viewHolder, position);
- }
-
- @Override
- public void onAttachedToRecyclerView(RecyclerView recyclerView) {
- mGuidedActionAdapter.onAttachedToRecyclerView(recyclerView);
- }
-
- @Override
- public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
- mGuidedActionAdapter.onDetachedFromRecyclerView(recyclerView);
}
}
}
-
- private static class MyViewHolder extends RecyclerView.ViewHolder {
- public MyViewHolder(View itemView) {
- super(itemView);
- }
- }
}
diff --git a/src/com/android/tv/onboarding/WelcomeFragment.java b/src/com/android/tv/onboarding/WelcomeFragment.java
index f8cd8ee7..ed85df68 100644
--- a/src/com/android/tv/onboarding/WelcomeFragment.java
+++ b/src/com/android/tv/onboarding/WelcomeFragment.java
@@ -18,41 +18,41 @@ package com.android.tv.onboarding;
import android.animation.Animator;
import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.os.Bundle;
-import android.transition.TransitionValues;
+import android.support.annotation.Nullable;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.android.tv.R;
-import com.android.tv.common.ui.setup.SetupFragment;
-import com.android.tv.common.ui.setup.animation.CustomTransition;
-import com.android.tv.common.ui.setup.animation.CustomTransitionProvider;
+import com.android.tv.common.ui.setup.SetupActionHelper;
import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
+import com.android.tv.common.ui.setup.leanback.OnboardingFragment;
+
+import java.util.ArrayList;
+import java.util.List;
/**
- * A fragment for the onboarding screen.
+ * A fragment for the onboarding welcome screen.
*/
-public class WelcomeFragment extends SetupFragment {
+public class WelcomeFragment extends OnboardingFragment {
+ public static final String ACTION_CATEGORY = "comgoogle.android.tv.onboarding.WelcomeFragment";
public static final int ACTION_NEXT = 1;
- private static final long LOGO_SPLASH_PAUSE_DURATION_MS = 333;
- private static final long LOGO_SPLASH_DURATION_MS = 1000;
- private static final long START_DELAY_PAGE_INDICATOR_MS = LOGO_SPLASH_DURATION_MS;
- private static final long START_DELAY_TITLE_MS = LOGO_SPLASH_DURATION_MS + 33;
- private static final long START_DELAY_DESCRIPTION_MS = LOGO_SPLASH_DURATION_MS + 33;
- private static final long START_DELAY_CLOUD_MS = LOGO_SPLASH_DURATION_MS + 33;
- private static final long START_DELAY_TV_MS = LOGO_SPLASH_DURATION_MS + 567;
- private static final long START_DELAY_TV_CONTENTS_MS = 266;
- private static final long START_DELAY_SHADOW_MS = LOGO_SPLASH_DURATION_MS + 567;
+ private static final long START_DELAY_CLOUD_MS = 33;
+ private static final long START_DELAY_TV_MS = 567;
+ private static final long START_DELAY_TV_CONTENTS_MS = 833;
+ private static final long START_DELAY_SHADOW_MS = 567;
- private static final long WELCOME_PAGE_TRANSITION_DURATION_MS = 417;
+ private static final long VIDEO_FADE_OUT_DURATION_MS = 333;
private static final long BLUE_SCREEN_HOLD_DURATION_MS = 1500;
+ // TODO: Use animator list xml.
private static final int[] TV_FRAMES_1_START = {
R.drawable.tv_1a_01,
R.drawable.tv_1a_02,
@@ -73,8 +73,7 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_1a_17,
R.drawable.tv_1a_18,
R.drawable.tv_1a_19,
- R.drawable.tv_1a_20,
- 0
+ R.drawable.tv_1a_20
};
private static final int[] TV_FRAMES_1_END = {
@@ -88,11 +87,238 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_1b_08,
R.drawable.tv_1b_09,
R.drawable.tv_1b_10,
- R.drawable.tv_1b_11,
- 0
+ R.drawable.tv_1b_11
+ };
+
+ private static final int[] TV_FRAMES_2_START = {
+ R.drawable.tv_5a_0,
+ R.drawable.tv_5a_1,
+ R.drawable.tv_5a_2,
+ R.drawable.tv_5a_3,
+ R.drawable.tv_5a_4,
+ R.drawable.tv_5a_5,
+ R.drawable.tv_5a_6,
+ R.drawable.tv_5a_7,
+ R.drawable.tv_5a_8,
+ R.drawable.tv_5a_9,
+ R.drawable.tv_5a_10,
+ R.drawable.tv_5a_11,
+ R.drawable.tv_5a_12,
+ R.drawable.tv_5a_13,
+ R.drawable.tv_5a_14,
+ R.drawable.tv_5a_15,
+ R.drawable.tv_5a_16,
+ R.drawable.tv_5a_17,
+ R.drawable.tv_5a_18,
+ R.drawable.tv_5a_19,
+ R.drawable.tv_5a_20,
+ R.drawable.tv_5a_21,
+ R.drawable.tv_5a_22,
+ R.drawable.tv_5a_23,
+ R.drawable.tv_5a_24,
+ R.drawable.tv_5a_25,
+ R.drawable.tv_5a_26,
+ R.drawable.tv_5a_27,
+ R.drawable.tv_5a_28,
+ R.drawable.tv_5a_29,
+ R.drawable.tv_5a_30,
+ R.drawable.tv_5a_31,
+ R.drawable.tv_5a_32,
+ R.drawable.tv_5a_33,
+ R.drawable.tv_5a_34,
+ R.drawable.tv_5a_35,
+ R.drawable.tv_5a_36,
+ R.drawable.tv_5a_37,
+ R.drawable.tv_5a_38,
+ R.drawable.tv_5a_39,
+ R.drawable.tv_5a_40,
+ R.drawable.tv_5a_41,
+ R.drawable.tv_5a_42,
+ R.drawable.tv_5a_43,
+ R.drawable.tv_5a_44,
+ R.drawable.tv_5a_45,
+ R.drawable.tv_5a_46,
+ R.drawable.tv_5a_47,
+ R.drawable.tv_5a_48,
+ R.drawable.tv_5a_49,
+ R.drawable.tv_5a_50,
+ R.drawable.tv_5a_51,
+ R.drawable.tv_5a_52,
+ R.drawable.tv_5a_53,
+ R.drawable.tv_5a_54,
+ R.drawable.tv_5a_55,
+ R.drawable.tv_5a_56,
+ R.drawable.tv_5a_57,
+ R.drawable.tv_5a_58,
+ R.drawable.tv_5a_59,
+ R.drawable.tv_5a_60,
+ R.drawable.tv_5a_61,
+ R.drawable.tv_5a_62,
+ R.drawable.tv_5a_63,
+ R.drawable.tv_5a_64,
+ R.drawable.tv_5a_65,
+ R.drawable.tv_5a_66,
+ R.drawable.tv_5a_67,
+ R.drawable.tv_5a_68,
+ R.drawable.tv_5a_69,
+ R.drawable.tv_5a_70,
+ R.drawable.tv_5a_71,
+ R.drawable.tv_5a_72,
+ R.drawable.tv_5a_73,
+ R.drawable.tv_5a_74,
+ R.drawable.tv_5a_75,
+ R.drawable.tv_5a_76,
+ R.drawable.tv_5a_77,
+ R.drawable.tv_5a_78,
+ R.drawable.tv_5a_79,
+ R.drawable.tv_5a_80,
+ R.drawable.tv_5a_81,
+ R.drawable.tv_5a_82,
+ R.drawable.tv_5a_83,
+ R.drawable.tv_5a_84,
+ R.drawable.tv_5a_85,
+ R.drawable.tv_5a_86,
+ R.drawable.tv_5a_87,
+ R.drawable.tv_5a_88,
+ R.drawable.tv_5a_89,
+ R.drawable.tv_5a_90,
+ R.drawable.tv_5a_91,
+ R.drawable.tv_5a_92,
+ R.drawable.tv_5a_93,
+ R.drawable.tv_5a_94,
+ R.drawable.tv_5a_95,
+ R.drawable.tv_5a_96,
+ R.drawable.tv_5a_97,
+ R.drawable.tv_5a_98,
+ R.drawable.tv_5a_99,
+ R.drawable.tv_5a_100,
+ R.drawable.tv_5a_101,
+ R.drawable.tv_5a_102,
+ R.drawable.tv_5a_103,
+ R.drawable.tv_5a_104,
+ R.drawable.tv_5a_105,
+ R.drawable.tv_5a_106,
+ R.drawable.tv_5a_107,
+ R.drawable.tv_5a_108,
+ R.drawable.tv_5a_109,
+ R.drawable.tv_5a_110,
+ R.drawable.tv_5a_111,
+ R.drawable.tv_5a_112,
+ R.drawable.tv_5a_113,
+ R.drawable.tv_5a_114,
+ R.drawable.tv_5a_115,
+ R.drawable.tv_5a_116,
+ R.drawable.tv_5a_117,
+ R.drawable.tv_5a_118,
+ R.drawable.tv_5a_119,
+ R.drawable.tv_5a_120,
+ R.drawable.tv_5a_121,
+ R.drawable.tv_5a_122,
+ R.drawable.tv_5a_123,
+ R.drawable.tv_5a_124,
+ R.drawable.tv_5a_125,
+ R.drawable.tv_5a_126,
+ R.drawable.tv_5a_127,
+ R.drawable.tv_5a_128,
+ R.drawable.tv_5a_129,
+ R.drawable.tv_5a_130,
+ R.drawable.tv_5a_131,
+ R.drawable.tv_5a_132,
+ R.drawable.tv_5a_133,
+ R.drawable.tv_5a_134,
+ R.drawable.tv_5a_135,
+ R.drawable.tv_5a_136,
+ R.drawable.tv_5a_137,
+ R.drawable.tv_5a_138,
+ R.drawable.tv_5a_139,
+ R.drawable.tv_5a_140,
+ R.drawable.tv_5a_141,
+ R.drawable.tv_5a_142,
+ R.drawable.tv_5a_143,
+ R.drawable.tv_5a_144,
+ R.drawable.tv_5a_145,
+ R.drawable.tv_5a_146,
+ R.drawable.tv_5a_147,
+ R.drawable.tv_5a_148,
+ R.drawable.tv_5a_149,
+ R.drawable.tv_5a_150,
+ R.drawable.tv_5a_151,
+ R.drawable.tv_5a_152,
+ R.drawable.tv_5a_153,
+ R.drawable.tv_5a_154,
+ R.drawable.tv_5a_155,
+ R.drawable.tv_5a_156,
+ R.drawable.tv_5a_157,
+ R.drawable.tv_5a_158,
+ R.drawable.tv_5a_159,
+ R.drawable.tv_5a_160,
+ R.drawable.tv_5a_161,
+ R.drawable.tv_5a_162,
+ R.drawable.tv_5a_163,
+ R.drawable.tv_5a_164,
+ R.drawable.tv_5a_165,
+ R.drawable.tv_5a_166,
+ R.drawable.tv_5a_167,
+ R.drawable.tv_5a_168,
+ R.drawable.tv_5a_169,
+ R.drawable.tv_5a_170,
+ R.drawable.tv_5a_171,
+ R.drawable.tv_5a_172,
+ R.drawable.tv_5a_173,
+ R.drawable.tv_5a_174,
+ R.drawable.tv_5a_175,
+ R.drawable.tv_5a_176,
+ R.drawable.tv_5a_177,
+ R.drawable.tv_5a_178,
+ R.drawable.tv_5a_179,
+ R.drawable.tv_5a_180,
+ R.drawable.tv_5a_181,
+ R.drawable.tv_5a_182,
+ R.drawable.tv_5a_183,
+ R.drawable.tv_5a_184,
+ R.drawable.tv_5a_185,
+ R.drawable.tv_5a_186,
+ R.drawable.tv_5a_187,
+ R.drawable.tv_5a_188,
+ R.drawable.tv_5a_189,
+ R.drawable.tv_5a_190,
+ R.drawable.tv_5a_191,
+ R.drawable.tv_5a_192,
+ R.drawable.tv_5a_193,
+ R.drawable.tv_5a_194,
+ R.drawable.tv_5a_195,
+ R.drawable.tv_5a_196,
+ R.drawable.tv_5a_197,
+ R.drawable.tv_5a_198,
+ R.drawable.tv_5a_199,
+ R.drawable.tv_5a_200,
+ R.drawable.tv_5a_201,
+ R.drawable.tv_5a_202,
+ R.drawable.tv_5a_203,
+ R.drawable.tv_5a_204,
+ R.drawable.tv_5a_205,
+ R.drawable.tv_5a_206,
+ R.drawable.tv_5a_207,
+ R.drawable.tv_5a_208,
+ R.drawable.tv_5a_209,
+ R.drawable.tv_5a_210,
+ R.drawable.tv_5a_211,
+ R.drawable.tv_5a_212,
+ R.drawable.tv_5a_213,
+ R.drawable.tv_5a_214,
+ R.drawable.tv_5a_215,
+ R.drawable.tv_5a_216,
+ R.drawable.tv_5a_217,
+ R.drawable.tv_5a_218,
+ R.drawable.tv_5a_219,
+ R.drawable.tv_5a_220,
+ R.drawable.tv_5a_221,
+ R.drawable.tv_5a_222,
+ R.drawable.tv_5a_223,
+ R.drawable.tv_5a_224
};
- private static final int[] TV_FRAMES_2_BLUE_ARROW = {
+ private static final int[] TV_FRAMES_3_BLUE_ARROW = {
R.drawable.arrow_blue_00,
R.drawable.arrow_blue_01,
R.drawable.arrow_blue_02,
@@ -153,11 +379,10 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.arrow_blue_57,
R.drawable.arrow_blue_58,
R.drawable.arrow_blue_59,
- R.drawable.arrow_blue_60,
- 0
+ R.drawable.arrow_blue_60
};
- private static final int[] TV_FRAMES_2_BLUE_START = {
+ private static final int[] TV_FRAMES_3_BLUE_START = {
R.drawable.tv_2a_01,
R.drawable.tv_2a_02,
R.drawable.tv_2a_03,
@@ -176,11 +401,10 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_2a_16,
R.drawable.tv_2a_17,
R.drawable.tv_2a_18,
- R.drawable.tv_2a_19,
- 0
+ R.drawable.tv_2a_19
};
- private static final int[] TV_FRAMES_2_BLUE_END = {
+ private static final int[] TV_FRAMES_3_BLUE_END = {
R.drawable.tv_2b_01,
R.drawable.tv_2b_02,
R.drawable.tv_2b_03,
@@ -199,11 +423,10 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_2b_16,
R.drawable.tv_2b_17,
R.drawable.tv_2b_18,
- R.drawable.tv_2b_19,
- 0
+ R.drawable.tv_2b_19
};
- private static final int[] TV_FRAMES_2_ORANGE_ARROW = {
+ private static final int[] TV_FRAMES_3_ORANGE_ARROW = {
R.drawable.arrow_orange_180,
R.drawable.arrow_orange_181,
R.drawable.arrow_orange_182,
@@ -264,11 +487,10 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.arrow_orange_237,
R.drawable.arrow_orange_238,
R.drawable.arrow_orange_239,
- R.drawable.arrow_orange_240,
- 0
+ R.drawable.arrow_orange_240
};
- private static final int[] TV_FRAMES_2_ORANGE_START = {
+ private static final int[] TV_FRAMES_3_ORANGE_START = {
R.drawable.tv_2c_01,
R.drawable.tv_2c_02,
R.drawable.tv_2c_03,
@@ -284,11 +506,10 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_2c_13,
R.drawable.tv_2c_14,
R.drawable.tv_2c_15,
- R.drawable.tv_2c_16,
- 0
+ R.drawable.tv_2c_16
};
- private static final int[] TV_FRAMES_3_START = {
+ private static final int[] TV_FRAMES_4_START = {
R.drawable.tv_3a_01,
R.drawable.tv_3a_02,
R.drawable.tv_3a_03,
@@ -349,439 +570,198 @@ public class WelcomeFragment extends SetupFragment {
R.drawable.tv_3b_115,
R.drawable.tv_3b_116,
R.drawable.tv_3b_117,
- R.drawable.tv_3b_118,
- 0
- };
-
- private static final int[] TV_FRAMES_4_START = {
- R.drawable.tv_4a_15,
- R.drawable.tv_4a_16,
- R.drawable.tv_4a_17,
- R.drawable.tv_4a_18,
- R.drawable.tv_4a_19,
- R.drawable.tv_4a_20,
- R.drawable.tv_4a_21,
- R.drawable.tv_4a_22,
- R.drawable.tv_4a_23,
- R.drawable.tv_4a_24,
- R.drawable.tv_4a_25,
- R.drawable.tv_4a_26,
- R.drawable.tv_4a_27,
- R.drawable.tv_4a_28,
- R.drawable.tv_4a_29,
- R.drawable.tv_4a_30,
- R.drawable.tv_4a_31,
- R.drawable.tv_4a_32,
- R.drawable.tv_4a_33,
- R.drawable.tv_4a_34,
- R.drawable.tv_4a_35,
- R.drawable.tv_4a_36,
- R.drawable.tv_4a_37,
- R.drawable.tv_4a_38,
- R.drawable.tv_4a_39,
- R.drawable.tv_4a_40,
- R.drawable.tv_4a_41,
- R.drawable.tv_4a_42,
- R.drawable.tv_4a_43,
- R.drawable.tv_4a_44,
- R.drawable.tv_4a_45,
- R.drawable.tv_4a_46,
- R.drawable.tv_4a_47,
- R.drawable.tv_4a_48,
- R.drawable.tv_4a_49,
- R.drawable.tv_4a_50,
- R.drawable.tv_4a_51,
- R.drawable.tv_4a_52,
- R.drawable.tv_4a_53,
- R.drawable.tv_4a_54,
- R.drawable.tv_4a_55,
- R.drawable.tv_4a_56,
- R.drawable.tv_4a_57,
- R.drawable.tv_4a_58,
- R.drawable.tv_4a_59,
- R.drawable.tv_4a_60,
- R.drawable.tv_4a_61,
- R.drawable.tv_4a_62,
- R.drawable.tv_4a_63,
- R.drawable.tv_4a_64,
- R.drawable.tv_4a_65,
- R.drawable.tv_4a_66,
- R.drawable.tv_4a_67,
- R.drawable.tv_4a_68,
- R.drawable.tv_4a_69,
- R.drawable.tv_4a_70,
- R.drawable.tv_4a_71,
- R.drawable.tv_4a_72,
- R.drawable.tv_4a_73,
- R.drawable.tv_4a_74,
- R.drawable.tv_4a_75,
- R.drawable.tv_4a_76,
- R.drawable.tv_4a_77,
- R.drawable.tv_4a_78,
- R.drawable.tv_4a_79,
- R.drawable.tv_4a_80,
- R.drawable.tv_4a_81,
- R.drawable.tv_4a_82,
- R.drawable.tv_4a_83,
- R.drawable.tv_4a_84,
- R.drawable.tv_4a_85,
- R.drawable.tv_4a_86,
- R.drawable.tv_4a_87,
- R.drawable.tv_4a_88,
- R.drawable.tv_4a_89,
- R.drawable.tv_4a_90,
- R.drawable.tv_4a_91,
- R.drawable.tv_4a_92,
- R.drawable.tv_4a_93,
- R.drawable.tv_4a_94,
- R.drawable.tv_4a_95,
- R.drawable.tv_4a_96,
- R.drawable.tv_4a_97,
- R.drawable.tv_4a_98,
- R.drawable.tv_4a_99,
- R.drawable.tv_4a_100,
- R.drawable.tv_4a_101,
- R.drawable.tv_4a_102,
- R.drawable.tv_4a_103,
- R.drawable.tv_4a_104,
- R.drawable.tv_4a_105,
- R.drawable.tv_4a_106,
- R.drawable.tv_4a_107,
- R.drawable.tv_4a_108,
- R.drawable.tv_4a_109,
- R.drawable.tv_4a_110,
- R.drawable.tv_4a_111,
- R.drawable.tv_4a_112,
- R.drawable.tv_4a_113,
- R.drawable.tv_4a_114,
- R.drawable.tv_4a_115,
- R.drawable.tv_4a_116,
- R.drawable.tv_4a_117,
- R.drawable.tv_4a_118,
- R.drawable.tv_4a_119,
- R.drawable.tv_4a_120,
- R.drawable.tv_4a_121,
- R.drawable.tv_4a_122,
- R.drawable.tv_4a_123,
- R.drawable.tv_4a_124,
- R.drawable.tv_4a_125,
- R.drawable.tv_4a_126,
- R.drawable.tv_4a_127,
- R.drawable.tv_4a_128,
- R.drawable.tv_4a_129,
- R.drawable.tv_4a_130,
- R.drawable.tv_4a_131,
- R.drawable.tv_4a_132,
- R.drawable.tv_4a_133,
- R.drawable.tv_4a_134,
- R.drawable.tv_4a_135,
- R.drawable.tv_4a_136,
- R.drawable.tv_4a_137,
- R.drawable.tv_4a_138,
- R.drawable.tv_4a_139,
- R.drawable.tv_4a_140,
- R.drawable.tv_4a_141,
- R.drawable.tv_4a_142,
- R.drawable.tv_4a_143,
- R.drawable.tv_4a_144,
- R.drawable.tv_4a_145,
- R.drawable.tv_4a_146,
- R.drawable.tv_4a_147,
- R.drawable.tv_4a_148,
- R.drawable.tv_4a_149,
- R.drawable.tv_4a_150,
- R.drawable.tv_4a_151,
- R.drawable.tv_4a_152,
- R.drawable.tv_4a_153,
- R.drawable.tv_4a_154,
- R.drawable.tv_4a_155,
- R.drawable.tv_4a_156,
- R.drawable.tv_4a_157,
- R.drawable.tv_4a_158,
- R.drawable.tv_4a_159,
- R.drawable.tv_4a_160,
- R.drawable.tv_4a_161,
- R.drawable.tv_4a_162,
- R.drawable.tv_4a_163,
- R.drawable.tv_4a_164,
- R.drawable.tv_4a_165,
- R.drawable.tv_4a_166,
- R.drawable.tv_4a_167,
- R.drawable.tv_4a_168,
- R.drawable.tv_4a_169,
- R.drawable.tv_4a_170,
- R.drawable.tv_4a_171,
- R.drawable.tv_4a_172,
- R.drawable.tv_4a_173,
- R.drawable.tv_4a_174,
- R.drawable.tv_4a_175,
- R.drawable.tv_4a_176,
- R.drawable.tv_4a_177,
- R.drawable.tv_4a_178,
- R.drawable.tv_4a_179,
- R.drawable.tv_4a_180,
- R.drawable.tv_4a_181,
- R.drawable.tv_4a_182,
- R.drawable.tv_4a_183,
- R.drawable.tv_4a_184,
- R.drawable.tv_4a_185,
- R.drawable.tv_4a_186,
- R.drawable.tv_4a_187,
- R.drawable.tv_4a_188,
- R.drawable.tv_4a_189,
- R.drawable.tv_4a_190,
- R.drawable.tv_4a_191,
- R.drawable.tv_4a_192,
- R.drawable.tv_4a_193,
- R.drawable.tv_4a_194,
- R.drawable.tv_4a_195,
- R.drawable.tv_4a_196,
- R.drawable.tv_4a_197,
- R.drawable.tv_4a_198,
- R.drawable.tv_4a_199,
- R.drawable.tv_4a_200,
- R.drawable.tv_4a_201,
- R.drawable.tv_4a_202,
- R.drawable.tv_4a_203,
- R.drawable.tv_4a_204,
- R.drawable.tv_4a_205,
- R.drawable.tv_4a_206,
- R.drawable.tv_4a_207,
- R.drawable.tv_4a_208,
- R.drawable.tv_4a_209,
- R.drawable.tv_4a_210,
- R.drawable.tv_4a_211,
- R.drawable.tv_4a_212,
- R.drawable.tv_4a_213,
- R.drawable.tv_4a_214,
- R.drawable.tv_4a_215,
- R.drawable.tv_4a_216,
- R.drawable.tv_4a_217,
- R.drawable.tv_4a_218,
- R.drawable.tv_4a_219,
- R.drawable.tv_4a_220,
- R.drawable.tv_4a_221,
- R.drawable.tv_4a_222,
- R.drawable.tv_4a_223,
- R.drawable.tv_4a_224,
- R.drawable.tv_4a_225,
- R.drawable.tv_4a_226,
- R.drawable.tv_4a_227,
- R.drawable.tv_4a_228,
- R.drawable.tv_4a_229,
- R.drawable.tv_4a_230,
- R.drawable.tv_4a_231,
- R.drawable.tv_4a_232,
- R.drawable.tv_4a_233,
- R.drawable.tv_4a_234,
- R.drawable.tv_4a_235,
- R.drawable.tv_4a_236,
- R.drawable.tv_4a_237,
- R.drawable.tv_4a_238,
- R.drawable.tv_4a_239,
- 0
+ R.drawable.tv_3b_118
};
- private int mNumPages;
private String[] mPageTitles;
private String[] mPageDescriptions;
- private int mCurrentPageIndex;
- private int mPageTransitionDistance;
private ImageView mTvContentView;
- private PagingIndicator mPageIndicator;
private ImageView mArrowView;
- private View mLogoView;
private Animator mAnimator;
+ private boolean mNeedToEndAnimator;
public WelcomeFragment() {
- enableFragmentTransition(FRAGMENT_EXIT_TRANSITION);
- setEnterTransition(new CustomTransition(new CustomTransitionProvider() {
- @Override
- public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
- TransitionValues endValues) {
- Animator animator = null;
- switch (endValues.view.getId()) {
- case R.id.logo: {
- Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_logo_enter);
- Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_logo_exit);
- outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS);
- animator = new AnimatorSet();
- ((AnimatorSet) animator).playSequentially(inAnimator, outAnimator);
- animator.setTarget(view);
- break;
- }
- case R.id.page_indicator:
- view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_page_indicator_enter);
- animator.setStartDelay(START_DELAY_PAGE_INDICATOR_MS);
- animator.setTarget(view);
- break;
- case R.id.title:
- view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_title_enter);
- animator.setStartDelay(START_DELAY_TITLE_MS);
- animator.setTarget(view);
- break;
- case R.id.description:
- view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_description_enter);
- animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
- animator.setTarget(view);
- break;
- case R.id.cloud1:
- case R.id.cloud2:
- view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_cloud_enter);
- animator.setStartDelay(START_DELAY_CLOUD_MS);
- animator.setTarget(view);
- break;
- case R.id.tv_container: {
- view.setAlpha(0);
- Animator tvAnimator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_tv_enter);
- tvAnimator.setTarget(view);
- Animator frameAnimator = SetupAnimationHelper.createFrameAnimator(
- mTvContentView, TV_FRAMES_1_START);
- frameAnimator.setStartDelay(START_DELAY_TV_CONTENTS_MS);
- frameAnimator.setTarget(mTvContentView);
- animator = new AnimatorSet();
- ((AnimatorSet) animator).playTogether(tvAnimator, frameAnimator);
- animator.setStartDelay(START_DELAY_TV_MS);
- break;
- }
- case R.id.shadow:
- view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
- R.animator.onboarding_welcome_shadow_enter);
- animator.setStartDelay(START_DELAY_SHADOW_MS);
- animator.setTarget(view);
- break;
- }
- return animator;
- }
-
- @Override
- public Animator onDisappear(ViewGroup sceneRoot, View view,
- TransitionValues startValues, TransitionValues endValues) {
- return null;
- }
- }));
+ setExitTransition(new SetupAnimationHelper.TransitionBuilder()
+ .setSlideEdge(Gravity.START)
+ .setParentIdsForDelay(new int[]{R.id.onboarding_fragment_root})
+ .build());
}
+ @Nullable
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- mAnimator = null;
- mPageTransitionDistance = getResources().getDimensionPixelOffset(
- R.dimen.onboarding_welcome_page_transition_distance);
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mPageTitles = getResources().getStringArray(R.array.welcome_page_titles);
mPageDescriptions = getResources().getStringArray(R.array.welcome_page_descriptions);
- mNumPages = mPageTitles.length;
- mCurrentPageIndex = 0;
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @Override
+ protected void onStartEnterAnimation() {
+ List<Animator> animators = new ArrayList<>();
+ // Cloud 1
+ View view = getActivity().findViewById(R.id.cloud1);
+ view.setAlpha(0);
+ Animator animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.onboarding_welcome_cloud_enter);
+ animator.setStartDelay(START_DELAY_CLOUD_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ // Cloud 2
+ view = getActivity().findViewById(R.id.cloud2);
+ view.setAlpha(0);
+ animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.onboarding_welcome_cloud_enter);
+ animator.setStartDelay(START_DELAY_CLOUD_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ // TV container
+ view = getActivity().findViewById(R.id.tv_container);
+ view.setAlpha(0);
+ animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.onboarding_welcome_tv_enter);
+ animator.setStartDelay(START_DELAY_TV_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ // TV content
+ view = getActivity().findViewById(R.id.tv_content);
+ animator = SetupAnimationHelper.createFrameAnimator((ImageView) view, TV_FRAMES_1_START);
+ animator.setStartDelay(START_DELAY_TV_CONTENTS_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ // Shadow
+ view = getActivity().findViewById(R.id.shadow);
+ view.setAlpha(0);
+ animator = AnimatorInflater.loadAnimator(getActivity(),
+ R.animator.onboarding_welcome_shadow_enter);
+ animator.setStartDelay(START_DELAY_SHADOW_MS);
+ animator.setTarget(view);
+ animators.add(animator);
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(animators);
+ mAnimator = set;
+ mAnimator.start();
+ mNeedToEndAnimator = true;
+ }
+
+ @Nullable
+ @Override
+ protected View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container) {
+ return inflater.inflate(R.layout.onboarding_welcome_background, container, false);
+ }
+
+ @Nullable
+ @Override
+ protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) {
+ View view = inflater.inflate(R.layout.onboarding_welcome_content, container, false);
mTvContentView = (ImageView) view.findViewById(R.id.tv_content);
- mPageIndicator = (PagingIndicator) view.findViewById(R.id.page_indicator);
- mPageIndicator.setPageCount(mNumPages);
- mPageIndicator.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mCurrentPageIndex == mNumPages - 1) {
- onActionClick(ACTION_NEXT);
- } else {
- showPage(++mCurrentPageIndex);
- startTvFrameAnimation(mCurrentPageIndex);
- }
- }
- });
- mArrowView = (ImageView) view.findViewById(R.id.arrow);
- mLogoView = view.findViewById(R.id.logo);
- showPage(mCurrentPageIndex);
return view;
}
+ @Nullable
@Override
- protected int getLayoutResourceId() {
- return R.layout.fragment_welcome;
+ protected View onCreateForegroundView(LayoutInflater inflater, ViewGroup container) {
+ mArrowView = (ImageView) inflater.inflate(R.layout.onboarding_welcome_foreground, container,
+ false);
+ return mArrowView;
}
- /*
- * Should return {@link SetupFragment} for the custom animations.
- */
- private SetupFragment getPage(int index) {
- Bundle args = new Bundle();
- args.putString(WelcomePageFragment.KEY_TITLE, mPageTitles[index]);
- args.putString(WelcomePageFragment.KEY_DESCRIPTION, mPageDescriptions[index]);
- SetupFragment fragment = new WelcomePageFragment();
- fragment.setArguments(args);
- return fragment;
+ @Override
+ protected int getPageCount() {
+ return mPageTitles.length;
}
- private void showPage(final int pageIndex) {
- SetupFragment fragment = getPage(pageIndex);
- if (pageIndex == 0) {
- fragment.enableFragmentTransition(FRAGMENT_EXIT_TRANSITION);
- }
- if (pageIndex == mNumPages - 1) {
- fragment.enableFragmentTransition(FRAGMENT_ENTER_TRANSITION);
- }
- fragment.setTransitionDistance(mPageTransitionDistance);
- fragment.setTransitionDuration(WELCOME_PAGE_TRANSITION_DURATION_MS);
- getChildFragmentManager().beginTransaction().replace(R.id.page_container, fragment)
- .commit();
- mPageIndicator.onPageSelected(pageIndex, pageIndex != 0);
+ @Override
+ protected String getPageTitle(int pageIndex) {
+ return mPageTitles[pageIndex];
+ }
+
+ @Override
+ protected String getPageDescription(int pageIndex) {
+ return mPageDescriptions[pageIndex];
}
@Override
- protected int[] getParentIdsForDelay() {
- return new int[] {R.id.welcome_fragment_root};
+ protected int getLogoResourceId() {
+ return R.drawable.splash_logo;
}
- private void startTvFrameAnimation(int newPageIndex) {
+ @Override
+ protected void onFinishFragment() {
+ SetupActionHelper.onActionClick(WelcomeFragment.this, ACTION_CATEGORY, ACTION_NEXT);
+ }
+
+ @Override
+ protected void onStartPageChangeAnimation(int previousPage) {
if (mAnimator != null) {
- mAnimator.cancel();
+ if (mNeedToEndAnimator) {
+ mAnimator.end();
+ } else {
+ mAnimator.cancel();
+ }
}
- // TODO: Change the magic numbers to constants once the animation specification is given.
+ mArrowView.setVisibility(View.GONE);
+ // TV screen hiding animator.
+ Animator hideAnimator = previousPage == 0
+ ? SetupAnimationHelper.createFrameAnimator(mTvContentView, TV_FRAMES_1_END)
+ : SetupAnimationHelper.createFadeOutAnimator(mTvContentView,
+ VIDEO_FADE_OUT_DURATION_MS, true);
+ // TV screen showing animator.
AnimatorSet animatorSet = new AnimatorSet();
- switch (newPageIndex) {
+ int firstFrame;
+ switch (getCurrentPageIndex()) {
+ case 0:
+ animatorSet.playSequentially(hideAnimator,
+ SetupAnimationHelper.createFrameAnimator(mTvContentView,
+ TV_FRAMES_1_START));
+ firstFrame = TV_FRAMES_1_START[0];
+ break;
case 1:
- mLogoView.setVisibility(View.GONE);
- animatorSet.playSequentially(
- SetupAnimationHelper.createFrameAnimator(mTvContentView, TV_FRAMES_1_END),
+ animatorSet.playSequentially(hideAnimator,
+ SetupAnimationHelper.createFrameAnimator(mTvContentView,
+ TV_FRAMES_2_START));
+ firstFrame = TV_FRAMES_2_START[0];
+ break;
+ case 2:
+ mArrowView.setVisibility(View.VISIBLE);
+ animatorSet.playSequentially(hideAnimator,
SetupAnimationHelper.createFrameAnimator(mArrowView,
- TV_FRAMES_2_BLUE_ARROW),
+ TV_FRAMES_3_BLUE_ARROW),
SetupAnimationHelper.createFrameAnimator(mTvContentView,
- TV_FRAMES_2_BLUE_START),
+ TV_FRAMES_3_BLUE_START),
SetupAnimationHelper.createFrameAnimatorWithDelay(mTvContentView,
- TV_FRAMES_2_BLUE_END, BLUE_SCREEN_HOLD_DURATION_MS),
+ TV_FRAMES_3_BLUE_END, BLUE_SCREEN_HOLD_DURATION_MS),
SetupAnimationHelper.createFrameAnimator(mArrowView,
- TV_FRAMES_2_ORANGE_ARROW),
+ TV_FRAMES_3_ORANGE_ARROW),
SetupAnimationHelper.createFrameAnimator(mTvContentView,
- TV_FRAMES_2_ORANGE_START));
- mArrowView.setVisibility(View.VISIBLE);
- break;
- case 2:
- mArrowView.setVisibility(View.GONE);
- animatorSet.playSequentially(
- SetupAnimationHelper.createFadeOutAnimator(mTvContentView, 333, true),
- SetupAnimationHelper.createFrameAnimator(mTvContentView,
- TV_FRAMES_3_START));
+ TV_FRAMES_3_ORANGE_START));
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mArrowView.setImageResource(TV_FRAMES_3_BLUE_ARROW[0]);
+ }
+ });
+ firstFrame = TV_FRAMES_3_BLUE_START[0];
break;
case 3:
- animatorSet.playSequentially(
- SetupAnimationHelper.createFadeOutAnimator(mTvContentView, 333, true),
+ default:
+ animatorSet.playSequentially(hideAnimator,
SetupAnimationHelper.createFrameAnimator(mTvContentView,
TV_FRAMES_4_START));
+ firstFrame = TV_FRAMES_4_START[0];
break;
}
+ final int firstImageResource = firstFrame;
+ hideAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Shows the first frame of show animation when the hide animator is canceled.
+ mTvContentView.setImageResource(firstImageResource);
+ }
+ });
mAnimator = SetupAnimationHelper.applyAnimationTimeScale(animatorSet);
mAnimator.start();
+ mNeedToEndAnimator = false;
}
}
diff --git a/src/com/android/tv/onboarding/WelcomePageFragment.java b/src/com/android/tv/onboarding/WelcomePageFragment.java
deleted file mode 100644
index 28499f1d..00000000
--- a/src/com/android/tv/onboarding/WelcomePageFragment.java
+++ /dev/null
@@ -1,58 +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.onboarding;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.tv.R;
-import com.android.tv.common.ui.setup.SetupFragment;
-
-/**
- * A fragment for the onboarding screen.
- */
-public class WelcomePageFragment extends SetupFragment {
- public static final String KEY_TITLE = "key_title";
- public static final String KEY_DESCRIPTION = "key_description";
-
- public WelcomePageFragment() {
- enableFragmentTransition(FRAGMENT_ENTER_TRANSITION | FRAGMENT_EXIT_TRANSITION);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- Bundle args = getArguments();
- ((TextView) view.findViewById(R.id.title)).setText(args.getString(KEY_TITLE));
- ((TextView) view.findViewById(R.id.description)).setText(args.getString(KEY_DESCRIPTION));
- return view;
- }
-
- @Override
- protected int getLayoutResourceId() {
- return R.layout.fragment_welcome_page;
- }
-
- @Override
- protected int[] getParentIdsForDelay() {
- return new int[] {R.id.welcome_page_fragment_root};
- }
-}
diff --git a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
index 2db877f7..313b2dfa 100644
--- a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
+++ b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
@@ -29,6 +29,7 @@ import com.android.tv.ApplicationSingletons;
import com.android.tv.TvApplication;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.SharedPreferencesUtils;
/**
* Creates HDMI plug broadcast receiver, and reports AC3 passthrough capabilities to Google
@@ -36,7 +37,6 @@ import com.android.tv.analytics.Tracker;
* {@link #unregister} to stop.
*/
public final class AudioCapabilitiesReceiver {
- private static final String PREFS_NAME = "com.android.tv.audio_capabilities";
private static final String SETTINGS_KEY_AC3_PASSTHRU_REPORTED = "ac3_passthrough_reported";
private static final String SETTINGS_KEY_AC3_PASSTHRU_CAPABILITIES = "ac3_passthrough";
private static final String SETTINGS_KEY_AC3_REPORT_REVISION = "ac3_report_revision";
@@ -121,7 +121,8 @@ public final class AudioCapabilitiesReceiver {
}
private SharedPreferences getSharedPreferences() {
- return mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ return mContext.getSharedPreferences(SharedPreferencesUtils.SHARED_PREF_AUDIO_CAPABILITIES,
+ Context.MODE_PRIVATE);
}
private boolean getBoolean(String key, boolean def) {
diff --git a/src/com/android/tv/receiver/BootCompletedReceiver.java b/src/com/android/tv/receiver/BootCompletedReceiver.java
index 2b997c32..3cd6186c 100644
--- a/src/com/android/tv/receiver/BootCompletedReceiver.java
+++ b/src/com/android/tv/receiver/BootCompletedReceiver.java
@@ -25,6 +25,7 @@ import android.util.Log;
import com.android.tv.Features;
import com.android.tv.TvActivity;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.dvr.DvrRecordingService;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.util.OnboardingUtils;
@@ -58,8 +59,8 @@ public class BootCompletedReceiver extends BroadcastReceiver {
if (Features.UNHIDE.isEnabled(context)) {
if (OnboardingUtils.isFirstBoot(context)) {
- // Enable the application if this is the first run after the on-boarding experience
- // is applied just in case when the app is disabled before.
+ // Enable the application if this is the first "unhide" feature is enabled just in
+ // case when the app has been disabled before.
PackageManager pm = context.getPackageManager();
ComponentName name = new ComponentName(context, TvActivity.class);
if (pm.getComponentEnabledSetting(name)
@@ -72,7 +73,7 @@ public class BootCompletedReceiver extends BroadcastReceiver {
}
// DVR
- if (Features.DVR.isEnabled(context)) {
+ if (CommonFeatures.DVR.isEnabled(context)) {
DvrRecordingService.startService(context);
}
}
diff --git a/src/com/android/tv/receiver/PackageIntentsReceiver.java b/src/com/android/tv/receiver/PackageIntentsReceiver.java
index cb35c87a..67f0529f 100644
--- a/src/com/android/tv/receiver/PackageIntentsReceiver.java
+++ b/src/com/android/tv/receiver/PackageIntentsReceiver.java
@@ -24,7 +24,7 @@ import android.content.pm.PackageManager;
import com.android.tv.TvActivity;
import com.android.tv.TvApplication;
-import com.android.usbtuner.TunerSetupActivity;
+import com.android.usbtuner.setup.TunerSetupActivity;
import com.android.usbtuner.UsbTunerPreferences;
import com.android.usbtuner.tvinput.UsbTunerTvInputService;
diff --git a/src/com/android/tv/recommendation/NotificationService.java b/src/com/android/tv/recommendation/NotificationService.java
index 3ab67c8b..c6a0c3f6 100644
--- a/src/com/android/tv/recommendation/NotificationService.java
+++ b/src/com/android/tv/recommendation/NotificationService.java
@@ -34,30 +34,36 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseLongArray;
import android.view.View;
-import com.android.tv.R;
import com.android.tv.ApplicationSingletons;
+import com.android.tv.MainActivityWrapper.OnCurrentChannelChangeListener;
+import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.util.BitmapUtils;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
+import com.android.tv.util.ImageLoader;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
+import java.util.ArrayList;
import java.util.List;
/**
* A local service for notify recommendation at home launcher.
*/
-public class NotificationService extends Service implements Recommender.Listener {
- private static final boolean DEBUG = false;
+public class NotificationService extends Service implements Recommender.Listener,
+ OnCurrentChannelChangeListener {
private static final String TAG = "NotificationService";
+ private static final boolean DEBUG = false;
public static final String ACTION_SHOW_RECOMMENDATION =
"com.android.tv.notification.ACTION_SHOW_RECOMMENDATION";
@@ -101,6 +107,8 @@ public class NotificationService extends Service implements Recommender.Listener
private int mCurrentNotificationCount;
private long[] mNotificationChannels;
+ private Channel mPlayingChannel;
+
private float mNotificationCardMaxWidth;
private float mNotificationCardHeight;
private int mCardImageHeight;
@@ -152,6 +160,16 @@ public class NotificationService extends Service implements Recommender.Listener
// Just called for early initialization.
appSingletons.getChannelDataManager();
appSingletons.getProgramDataManager();
+ appSingletons.getMainActivityWrapper().addOnCurrentChannelChangeListener(this);
+ }
+
+ @UiThread
+ @Override
+ public void onCurrentChannelChange(@Nullable Channel channel) {
+ if (DEBUG) Log.d(TAG, "onCurrentChannelChange");
+ mPlayingChannel = channel;
+ mHandler.removeMessages(MSG_SHOW_RECOMMENDATION);
+ mHandler.sendEmptyMessage(MSG_SHOW_RECOMMENDATION);
}
private void handleInitializeRecommender() {
@@ -195,11 +213,17 @@ public class NotificationService extends Service implements Recommender.Listener
@Override
public void onDestroy() {
- mRecommender.release();
- mRecommender = null;
- mHandlerThread.quit();
- mHandlerThread = null;
- mHandler = null;
+ TvApplication.getSingletons(this).getMainActivityWrapper()
+ .removeOnCurrentChannelChangeListener(this);
+ if (mRecommender != null) {
+ mRecommender.release();
+ mRecommender = null;
+ }
+ if (mHandlerThread != null) {
+ mHandlerThread.quit();
+ mHandlerThread = null;
+ mHandler = null;
+ }
super.onDestroy();
}
@@ -231,6 +255,7 @@ public class NotificationService extends Service implements Recommender.Listener
public void onRecommenderReady() {
if (DEBUG) Log.d(TAG, "onRecommendationReady");
if (mShowRecommendationAfterRecommenderReady) {
+ mHandler.removeMessages(MSG_SHOW_RECOMMENDATION);
mHandler.sendEmptyMessage(MSG_SHOW_RECOMMENDATION);
mShowRecommendationAfterRecommenderReady = false;
}
@@ -239,6 +264,13 @@ public class NotificationService extends Service implements Recommender.Listener
@Override
public void onRecommendationChanged() {
if (DEBUG) Log.d(TAG, "onRecommendationChanged");
+ // Update recommendation on the handler thread.
+ mHandler.removeMessages(MSG_SHOW_RECOMMENDATION);
+ mHandler.sendEmptyMessage(MSG_SHOW_RECOMMENDATION);
+ }
+
+ private void showRecommendation() {
+ if (DEBUG) Log.d(TAG, "showRecommendation");
SparseLongArray notificationChannels = new SparseLongArray();
for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
if (mNotificationChannels[i] == Channel.INVALID_ID) {
@@ -246,7 +278,7 @@ public class NotificationService extends Service implements Recommender.Listener
}
notificationChannels.put(i, mNotificationChannels[i]);
}
- List<Channel> channels = mRecommender.recommendChannels();
+ List<Channel> channels = recommendChannels();
for (Channel c : channels) {
int index = notificationChannels.indexOfValue(c.getId());
if (index >= 0) {
@@ -261,13 +293,7 @@ public class NotificationService extends Service implements Recommender.Listener
mNotificationChannels[notificationId] = Channel.INVALID_ID;
--mCurrentNotificationCount;
}
- showRecommendation();
}
- }
-
- private void showRecommendation() {
- if (DEBUG) Log.d(TAG, "showRecommendation");
- List<Channel> channels = mRecommender.recommendChannels();
for (Channel c : channels) {
if (mCurrentNotificationCount >= NOTIFICATION_COUNT) {
break;
@@ -277,14 +303,13 @@ public class NotificationService extends Service implements Recommender.Listener
}
}
if (mCurrentNotificationCount < NOTIFICATION_COUNT) {
- Message msg = mHandler.obtainMessage(MSG_SHOW_RECOMMENDATION);
- mHandler.sendMessageDelayed(msg, RECOMMENDATION_RETRY_TIME_MS);
+ mHandler.sendEmptyMessageDelayed(MSG_SHOW_RECOMMENDATION, RECOMMENDATION_RETRY_TIME_MS);
}
}
private void changeRecommendation(int notificationId) {
if (DEBUG) Log.d(TAG, "changeRecommendation");
- List<Channel> channels = mRecommender.recommendChannels();
+ List<Channel> channels = recommendChannels();
if (mNotificationChannels[notificationId] != Channel.INVALID_ID) {
mNotificationChannels[notificationId] = Channel.INVALID_ID;
--mCurrentNotificationCount;
@@ -299,6 +324,15 @@ public class NotificationService extends Service implements Recommender.Listener
mNotificationManager.cancel(NOTIFY_TAG, notificationId);
}
+ private List<Channel> recommendChannels() {
+ List channels = mRecommender.recommendChannels();
+ if (channels.contains(mPlayingChannel)) {
+ channels = new ArrayList<>(channels);
+ channels.remove(mPlayingChannel);
+ }
+ return channels;
+ }
+
private void hideAllRecommendation() {
for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
if (mNotificationChannels[i] != Channel.INVALID_ID) {
@@ -319,9 +353,6 @@ public class NotificationService extends Service implements Recommender.Listener
Log.d(TAG, "sendNotification (channelName=" + channel.getDisplayName() + " notifyId="
+ notificationId + ")");
}
- Intent intent = new Intent(Intent.ACTION_VIEW, channel.getUri());
- intent.putExtra(TUNE_PARAMS_RECOMMENDATION_TYPE, mRecommendationType);
- final PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
// TODO: Move some checking logic into TvRecommendation.
String inputId = Utils.getInputIdForChannel(this, channel.getId());
@@ -361,43 +392,9 @@ public class NotificationService extends Service implements Recommender.Listener
final Bitmap posterArtBitmap = posterArtBitmapInfo.bitmap;
channel.loadBitmap(this, Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO, mChannelLogoMaxWidth,
- mChannelLogoMaxHeight, new Channel.LoadImageCallback() {
- @Override
- public void onLoadImageFinished(Channel channel, int type, Bitmap channelLogo) {
- // This callback will run on the main thread.
- Bitmap largeIconBitmap = (channelLogo == null) ? posterArtBitmap
- : overlayChannelLogo(channelLogo, posterArtBitmap);
- String channelDisplayName = channel.getDisplayName();
- Notification notification =
- new Notification.Builder(NotificationService.this)
- .setContentIntent(notificationIntent)
- .setContentTitle(program.getTitle())
- .setContentText(inputDisplayName + " " +
- (TextUtils.isEmpty(channelDisplayName)
- ? channel.getDisplayNumber() : channelDisplayName))
- .setContentInfo(channelDisplayName)
- .setAutoCancel(true)
- .setLargeIcon(largeIconBitmap)
- .setSmallIcon(R.drawable.ic_launcher_s)
- .setCategory(Notification.CATEGORY_RECOMMENDATION)
- .setProgress((programProgress > 0) ? 100 : 0,
- programProgress,
- false)
- .setSortKey(mRecommender.getChannelSortKey(channelId))
- .build();
- notification.color = Utils.getColor(getResources(),
- R.color.recommendation_card_background);
- if (!TextUtils.isEmpty(program.getThumbnailUri())) {
- notification.extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI,
- program.getThumbnailUri());
- }
- mNotificationManager.notify(NOTIFY_TAG, notificationId, notification);
- Message msg = mHandler.obtainMessage(
- MSG_UPDATE_RECOMMENDATION, notificationId, 0, channel);
- mHandler.sendMessageDelayed(msg,
- programDurationMs / MAX_PROGRAM_UPDATE_COUNT);
- }
- });
+ mChannelLogoMaxHeight,
+ createChannelLogoCallback(this, notificationId, inputDisplayName, channel, program,
+ posterArtBitmap));
if (mNotificationChannels[notificationId] == Channel.INVALID_ID) {
++mCurrentNotificationCount;
@@ -407,6 +404,55 @@ public class NotificationService extends Service implements Recommender.Listener
return true;
}
+ @NonNull
+ private static ImageLoader.ImageLoaderCallback<NotificationService> createChannelLogoCallback(
+ NotificationService service, final int notificationId, final String inputDisplayName,
+ final Channel channel, final Program program, final Bitmap posterArtBitmap) {
+ return new ImageLoader.ImageLoaderCallback<NotificationService>(service) {
+ @Override
+ public void onBitmapLoaded(NotificationService service, Bitmap channelLogo) {
+ service.sendNotification(notificationId, channelLogo, channel, posterArtBitmap,
+ program, inputDisplayName);
+ }
+ };
+ }
+
+ private void sendNotification(int notificationId, Bitmap channelLogo, Channel channel,
+ Bitmap posterArtBitmap, Program program, String inputDisplayName1) {
+
+ final long programDurationMs = program.getEndTimeUtcMillis() - program
+ .getStartTimeUtcMillis();
+ long programLeftTimsMs = program.getEndTimeUtcMillis() - System.currentTimeMillis();
+ final int programProgress = (programDurationMs <= 0) ? -1
+ : 100 - (int) (programLeftTimsMs * 100 / programDurationMs);
+ Intent intent = new Intent(Intent.ACTION_VIEW, channel.getUri());
+ intent.putExtra(TUNE_PARAMS_RECOMMENDATION_TYPE, mRecommendationType);
+ final PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
+
+ // This callback will run on the main thread.
+ Bitmap largeIconBitmap = (channelLogo == null) ? posterArtBitmap
+ : overlayChannelLogo(channelLogo, posterArtBitmap);
+ String channelDisplayName = channel.getDisplayName();
+ Notification notification = new Notification.Builder(this)
+ .setContentIntent(notificationIntent).setContentTitle(program.getTitle())
+ .setContentText(inputDisplayName1 + " " +
+ (TextUtils.isEmpty(channelDisplayName) ? channel.getDisplayNumber()
+ : channelDisplayName)).setContentInfo(channelDisplayName)
+ .setAutoCancel(true).setLargeIcon(largeIconBitmap)
+ .setSmallIcon(R.drawable.ic_launcher_s)
+ .setCategory(Notification.CATEGORY_RECOMMENDATION)
+ .setProgress((programProgress > 0) ? 100 : 0, programProgress, false)
+ .setSortKey(mRecommender.getChannelSortKey(channel.getId())).build();
+ notification.color = Utils.getColor(getResources(), R.color.recommendation_card_background);
+ if (!TextUtils.isEmpty(program.getThumbnailUri())) {
+ notification.extras
+ .putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, program.getThumbnailUri());
+ }
+ mNotificationManager.notify(NOTIFY_TAG, notificationId, notification);
+ Message msg = mHandler.obtainMessage(MSG_UPDATE_RECOMMENDATION, notificationId, 0, channel);
+ mHandler.sendMessageDelayed(msg, programDurationMs / MAX_PROGRAM_UPDATE_COUNT);
+ }
+
private Bitmap overlayChannelLogo(Bitmap logo, Bitmap background) {
Bitmap result = BitmapUtils.scaleBitmap(
background, Integer.MAX_VALUE, mCardImageHeight);
diff --git a/src/com/android/tv/search/DataManagerSearch.java b/src/com/android/tv/search/DataManagerSearch.java
index 88c69c53..d26ae334 100644
--- a/src/com/android/tv/search/DataManagerSearch.java
+++ b/src/com/android/tv/search/DataManagerSearch.java
@@ -22,7 +22,7 @@ import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Programs;
import android.media.tv.TvInputManager;
-import android.support.annotation.UiThread;
+import android.support.annotation.MainThread;
import android.text.TextUtils;
import android.util.Log;
@@ -87,7 +87,7 @@ public class DataManagerSearch implements SearchInterface {
}
}
- @UiThread
+ @MainThread
private List<SearchResult> searchFromDataManagers(String query, int limit, int action) {
List<SearchResult> results = new ArrayList<>();
if (!mChannelDataManager.isDbLoadFinished()) {
diff --git a/src/com/android/tv/search/LocalSearchProvider.java b/src/com/android/tv/search/LocalSearchProvider.java
index 3cc21ace..7edb07dc 100644
--- a/src/com/android/tv/search/LocalSearchProvider.java
+++ b/src/com/android/tv/search/LocalSearchProvider.java
@@ -64,8 +64,6 @@ public class LocalSearchProvider extends ContentProvider {
static final String SUGGEST_PARAMETER_ACTION = "action";
static final int DEFAULT_SEARCH_ACTION = SearchInterface.ACTION_TYPE_AMBIGUOUS;
- private SearchInterface mSearch;
-
@Override
public boolean onCreate() {
return true;
@@ -78,10 +76,11 @@ public class LocalSearchProvider extends ContentProvider {
Log.d(TAG, "query(" + uri + ", " + Arrays.toString(projection) + ", " + selection + ", "
+ Arrays.toString(selectionArgs) + ", " + sortOrder + ")");
}
+ SearchInterface search;
if (PermissionUtils.hasAccessAllEpg(getContext())) {
- mSearch = new TvProviderSearch(getContext());
+ search = new TvProviderSearch(getContext());
} else {
- mSearch = new DataManagerSearch(getContext());
+ search = new DataManagerSearch(getContext());
}
String query = uri.getLastPathSegment();
int limit = DEFAULT_SEARCH_LIMIT;
@@ -94,7 +93,7 @@ public class LocalSearchProvider extends ContentProvider {
}
List<SearchResult> results = new ArrayList<>();
if (!TextUtils.isEmpty(query)) {
- results.addAll(mSearch.search(query, limit, action));
+ results.addAll(search.search(query, limit, action));
}
return createSuggestionsCursor(results);
}
diff --git a/src/com/android/tv/search/ProgramGuideSearchFragment.java b/src/com/android/tv/search/ProgramGuideSearchFragment.java
index 7d6efcb3..87eec68e 100644
--- a/src/com/android/tv/search/ProgramGuideSearchFragment.java
+++ b/src/com/android/tv/search/ProgramGuideSearchFragment.java
@@ -71,21 +71,14 @@ public class ProgramGuideSearchFragment extends SearchFragment {
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object o) {
- final ImageCardView cardView = (ImageCardView) viewHolder.view;
+ ImageCardView cardView = (ImageCardView) viewHolder.view;
LocalSearchProvider.SearchResult result = (LocalSearchProvider.SearchResult) o;
if (DEBUG) Log.d(TAG, "onBindViewHolder result:" + result);
cardView.setTitleText(result.title);
if (!TextUtils.isEmpty(result.imageUri)) {
- ImageLoader.loadBitmap(mMainActivity, result.imageUri,
- mMainCardWidth, mMainCardHeight,
- new ImageLoader.ImageLoaderCallback() {
- @Override
- public void onBitmapLoaded(Bitmap bitmap) {
- cardView.setMainImage(
- new BitmapDrawable(mMainActivity.getResources(), bitmap));
- }
- });
+ ImageLoader.loadBitmap(mMainActivity, result.imageUri, mMainCardWidth,
+ mMainCardHeight, createImageLoaderCallback(cardView));
} else {
cardView.setMainImage(mMainActivity.getDrawable(R.drawable.ic_launcher));
}
@@ -97,6 +90,17 @@ public class ProgramGuideSearchFragment extends SearchFragment {
}
};
+ private static ImageLoader.ImageLoaderCallback<ImageCardView> createImageLoaderCallback(
+ ImageCardView cardView) {
+ return new ImageLoader.ImageLoaderCallback<ImageCardView>(cardView) {
+ @Override
+ public void onBitmapLoaded(ImageCardView cardView, Bitmap bitmap) {
+ cardView.setMainImage(
+ new BitmapDrawable(cardView.getContext().getResources(), bitmap));
+ }
+ };
+ }
+
private final SearchResultProvider mSearchResultProvider = new SearchResultProvider() {
@Override
public ObjectAdapter getResultsAdapter() {
diff --git a/src/com/android/tv/search/TvProviderSearch.java b/src/com/android/tv/search/TvProviderSearch.java
index a5ad00ff..bd4ae5e5 100644
--- a/src/com/android/tv/search/TvProviderSearch.java
+++ b/src/com/android/tv/search/TvProviderSearch.java
@@ -32,6 +32,7 @@ import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
+import com.android.tv.common.TvContentRatingCache;
import com.android.tv.search.LocalSearchProvider.SearchResult;
import com.android.tv.util.PermissionUtils;
import com.android.tv.util.Utils;
@@ -61,6 +62,7 @@ public class TvProviderSearch implements SearchInterface {
private final Context mContext;
private final ContentResolver mContentResolver;
private final TvInputManager mTvInputManager;
+ private final TvContentRatingCache mTvContentRatingCache = TvContentRatingCache.getInstance();
TvProviderSearch(Context context) {
mContext = context;
@@ -403,17 +405,15 @@ public class TvProviderSearch implements SearchInterface {
}
private boolean isRatingBlocked(String ratings) {
- if (ratings == null) {
+ if (TextUtils.isEmpty(ratings) || !mTvInputManager.isParentalControlsEnabled()) {
return false;
}
- for (String rating : ratings.split("\\s*,\\s*")) {
- try {
- if (mTvInputManager.isParentalControlsEnabled() && mTvInputManager.isRatingBlocked(
- TvContentRating.unflattenFromString(rating))) {
+ TvContentRating[] ratingArray = mTvContentRatingCache.getRatings(ratings);
+ if (ratingArray != null) {
+ for (TvContentRating r : ratingArray) {
+ if (mTvInputManager.isRatingBlocked(r)) {
return true;
}
- } catch (IllegalArgumentException e) {
- // Do nothing.
}
}
return false;
diff --git a/src/com/android/tv/ui/AppLayerTvView.java b/src/com/android/tv/ui/AppLayerTvView.java
index 23ac5392..befa004c 100644
--- a/src/com/android/tv/ui/AppLayerTvView.java
+++ b/src/com/android/tv/ui/AppLayerTvView.java
@@ -16,7 +16,7 @@
package com.android.tv.ui;
-import com.android.tv.common.dvr.DvrTvView;
+import com.android.tv.common.recording.PlaybackTvView;
import android.content.Context;
import android.util.AttributeSet;
@@ -30,7 +30,7 @@ import android.util.AttributeSet;
* TODO: remove this class once the TvView.setMain() is revisited.
* </p>
*/
-public class AppLayerTvView extends DvrTvView {
+public class AppLayerTvView extends PlaybackTvView {
public AppLayerTvView(Context context) {
super(context);
}
diff --git a/src/com/android/tv/ui/ChannelBannerView.java b/src/com/android/tv/ui/ChannelBannerView.java
index bf8e69c7..17ac8f3b 100644
--- a/src/com/android/tv/ui/ChannelBannerView.java
+++ b/src/com/android/tv/ui/ChannelBannerView.java
@@ -16,6 +16,8 @@
package com.android.tv.ui;
+import static com.android.tv.util.ImageLoader.ImageLoaderCallback;
+
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
@@ -29,6 +31,7 @@ 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;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -62,8 +65,7 @@ import java.util.Objects;
/**
* A view to render channel banner.
*/
-public class ChannelBannerView extends FrameLayout implements Channel.LoadImageCallback,
- TvTransitionManager.TransitionLayout {
+public class ChannelBannerView extends FrameLayout implements TvTransitionManager.TransitionLayout {
/**
* Show all information at the channel banner.
@@ -128,7 +130,8 @@ public class ChannelBannerView extends FrameLayout implements Channel.LoadImageC
TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
}
};
private final long mShowDurationMillis;
@@ -407,8 +410,7 @@ public class ChannelBannerView extends FrameLayout implements Channel.LoadImageC
TvInputInfo info = mMainActivity.getTvInputManagerHelper().getTvInputInfo(
mCurrentChannel.getInputId());
- if (info == null ||
- !ImageLoader.loadBitmap(createTvInputLogoLoaderCallback(info),
+ if (info == null || !ImageLoader.loadBitmap(createTvInputLogoLoaderCallback(info, this),
new LoadTvInputLogoTask(getContext(), ImageCache.getInstance(), info))) {
mTvInputLogoImageView.setVisibility(View.GONE);
mTvInputLogoImageView.setImageDrawable(null);
@@ -416,17 +418,23 @@ public class ChannelBannerView extends FrameLayout implements Channel.LoadImageC
mChannelLogoImageView.setImageBitmap(null);
mChannelLogoImageView.setVisibility(View.GONE);
mCurrentChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
- mChannelLogoImageViewWidth, mChannelLogoImageViewHeight, this);
+ mChannelLogoImageViewWidth, mChannelLogoImageViewHeight,
+ createChannelLogoCallback(this, mCurrentChannel));
+ }
+
+ private void updateTvInputLogo(Bitmap bitmap) {
+ mTvInputLogoImageView.setVisibility(View.VISIBLE);
+ mTvInputLogoImageView.setImageBitmap(bitmap);
}
- private ImageLoader.ImageLoaderCallback createTvInputLogoLoaderCallback(
- final TvInputInfo info) {
- return new ImageLoader.ImageLoaderCallback() {
+ private static ImageLoaderCallback<ChannelBannerView> createTvInputLogoLoaderCallback(
+ final TvInputInfo info, ChannelBannerView channelBannerView) {
+ return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
@Override
- public void onBitmapLoaded(Bitmap bitmap) {
- if (bitmap != null && info.getId().equals(mCurrentChannel.getInputId())) {
- mTvInputLogoImageView.setVisibility(View.VISIBLE);
- mTvInputLogoImageView.setImageBitmap(bitmap);
+ public void onBitmapLoaded(ChannelBannerView channelBannerView, Bitmap bitmap) {
+ if (bitmap != null && info.getId()
+ .equals(channelBannerView.mCurrentChannel.getInputId())) {
+ channelBannerView.updateTvInputLogo(bitmap);
}
}
};
@@ -458,12 +466,21 @@ public class ChannelBannerView extends FrameLayout implements Channel.LoadImageC
}
}
- @Override
- public void onLoadImageFinished(Channel channel, int type, Bitmap logo) {
- if (channel != mCurrentChannel) {
- // The logo is obsolete.
- return;
- }
+ private static ImageLoaderCallback<ChannelBannerView> createChannelLogoCallback(
+ ChannelBannerView channelBannerView, final Channel channel) {
+ return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
+ @Override
+ public void onBitmapLoaded(ChannelBannerView view, @Nullable Bitmap logo) {
+ if (channel != view.mCurrentChannel) {
+ // The logo is obsolete.
+ return;
+ }
+ view.updateLogo(logo);
+ }
+ };
+ }
+
+ private void updateLogo(@Nullable Bitmap logo) {
if (logo == null) {
// Need to update the text size of the program text view depending on the channel logo.
updateProgramTextView(mLastUpdatedProgram);
diff --git a/src/com/android/tv/ui/InputBannerView.java b/src/com/android/tv/ui/InputBannerView.java
index 649331f4..4e254c62 100644
--- a/src/com/android/tv/ui/InputBannerView.java
+++ b/src/com/android/tv/ui/InputBannerView.java
@@ -38,7 +38,8 @@ public class InputBannerView extends LinearLayout implements TvTransitionManager
TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
}
};
diff --git a/src/com/android/tv/ui/KeypadChannelSwitchView.java b/src/com/android/tv/ui/KeypadChannelSwitchView.java
index 140ba533..cf43fc9b 100644
--- a/src/com/android/tv/ui/KeypadChannelSwitchView.java
+++ b/src/com/android/tv/ui/KeypadChannelSwitchView.java
@@ -84,7 +84,8 @@ public class KeypadChannelSwitchView extends LinearLayout implements
TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
| TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
}
}
};
@@ -127,6 +128,7 @@ public class KeypadChannelSwitchView extends LinearLayout implements
@Override
protected void onFinishInflate(){
+ super.onFinishInflate();
mChannelNumberView = (TextView) findViewById(R.id.channel_number);
mChannelItemListView = (ListView) findViewById(R.id.channel_list);
mChannelItemListView.setAdapter(mAdapter);
diff --git a/src/com/android/tv/ui/SetupView.java b/src/com/android/tv/ui/SetupView.java
deleted file mode 100644
index 95a9f28e..00000000
--- a/src/com/android/tv/ui/SetupView.java
+++ /dev/null
@@ -1,419 +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;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.app.Dialog;
-import android.content.Context;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager.TvInputCallback;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.TvInputNewComparator;
-import com.android.tv.util.SetupUtils;
-import com.android.tv.util.TvInputManagerHelper;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class SetupView extends FullscreenDialogView {
- private static final String TAG = "SetupView";
- private static final boolean DEBUG = false;
-
- private static final int FINISH_ACTIVITY_DELAY_MS = 200;
- private static final int REFRESH_DELAY_MS_AFTER_WINDOW_FOCUS_GAINED = 200;
-
- private static final long ANIMATION_START_DELAY = 25;
-
- private VerticalGridView mInputView;
- private ChannelDataManager mChannelDataManager;
- private TvInputManagerHelper mInputManager;
- private List<TvInputInfo> mInputList;
- // mInputList[0:mKnownInputStartIndex - 1] are new inputs.
- // And mInputList[mKnownInputStartIndex:end] are inputs which have been shown in SetupView.
- private int mKnownInputStartIndex;
- private boolean mShowDivider;
- private SetupAdapter mAdapter;
- private boolean mClosing;
- private boolean mInitialized;
- private SetupUtils mSetupUtils;
- private boolean mNeedIntroDialog;
- private final int mEnterTranslationX;
- private final int mExitTranslationX;
- private Animator mEnterAnimator;
-
- private final TvInputCallback mInputCallback = new TvInputCallback() {
- @Override
- public void onInputAdded(String inputId) {
- if (DEBUG) {
- Log.d(TAG, "onInputAdded: " + inputId);
- }
- if (!mInitialized) {
- return;
- }
- updateInputList();
- }
-
- @Override
- public void onInputRemoved(String inputId) {
- if (DEBUG) {
- Log.d(TAG, "onInputRemoved: " + inputId);
- }
- if (!mInitialized) {
- return;
- }
- updateInputList();
- }
- };
- private final ChannelDataManager.Listener mChannelDataListener =
- new ChannelDataManager.Listener() {
- @Override
- public void onLoadFinished() { }
-
- @Override
- public void onChannelListUpdated() {
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onChannelBrowsableChanged() {
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
- }
- };
-
- public SetupView(Context context) {
- this(context, null, 0);
- }
-
- public SetupView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SetupView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mEnterTranslationX = context.getResources().getInteger(
- R.integer.fullscreen_dialog_enter_translation_x);
- mExitTranslationX = context.getResources().getInteger(
- R.integer.fullscreen_dialog_exit_translation_x);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- TextView titleView = (TextView) findViewById(R.id.setup_title);
- titleView.setText(R.string.setup_title);
- TextView descriptionView = (TextView) findViewById(R.id.setup_description);
- descriptionView.setText(R.string.setup_description);
- mInputView = (VerticalGridView) findViewById(R.id.input_list);
- TypedValue outValue = new TypedValue();
- getResources().getValue(R.dimen.setup_item_window_alignment_offset_percent, outValue, true);
- mInputView.setWindowAlignmentOffsetPercent(outValue.getFloat());
- }
-
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- mInputManager.addCallback(mInputCallback);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mInputManager.removeCallback(mInputCallback);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- return mClosing || super.dispatchKeyEvent(event);
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- if (hasWindowFocus && mAdapter != null) {
- // Without the following delay, the channel count description is sometimes
- // changed twice by this method and mChannelDataListener.
- postDelayed(new Runnable() {
- @Override
- public void run() {
- // When channel count is still 0 after setup, the description should be changed
- // from "Not set up" to "No channels".
- if (mAdapter.getItemCount() != 0) {
- mAdapter.notifyItemRangeChanged(0, mAdapter.getItemCount());
- }
- }
- }, REFRESH_DELAY_MS_AFTER_WINDOW_FOCUS_GAINED);
- }
- }
-
- /**
- * Initializes SetupView.
- */
- @Override
- public void initialize(MainActivity activity, Dialog dialog) {
- super.initialize(activity, dialog);
- if (mInitialized) {
- throw new IllegalStateException("initialize() is called more than once");
- }
- mInitialized = true;
- mInputManager = getActivity().getTvInputManagerHelper();
- mChannelDataManager = getActivity().getChannelDataManager();
- mSetupUtils = SetupUtils.getInstance(activity);
- mNeedIntroDialog = mSetupUtils.isFirstTune();
- mAdapter = new SetupAdapter();
- mInputView.setAdapter(mAdapter);
- mChannelDataManager.addListener(mChannelDataListener);
- updateInputList();
- }
-
- private void updateInputList() {
- mInputList = new ArrayList<>();
- mKnownInputStartIndex = 0;
- mInputList = mInputManager.getTvInputInfos(true, true);
- Collections.sort(mInputList, new TvInputNewComparator(mSetupUtils, mInputManager));
- for (TvInputInfo input : mInputList) {
- if (mSetupUtils.isNewInput(input.getId())) {
- mSetupUtils.markAsKnownInput(input.getId());
- ++mKnownInputStartIndex;
- }
- }
- mShowDivider = mKnownInputStartIndex != 0 && mKnownInputStartIndex != mInputList.size();
- mNeedIntroDialog = mSetupUtils.isFirstTune();
- mAdapter.notifyDataSetChanged();
- }
-
- /**
- * Called when the DialogFragment including this view is destroyed.
- */
- @Override
- public void onDestroy() {
- mChannelDataManager.removeListener(mChannelDataListener);
- }
-
- @Override
- protected void dismiss() {
- mClosing = true;
- if (mNeedIntroDialog) {
- LayoutInflater inflater = LayoutInflater.from(getActivity());
- IntroView v = (IntroView) inflater.inflate(R.layout.intro_dialog, null);
- transitionTo(v);
- } else {
- super.dismiss();
- }
- }
- /**
- * Called when the back key is pressed.
- */
- @Override
- public void onBackPressed() {
- if (mChannelDataManager.getChannelCount() == 0) {
- // If there is no channel, we finish the activity rather than closing just the view.
- getActivity().finish();
- }
- dismiss();
- }
-
- @Override
- protected void onStartEnterAnimation(final TimeInterpolator interpolator, final long duration) {
- List<Animator> animatorList = new ArrayList<>();
- View leftPanel = findViewById(R.id.setup_left);
- leftPanel.setAlpha(0);
- leftPanel.setTranslationX(mEnterTranslationX);
- animatorList.add(buildEnterAnimator(leftPanel, duration, 0, interpolator));
-
- for (int i = 0; i < mInputView.getChildCount(); ++i) {
- View itemView = mInputView.getChildAt(i);
- itemView.setAlpha(0);
- itemView.setTranslationX(mEnterTranslationX);
- int itemPosition = mInputView.getChildAdapterPosition(itemView);
- animatorList.add(buildEnterAnimator(itemView, duration,
- ANIMATION_START_DELAY * (itemPosition + 1), interpolator));
- }
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(animatorList);
- mEnterAnimator = animatorSet;
- mEnterAnimator.start();
- }
-
- private Animator buildEnterAnimator(View v, long duration, long startDelay,
- TimeInterpolator interpolator) {
- Animator animator = ObjectAnimator.ofPropertyValuesHolder(v,
- PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1.0f),
- PropertyValuesHolder.ofFloat(View.TRANSLATION_X, mEnterTranslationX, 0));
- animator.setStartDelay(startDelay);
- animator.setDuration(duration);
- animator.setInterpolator(interpolator);
- animator.addListener(new HardwareLayerAnimatorListenerAdapter(v));
- return animator;
- }
-
- @Override
- protected void onStartExitAnimation(TimeInterpolator interpolator, long duration,
- final Runnable onAnimationEnded) {
- if (mEnterAnimator != null && mEnterAnimator.isRunning()) {
- mEnterAnimator.cancel();
- }
- List<Animator> animatorList = new ArrayList<>();
- animatorList.add(
- buildExitAnimator(findViewById(R.id.setup_left), duration, 0, interpolator));
- for (int i = 0; i < mInputView.getChildCount(); ++i) {
- View itemView = mInputView.getChildAt(i);
- int itemPosition = mInputView.getChildAdapterPosition(itemView);
- animatorList.add(buildExitAnimator(itemView, duration,
- ANIMATION_START_DELAY * (itemPosition + 1), interpolator));
- }
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(animatorList);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- onAnimationEnded.run();
- }
- });
- animatorSet.start();
- }
-
- private Animator buildExitAnimator(View v, long duration, long startDelay,
- TimeInterpolator interpolator) {
- Animator animator = ObjectAnimator.ofPropertyValuesHolder(v,
- PropertyValuesHolder.ofFloat(View.ALPHA, v.getAlpha(), 0f),
- PropertyValuesHolder.ofFloat(View.TRANSLATION_X,
- v.getTranslationX(), mExitTranslationX));
- animator.setStartDelay(startDelay);
- animator.setDuration(duration);
- animator.setInterpolator(interpolator);
- animator.addListener(new HardwareLayerAnimatorListenerAdapter(v));
- return animator;
- }
-
- private class SetupAdapter extends RecyclerView.Adapter<MyViewHolder> {
- @Override
- public int getItemViewType(int position) {
- if (mShowDivider && position == mKnownInputStartIndex) {
- return R.layout.setup_item_divider;
- } else if (position == getItemCount() - 1) {
- return R.layout.setup_item_action;
- } else {
- return R.layout.setup_item_input;
- }
- }
-
- @Override
- public int getItemCount() {
- if (mInputList == null) {
- return 1;
- }
- return mInputList.size() + 1 + (mShowDivider ? 1 : 0);
- }
-
- @Override
- public void onBindViewHolder(final MyViewHolder viewHolder, int position) {
- if (position == getItemCount() - 1) {
- final boolean closeActivity = mChannelDataManager.getChannelCount() == 0;
- viewHolder.mTitle.setText(R.string.setup_done_button_label);
- viewHolder.itemView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mClosing = true;
- if (closeActivity) {
- // To wait completing ripple animation, finish() is called
- // FINISH_ACTIVITY_DELAY_MS later.
- mNeedIntroDialog = false;
- postDelayed(new Runnable() {
- @Override
- public void run() {
- getActivity().finish();
- }
- }, FINISH_ACTIVITY_DELAY_MS);
- } else {
- dismiss();
- }
- }
- });
- } else {
- if (mShowDivider) {
- if (position == mKnownInputStartIndex) {
- // This view is a divider.
- return;
- } else if (position > mKnownInputStartIndex) {
- --position;
- }
- }
- final TvInputInfo input = mInputList.get(position);
- viewHolder.mTitle.setText(input.loadLabel(getContext()));
- int channelCount = mChannelDataManager.getChannelCountForInput(input.getId());
- if (mSetupUtils.isSetupDone(input.getId())) {
- if (channelCount == 0) {
- viewHolder.mDescription.setText(R.string.setup_input_no_channels);
- } else {
- viewHolder.mDescription.setText(getResources().getQuantityString(
- R.plurals.setup_input_channels, channelCount, channelCount));
- }
- } else if (position >= mKnownInputStartIndex) {
- viewHolder.mDescription.setText(R.string.channel_description_setup_now);
- } else {
- viewHolder.mDescription.setText(R.string.setup_input_new);
- }
- viewHolder.itemView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().startSetupActivity(input, true);
- }
- });
- }
- }
-
- @Override
- public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View itemView = LayoutInflater.from(parent.getContext()).inflate(viewType, parent,
- false);
- return new MyViewHolder(itemView);
- }
- }
-
- private static class MyViewHolder extends RecyclerView.ViewHolder {
- final TextView mTitle;
- final TextView mDescription;
-
- public MyViewHolder(View itemView) {
- super(itemView);
- mTitle = (TextView) itemView.findViewById(R.id.title);
- mDescription = (TextView) itemView.findViewById(R.id.description);
- }
- }
-}
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index fe185b2e..806dc6ef 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -21,6 +21,7 @@ import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.PlaybackParams;
@@ -28,10 +29,10 @@ import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
-import android.media.tv.TvView;
import android.media.tv.TvView.OnUnhandledInputEventListener;
import android.media.tv.TvView.TvInputCallback;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
@@ -47,12 +48,13 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
-import com.android.tv.R;
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.analytics.Tracker;
-import com.android.tv.common.TvCommonConstants;
+import com.android.tv.common.recording.PlaybackTvView;
+import com.android.tv.common.recording.RecordingUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
@@ -311,6 +313,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
@Override
+ @TargetApi(Build.VERSION_CODES.M)
public void onTimeShiftStatusChanged(String inputId, int status) {
setTimeShiftAvailable(status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
}
@@ -468,6 +471,18 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
+ * Plays a recording.
+ */
+ public boolean playRecording(String inputId, Uri recordingUri, OnTuneListener listener) {
+ // Create a dummy channel.
+ Channel channel = new Channel.Builder()
+ .setId(0)
+ .setInputId(inputId)
+ .build();
+ return tuneTo(channel, RecordingUtils.buildMediaUri(recordingUri), listener);
+ }
+
+ /**
* Tunes to a channel with the {@code channelId}.
*
* @param params extra data to send it to TIS and store the data in TIMS.
@@ -517,7 +532,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mHasClosedCaption = false;
mTvView.setCallback(mCallback);
mTimeShiftCurrentPositionMs = INVALID_TIME;
- if (TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// To reduce the IPCs, unregister the callback here and register it when necessary.
mTvView.setTimeShiftPositionCallback(null);
}
@@ -1074,12 +1089,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
private void setTimeShiftAvailable(boolean isTimeShiftAvailable) {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API || mTimeShiftAvailable == isTimeShiftAvailable) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || mTimeShiftAvailable == isTimeShiftAvailable) {
return;
}
mTimeShiftAvailable = isTimeShiftAvailable;
if (isTimeShiftAvailable) {
- mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
+ mTvView.setTimeShiftPositionCallback(new PlaybackTvView.TimeShiftPositionCallback2() {
@Override
public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
if (mTimeShiftListener != null && mCurrentChannel != null
@@ -1092,6 +1107,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
mTimeShiftCurrentPositionMs = timeMs;
}
+
+ @Override
+ public void onTimeShiftEndPositionChanged(String inputId, long timeMs) {
+ if (mTimeShiftListener != null && mCurrentChannel != null
+ && mCurrentChannel.getInputId().equals(inputId)) {
+ mTimeShiftListener.onRecordEndTimeChanged(timeMs);
+ }
+ }
});
} else {
mTvView.setTimeShiftPositionCallback(null);
@@ -1122,7 +1145,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* Plays the media, if the current input supports time-shifting.
*/
public void timeshiftPlay() {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
return;
}
@@ -1139,7 +1162,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* Pauses the media, if the current input supports time-shifting.
*/
public void timeshiftPause() {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
return;
}
@@ -1158,20 +1181,19 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* @param speed The speed to rewind the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
*/
public void timeshiftRewind(int speed) {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
- return;
- }
- if (!isTimeShiftAvailable()) {
+ } else if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
+ } else {
+ if (speed <= 0) {
+ throw new IllegalArgumentException("The speed should be a positive integer.");
+ }
+ mTimeShiftState = TIME_SHIFT_STATE_REWIND;
+ PlaybackParams params = new PlaybackParams();
+ params.setSpeed(speed * -1);
+ mTvView.timeShiftSetPlaybackParams(params);
}
- if (speed <= 0) {
- throw new IllegalArgumentException("The speed should be a positive integer.");
- }
- mTimeShiftState = TIME_SHIFT_STATE_REWIND;
- PlaybackParams params = new PlaybackParams();
- params.setSpeed(speed * -1);
- mTvView.timeShiftSetPlaybackParams(params);
}
/**
@@ -1180,20 +1202,19 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* @param speed The speed to forward the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
*/
public void timeshiftFastForward(int speed) {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
- return;
- }
- if (!isTimeShiftAvailable()) {
+ } else if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
+ } else {
+ if (speed <= 0) {
+ throw new IllegalArgumentException("The speed should be a positive integer.");
+ }
+ mTimeShiftState = TIME_SHIFT_STATE_FAST_FORWARD;
+ PlaybackParams params = new PlaybackParams();
+ params.setSpeed(speed);
+ mTvView.timeShiftSetPlaybackParams(params);
}
- if (speed <= 0) {
- throw new IllegalArgumentException("The speed should be a positive integer.");
- }
- mTimeShiftState = TIME_SHIFT_STATE_FAST_FORWARD;
- PlaybackParams params = new PlaybackParams();
- params.setSpeed(speed);
- mTvView.timeShiftSetPlaybackParams(params);
}
/**
@@ -1202,7 +1223,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* @param timeMs The time in milliseconds to seek to.
*/
public void timeshiftSeekTo(long timeMs) {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
return;
}
@@ -1216,7 +1237,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* Returns the current playback position in milliseconds.
*/
public long timeshiftGetCurrentPositionMs() {
- if (!TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.w(TAG, "Time shifting is not supported in this platform.");
return INVALID_TIME;
}
@@ -1241,9 +1262,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
public abstract void onAvailabilityChanged();
/**
- * Called when the record start time has been changed..
+ * Called when the record start time has been changed.
*/
public abstract void onRecordStartTimeChanged(long recordStartTimeMs);
+
+ /**
+ * Called when the record end time has been changed.
+ */
+ public abstract void onRecordEndTimeChanged(long recordEndTimeMs);
}
/**
diff --git a/src/com/android/tv/ui/TvOverlayManager.java b/src/com/android/tv/ui/TvOverlayManager.java
index 2bd4fcc5..124f3393 100644
--- a/src/com/android/tv/ui/TvOverlayManager.java
+++ b/src/com/android/tv/ui/TvOverlayManager.java
@@ -16,13 +16,26 @@
package com.android.tv.ui;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentManager.OnBackStackChangedListener;
+import android.content.Intent;
+import android.media.tv.TvInputInfo;
+import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
+import android.widget.Space;
import com.android.tv.ApplicationSingletons;
import com.android.tv.ChannelTuner;
@@ -33,34 +46,44 @@ import com.android.tv.TimeShiftManager;
import com.android.tv.TvApplication;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.WeakHandler;
+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.FullscreenDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.RecentlyWatchedDialogFragment;
import com.android.tv.dialog.SafeDismissDialogFragment;
+import com.android.tv.dvr.ui.DvrActivity;
import com.android.tv.guide.ProgramGuide;
import com.android.tv.menu.Menu;
import com.android.tv.menu.Menu.MenuShowReason;
import com.android.tv.menu.MenuRowFactory;
import com.android.tv.menu.MenuView;
+import com.android.tv.onboarding.NewSourcesFragment;
+import com.android.tv.onboarding.SetupSourcesFragment;
+import com.android.tv.onboarding.SetupSourcesFragment.InputSetupRunnable;
import com.android.tv.search.ProgramGuideSearchFragment;
import com.android.tv.ui.TvTransitionManager.SceneType;
-import com.android.tv.ui.sidepanel.AboutFragment;
+import com.android.tv.ui.sidepanel.SettingsFragment;
import com.android.tv.ui.sidepanel.SideFragmentManager;
import com.android.tv.ui.sidepanel.parentalcontrols.RatingsFragment;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
* A class responsible for the life cycle and event handling of the pop-ups over TV view.
*/
// TODO: Put TvTransitionManager into this class.
+@UiThread
public class TvOverlayManager {
private static final String TAG = "TvOverlayManager";
private static final boolean DEBUG = false;
- public static final String SETUP_TRACKER_LABEL = "Setup dialog";
public static final String INTRO_TRACKER_LABEL = "Intro dialog";
@Retention(RetentionPolicy.SOURCE)
@@ -68,50 +91,54 @@ public class TvOverlayManager {
value = {FLAG_HIDE_OVERLAYS_DEFAULT, FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION,
FLAG_HIDE_OVERLAYS_KEEP_SCENE, FLAG_HIDE_OVERLAYS_KEEP_DIALOG,
FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS, FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY,
- FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE, FLAG_HIDE_OVERLAYS_KEEP_MENU})
+ FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE, FLAG_HIDE_OVERLAYS_KEEP_MENU,
+ FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT})
public @interface HideOverlayFlag {}
// FLAG_HIDE_OVERLAYs must be bitwise exclusive.
- public static final int FLAG_HIDE_OVERLAYS_DEFAULT = 0b00000000;
- public static final int FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION = 0b00000010;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_SCENE = 0b00000100;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_DIALOG = 0b00001000;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS = 0b00010000;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY = 0b00100000;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE = 0b01000000;
- public static final int FLAG_HIDE_OVERLAYS_KEEP_MENU = 0b10000000;
-
- public static final int MSG_SHOW_DIALOG = 1000;
+ public static final int FLAG_HIDE_OVERLAYS_DEFAULT = 0b000000000;
+ public static final int FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION = 0b000000010;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_SCENE = 0b000000100;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_DIALOG = 0b000001000;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS = 0b000010000;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY = 0b000100000;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE = 0b001000000;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_MENU = 0b010000000;
+ public static final int FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT = 0b100000000;
+
+ public static final int MSG_OVERLAY_CLOSED = 1000;
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true,
value = {OVERLAY_TYPE_NONE, OVERLAY_TYPE_MENU, OVERLAY_TYPE_SIDE_FRAGMENT,
OVERLAY_TYPE_DIALOG, OVERLAY_TYPE_GUIDE, OVERLAY_TYPE_SCENE_CHANNEL_BANNER,
OVERLAY_TYPE_SCENE_INPUT_BANNER, OVERLAY_TYPE_SCENE_KEYPAD_CHANNEL_SWITCH,
- OVERLAY_TYPE_SCENE_SELECT_INPUT})
+ OVERLAY_TYPE_SCENE_SELECT_INPUT, OVERLAY_TYPE_FRAGMENT})
private @interface TvOverlayType {}
// OVERLAY_TYPEs must be bitwise exclusive.
- private static final int OVERLAY_TYPE_NONE = 0b00000000;
- private static final int OVERLAY_TYPE_MENU = 0b00000001;
- private static final int OVERLAY_TYPE_SIDE_FRAGMENT = 0b00000010;
- private static final int OVERLAY_TYPE_DIALOG = 0b00000100;
- private static final int OVERLAY_TYPE_GUIDE = 0b00001000;
- private static final int OVERLAY_TYPE_SCENE_CHANNEL_BANNER = 0b00010000;
- private static final int OVERLAY_TYPE_SCENE_INPUT_BANNER = 0b00100000;
- private static final int OVERLAY_TYPE_SCENE_KEYPAD_CHANNEL_SWITCH = 0b01000000;
- private static final int OVERLAY_TYPE_SCENE_SELECT_INPUT = 0b10000000;
+ private static final int OVERLAY_TYPE_NONE = 0b000000000;
+ private static final int OVERLAY_TYPE_MENU = 0b000000001;
+ private static final int OVERLAY_TYPE_SIDE_FRAGMENT = 0b000000010;
+ private static final int OVERLAY_TYPE_DIALOG = 0b000000100;
+ private static final int OVERLAY_TYPE_GUIDE = 0b000001000;
+ private static final int OVERLAY_TYPE_SCENE_CHANNEL_BANNER = 0b000010000;
+ private static final int OVERLAY_TYPE_SCENE_INPUT_BANNER = 0b000100000;
+ private static final int OVERLAY_TYPE_SCENE_KEYPAD_CHANNEL_SWITCH = 0b001000000;
+ private static final int OVERLAY_TYPE_SCENE_SELECT_INPUT = 0b010000000;
+ private static final int OVERLAY_TYPE_FRAGMENT = 0b100000000;
private static final Set<String> AVAILABLE_DIALOG_TAGS = new HashSet<>();
static {
AVAILABLE_DIALOG_TAGS.add(RecentlyWatchedDialogFragment.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(PinDialogFragment.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(FullscreenDialogFragment.DIALOG_TAG);
- AVAILABLE_DIALOG_TAGS.add(AboutFragment.LicenseActionItem.DIALOG_TAG);
+ AVAILABLE_DIALOG_TAGS.add(SettingsFragment.LicenseActionItem.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(RatingsFragment.AttributionItem.DIALOG_TAG);
}
private final MainActivity mMainActivity;
private final ChannelTuner mChannelTuner;
private final TvTransitionManager mTransitionManager;
+ private final ChannelDataManager mChannelDataManager;
private final Menu mMenu;
private final SideFragmentManager mSideFragmentManager;
private final ProgramGuide mProgramGuide;
@@ -120,10 +147,16 @@ public class TvOverlayManager {
private final ProgramGuideSearchFragment mSearchFragment;
private final Tracker mTracker;
private SafeDismissDialogFragment mCurrentDialog;
+ private final SetupSourcesFragment mSetupFragment;
+ private boolean mSetupFragmentActive;
+ private final NewSourcesFragment mNewSourcesFragment;
+ private boolean mNewSourcesFragmentActive;
private final Handler mHandler = new TvOverlayHandler(this);
private @TvOverlayType int mOpenedOverlays;
+ private List<Runnable> mPendingActions = new ArrayList<>();
+
public TvOverlayManager(MainActivity mainActivity, ChannelTuner channelTuner,
KeypadChannelSwitchView keypadChannelSwitchView,
ChannelBannerView channelBannerView, InputBannerView inputBannerView,
@@ -131,10 +164,11 @@ public class TvOverlayManager {
ProgramGuideSearchFragment searchFragment) {
mMainActivity = mainActivity;
mChannelTuner = channelTuner;
+ ApplicationSingletons singletons = TvApplication.getSingletons(mainActivity);
+ mChannelDataManager = singletons.getChannelDataManager();
mKeypadChannelSwitchView = keypadChannelSwitchView;
mSelectInputView = selectInputView;
mSearchFragment = searchFragment;
- ApplicationSingletons singletons = TvApplication.getSingletons(mainActivity);
mTracker = singletons.getTracker();
mTransitionManager = new TvTransitionManager(mainActivity, sceneContainer,
channelBannerView, inputBannerView, mKeypadChannelSwitchView, selectInputView);
@@ -194,9 +228,46 @@ public class TvOverlayManager {
}
};
mProgramGuide = new ProgramGuide(mainActivity, channelTuner,
- singletons.getTvInputManagerHelper(), singletons.getChannelDataManager(),
+ singletons.getTvInputManagerHelper(), mChannelDataManager,
singletons.getProgramDataManager(), singletons.getTracker(), preShowRunnable,
postHideRunnable);
+ mSetupFragment = new SetupSourcesFragment();
+ mSetupFragment.setOnActionClickListener(new OnActionClickListener() {
+ @Override
+ public void onActionClick(String category, int id) {
+ switch (id) {
+ case SetupMultiPaneFragment.ACTION_DONE:
+ closeSetupFragment(true);
+ break;
+ case SetupSourcesFragment.ACTION_PLAY_STORE:
+ mMainActivity.showMerchantCollection();
+ break;
+ }
+ }
+ });
+ mSetupFragment.setInputSetupRunnable(new InputSetupRunnable() {
+ @Override
+ public void runInputSetup(TvInputInfo input) {
+ mMainActivity.startSetupActivity(input, true);
+ }
+ });
+ mNewSourcesFragment = new NewSourcesFragment();
+ mNewSourcesFragment.setOnActionClickListener(new OnActionClickListener() {
+ @Override
+ public void onActionClick(String category, int id) {
+ switch (id) {
+ case NewSourcesFragment.ACTION_SETUP:
+ closeNewSourcesFragment(false);
+ showSetupFragment();
+ break;
+ case NewSourcesFragment.ACTION_SKIP:
+ // Don't remove the fragment because new fragment will be replaced with
+ // this fragment.
+ closeNewSourcesFragment(true);
+ break;
+ }
+ }
+ });
}
/**
@@ -230,6 +301,20 @@ public class TvOverlayManager {
}
/**
+ * Checks whether the setup fragment is active or not.
+ */
+ public boolean isSetupFragmentActive() {
+ return mSetupFragmentActive;
+ }
+
+ /**
+ * Checks whether the new sources fragment is active or not.
+ */
+ public boolean isNewSourcesFragmentActive() {
+ return mNewSourcesFragmentActive;
+ }
+
+ /**
* Returns the instance of {@link ProgramGuide}.
*/
public ProgramGuide getProgramGuide() {
@@ -261,14 +346,6 @@ public class TvOverlayManager {
*/
public void showDialogFragment(String tag, SafeDismissDialogFragment dialog,
boolean keepSidePanelHistory) {
- showDialogFragment(tag, dialog, keepSidePanelHistory, 0);
- }
-
- /**
- * Shows the given dialog with a delay {@code delayMillis}.
- */
- public void showDialogFragment(String tag, SafeDismissDialogFragment dialog,
- boolean keepSidePanelHistory, long delayMillis) {
int flags = FLAG_HIDE_OVERLAYS_KEEP_DIALOG;
if (keepSidePanelHistory) {
flags |= FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY;
@@ -279,17 +356,14 @@ public class TvOverlayManager {
return;
}
- // TODO: Consider showing multiple dialog at once.
- if (mCurrentDialog != null && mCurrentDialog.isAdded()) {
+ Fragment old = mMainActivity.getFragmentManager().findFragmentByTag(tag);
+ // Do not show the dialog if the same kind of dialog is already opened.
+ if (old != null) {
return;
}
mCurrentDialog = dialog;
- if (delayMillis == 0) {
- dialog.show(mMainActivity.getFragmentManager(), tag);
- } else {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_DIALOG, tag), delayMillis);
- }
+ dialog.show(mMainActivity.getFragmentManager(), tag);
// Calling this from SafeDismissDialogFragment.onCreated() might be late
// because it takes time for onCreated to be called
@@ -297,21 +371,101 @@ public class TvOverlayManager {
onOverlayOpened(OVERLAY_TYPE_DIALOG);
}
+ private void runAfterSideFragmentsAreClosed(final Runnable runnable) {
+ final FragmentManager manager = mMainActivity.getFragmentManager();
+ if (mSideFragmentManager.isSidePanelVisible()) {
+ manager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
+ @Override
+ public void onBackStackChanged() {
+ if (manager.getBackStackEntryCount() == 0) {
+ manager.removeOnBackStackChangedListener(this);
+ runnable.run();
+ }
+ }
+ });
+ } else {
+ runnable.run();
+ }
+ }
+
+ private void showFragment(final Fragment fragment) {
+ hideOverlays(FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
+ onOverlayOpened(OVERLAY_TYPE_FRAGMENT);
+ runAfterSideFragmentsAreClosed(new Runnable() {
+ @Override
+ public void run() {
+ mMainActivity.getFragmentManager().beginTransaction()
+ .replace(R.id.fragment_container, fragment).commit();
+ }
+ });
+ }
+
+ private void closeFragment(Fragment fragmentToRemove) {
+ onOverlayClosed(OVERLAY_TYPE_FRAGMENT);
+ if (fragmentToRemove != null) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ // In L, NPE happens if there is no next fragment when removing or hiding a fragment
+ // which has an exit transition. b/22631964
+ // A workaround is just replacing with a dummy fragment.
+ mMainActivity.getFragmentManager().beginTransaction()
+ .replace(R.id.fragment_container, new DummyFragment()).commit();
+ } else {
+ mMainActivity.getFragmentManager().beginTransaction().remove(fragmentToRemove)
+ .commit();
+ }
+ }
+ }
+
/**
* Shows setup dialog.
*/
- public void showSetupDialog() {
- showSetupDialog(0);
+ public void showSetupFragment() {
+ if (DEBUG) Log.d(TAG, "showSetupFragment");
+ mSetupFragmentActive = true;
+ SetupSourcesFragment.setTheme(R.style.Theme_TV_GuidedStep);
+ mSetupFragment.enableFragmentTransition(SetupFragment.FRAGMENT_ENTER_TRANSITION
+ | SetupFragment.FRAGMENT_EXIT_TRANSITION | SetupFragment.FRAGMENT_RETURN_TRANSITION
+ | SetupFragment.FRAGMENT_REENTER_TRANSITION);
+ mSetupFragment.setFragmentTransition(SetupFragment.FRAGMENT_EXIT_TRANSITION, Gravity.END);
+ showFragment(mSetupFragment);
+ }
+
+ // Set removeFragment to false only when the new fragment is going to be shown.
+ private void closeSetupFragment(boolean removeFragment) {
+ if (DEBUG) Log.d(TAG, "closeSetupFragment");
+ if (!mSetupFragmentActive) {
+ return;
+ }
+ mSetupFragmentActive = false;
+ SetupSourcesFragment.setTheme(SetupSourcesFragment.DEFAULT_THEME);
+ closeFragment(removeFragment ? mSetupFragment : null);
+ if (mChannelDataManager.getChannelCount() == 0) {
+ mMainActivity.finish();
+ }
}
/**
- * Shows setup dialog with a delay {@code delayMillis}.
+ * Shows new sources dialog.
*/
- public void showSetupDialog(long delayMillis) {
- if (DEBUG) Log.d(TAG,"showSetupDialog");
- showDialogFragment(FullscreenDialogFragment.DIALOG_TAG,
- new FullscreenDialogFragment(R.layout.setup_dialog, SETUP_TRACKER_LABEL), false,
- delayMillis);
+ public void showNewSourcesFragment() {
+ if (DEBUG) Log.d(TAG, "showNewSourcesFragment");
+ mNewSourcesFragmentActive = true;
+ showFragment(mNewSourcesFragment);
+ }
+
+ // Set removeFragment to false only when the new fragment is going to be shown.
+ private void closeNewSourcesFragment(boolean removeFragment) {
+ if (DEBUG) Log.d(TAG, "closeNewSourcesFragment");
+ mNewSourcesFragmentActive = false;
+ closeFragment(removeFragment ? mNewSourcesFragment : null);
+ }
+
+ /**
+ * Shows DVR manager.
+ */
+ public void showDvrManager() {
+ Intent intent = new Intent(mMainActivity, DvrActivity.class);
+ mMainActivity.startActivity(intent);
}
/**
@@ -320,7 +474,8 @@ public class TvOverlayManager {
public void showIntroDialog() {
if (DEBUG) Log.d(TAG,"showIntroDialog");
showDialogFragment(FullscreenDialogFragment.DIALOG_TAG,
- new FullscreenDialogFragment(R.layout.intro_dialog, INTRO_TRACKER_LABEL), false);
+ FullscreenDialogFragment.newInstance(R.layout.intro_dialog, INTRO_TRACKER_LABEL),
+ false);
}
/**
@@ -341,7 +496,8 @@ public class TvOverlayManager {
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_DIALOG
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
mTransitionManager.goToKeypadChannelSwitchScene();
}
@@ -385,8 +541,8 @@ public class TvOverlayManager {
*/
// TODO: Add test for this method.
public void hideOverlays(@HideOverlayFlag int flags) {
- if (mMainActivity.needToKeepDialogWhenHidingOverlay()) {
- flags |= FLAG_HIDE_OVERLAYS_KEEP_DIALOG;
+ if (mMainActivity.needToKeepSetupScreenWhenHidingOverlay()) {
+ flags |= FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT;
}
if ((flags & FLAG_HIDE_OVERLAYS_KEEP_DIALOG) != 0) {
// Keeps the dialog.
@@ -398,18 +554,24 @@ public class TvOverlayManager {
// to null.
((PinDialogFragment) mCurrentDialog).setResultListener(null);
}
- if (mHandler.hasMessages(MSG_SHOW_DIALOG)) {
- mHandler.removeMessages(MSG_SHOW_DIALOG);
- onDialogDestroyed();
- } else {
- mCurrentDialog.dismiss();
- }
+ mCurrentDialog.dismiss();
}
mCurrentDialog = null;
}
-
boolean withAnimation = (flags & FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION) == 0;
+ if ((flags & FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT) == 0) {
+ if (mSetupFragmentActive) {
+ if (!withAnimation) {
+ mSetupFragment.setReturnTransition(null);
+ mSetupFragment.setExitTransition(null);
+ }
+ closeSetupFragment(true);
+ } else if (mNewSourcesFragmentActive) {
+ closeNewSourcesFragment(true);
+ }
+ }
+
if ((flags & FLAG_HIDE_OVERLAYS_KEEP_MENU) != 0) {
// Keeps the menu.
} else {
@@ -441,10 +603,12 @@ public class TvOverlayManager {
* UIs except banner is shown, the informational text needs to be hidden for clean UI.
*/
public boolean needHideTextOnMainView() {
- return getSideFragmentManager().isActive()
+ return mSideFragmentManager.isActive()
|| getMenu().isActive()
|| mTransitionManager.isKeypadChannelSwitchActive()
- || mTransitionManager.isSelectInputActive();
+ || mTransitionManager.isSelectInputActive()
+ || mSetupFragmentActive
+ || mNewSourcesFragmentActive;
}
@TvOverlayType private int convertSceneToOverlayType(@SceneType int sceneType) {
@@ -463,37 +627,61 @@ public class TvOverlayManager {
}
}
+ @UiThread
private void onOverlayOpened(@TvOverlayType int overlayType) {
if (DEBUG) Log.d(TAG, "Overlay opened: 0b" + Integer.toBinaryString(overlayType));
mOpenedOverlays |= overlayType;
if (DEBUG) Log.d(TAG, "Opened overlays: 0b" + Integer.toBinaryString(mOpenedOverlays));
+ mHandler.removeMessages(MSG_OVERLAY_CLOSED);
mMainActivity.updateKeyInputFocus();
}
+ @UiThread
private void onOverlayClosed(@TvOverlayType int overlayType) {
if (DEBUG) Log.d(TAG, "Overlay closed: 0b" + Integer.toBinaryString(overlayType));
mOpenedOverlays &= ~overlayType;
if (DEBUG) Log.d(TAG, "Opened overlays: 0b" + Integer.toBinaryString(mOpenedOverlays));
+ mHandler.removeMessages(MSG_OVERLAY_CLOSED);
mMainActivity.updateKeyInputFocus();
- boolean onlyBannerOrNoneOpened = (mOpenedOverlays & ~OVERLAY_TYPE_SCENE_CHANNEL_BANNER
- & ~OVERLAY_TYPE_SCENE_INPUT_BANNER) == 0;
// Show the main menu again if there are no pop-ups or banners only.
// The main menu should not be shown when the activity is in paused state.
- boolean wasMenuShown = false;
- if (mMainActivity.isActivityResumed() && onlyBannerOrNoneOpened) {
- wasMenuShown = showMenuWithTimeShiftPauseIfNeeded();
+ boolean menuAboutToShow = false;
+ if (canExecuteCloseAction()) {
+ menuAboutToShow = mMainActivity.getTimeShiftManager().isPaused();
+ mHandler.sendEmptyMessage(MSG_OVERLAY_CLOSED);
}
// Don't set screen name to main if the overlay closing is a banner
// or if a non banner overlay is still open
// or if we just opened the menu
if (overlayType != OVERLAY_TYPE_SCENE_CHANNEL_BANNER
&& overlayType != OVERLAY_TYPE_SCENE_INPUT_BANNER
- && onlyBannerOrNoneOpened
- && !wasMenuShown) {
+ && isOnlyBannerOrNoneOpened()
+ && !menuAboutToShow) {
mTracker.sendScreenView(MainActivity.SCREEN_NAME);
}
}
+ private boolean canExecuteCloseAction() {
+ return mMainActivity.isActivityResumed() && isOnlyBannerOrNoneOpened();
+ }
+
+ private boolean isOnlyBannerOrNoneOpened() {
+ return (mOpenedOverlays & ~OVERLAY_TYPE_SCENE_CHANNEL_BANNER
+ & ~OVERLAY_TYPE_SCENE_INPUT_BANNER) == 0;
+ }
+
+ /**
+ * Runs a given {@code action} after all the overlays are closed.
+ */
+ @UiThread
+ public void runAfterOverlaysAreClosed(Runnable action) {
+ if (canExecuteCloseAction()) {
+ action.run();
+ } else {
+ mPendingActions.add(action);
+ }
+ }
+
/**
* Handles the onUserInteraction event of the {@link MainActivity}.
*/
@@ -520,7 +708,8 @@ public class TvOverlayManager {
// Consumes the keys which may trigger system's default music player.
return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
}
- if (mMenu.isActive() || mSideFragmentManager.isActive() || mProgramGuide.isActive()) {
+ if (mMenu.isActive() || mSideFragmentManager.isActive() || mProgramGuide.isActive()
+ || mSetupFragmentActive || mNewSourcesFragmentActive) {
return MainActivity.KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY;
}
if (mTransitionManager.isKeypadChannelSwitchActive()) {
@@ -547,7 +736,9 @@ public class TvOverlayManager {
|| mSideFragmentManager.isActive()
|| mSearchFragment.isVisible()
|| mTransitionManager.isKeypadChannelSwitchActive()
- || mTransitionManager.isSelectInputActive()) {
+ || mTransitionManager.isSelectInputActive()
+ || mSetupFragmentActive
+ || mNewSourcesFragmentActive) {
// Do not handle media key when any pop-ups which can handle keys are active.
return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
}
@@ -625,7 +816,8 @@ public class TvOverlayManager {
timeShiftManager.play();
}
hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG);
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
}
if (mMenu.isActive()) {
@@ -654,6 +846,20 @@ public class TvOverlayManager {
MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED
: MainActivity.KEY_EVENT_HANDLER_RESULT_NOT_HANDLED;
}
+ if (mSetupFragmentActive) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ closeSetupFragment(true);
+ return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
+ }
+ return MainActivity.KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY;
+ }
+ if (mNewSourcesFragmentActive) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ closeNewSourcesFragment(true);
+ return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
+ }
+ return MainActivity.KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY;
+ }
return MainActivity.KEY_EVENT_HANDLER_RESULT_PASSTHROUGH;
}
@@ -681,11 +887,34 @@ public class TvOverlayManager {
@Override
public void handleMessage(Message msg, @NonNull TvOverlayManager tvOverlayManager) {
- if (msg.what == MSG_SHOW_DIALOG) {
- String tag = (String) msg.obj;
- tvOverlayManager.mCurrentDialog
- .show(tvOverlayManager.mMainActivity.getFragmentManager(), tag);
+ switch (msg.what) {
+ case MSG_OVERLAY_CLOSED:
+ if (!tvOverlayManager.canExecuteCloseAction()) {
+ return;
+ }
+ if (tvOverlayManager.showMenuWithTimeShiftPauseIfNeeded()) {
+ return;
+ }
+ if (!tvOverlayManager.mPendingActions.isEmpty()) {
+ Runnable action = tvOverlayManager.mPendingActions.get(0);
+ tvOverlayManager.mPendingActions.remove(action);
+ action.run();
+ }
+ break;
}
}
}
+
+ /**
+ * Dummny class for the workaround of b/22631964. See {@link #closeFragment}.
+ */
+ public static class DummyFragment extends Fragment {
+ @Override
+ public @Nullable View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View v = new Space(inflater.getContext());
+ v.setVisibility(View.GONE);
+ return v;
+ }
+ }
}
diff --git a/src/com/android/tv/ui/sidepanel/AboutFragment.java b/src/com/android/tv/ui/sidepanel/AboutFragment.java
deleted file mode 100644
index ee83e21e..00000000
--- a/src/com/android/tv/ui/sidepanel/AboutFragment.java
+++ /dev/null
@@ -1,187 +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.app.Activity;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Build;
-import android.provider.Settings;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.tv.Features;
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.analytics.OptOutPreferenceHelper;
-import com.android.tv.dialog.WebDialogFragment;
-import com.android.tv.license.LicenseUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Shows version, optional license information and Analytics OptOut.
- */
-public class AboutFragment extends SideFragment {
- private static final String TRACKER_LABEL = "about";
-
- /**
- * Shows the application version name.
- */
- private static final class VersionItem extends Item {
- @Override
- protected int getResourceId() {
- return R.layout.option_item_simple;
- }
-
- @Override
- protected void onBind(View view) {
- super.onBind(view);
- TextView titleView = (TextView) view.findViewById(R.id.title);
- titleView.setText(R.string.about_menu_version);
- TextView descriptionView = (TextView) view.findViewById(R.id.description);
- descriptionView.setText(TvApplication.getVersionName());
- }
-
- @Override
- protected void onSelected() {
- }
- }
-
- /**
- * 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.about_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);
- }
- }
-
- /**
- * Sets the users preference for allowing analytics.
- */
- private static final class AllowAnalyticsItem extends SwitchItem {
- //TODO: change this to use SwitchPreference
- private final OptOutPreferenceHelper mPreferenceHelper;
- private TextView mDescriptionView;
- private int mOriginalMaxDescriptionLine;
- private MainActivity mMainActivity;
- private View mBoundView;
-
- public AllowAnalyticsItem(Context context) {
- super(context.getResources().getString(R.string.about_menu_improve),
- context.getResources().getString(R.string.about_menu_improve),
- context.getResources().getString(R.string.about_menu_improve_summary));
- mPreferenceHelper = TvApplication.getSingletons(context).getOptPreferenceHelper();
- }
-
- @Override
- protected void onBind(View view) {
- super.onBind(view);
- mDescriptionView = (TextView) view.findViewById(getDescriptionViewId());
- mOriginalMaxDescriptionLine = mDescriptionView.getMaxLines();
- mDescriptionView.setMaxLines(Integer.MAX_VALUE);
- mMainActivity = (MainActivity) view.getContext();
- mBoundView = view;
- }
-
- @Override
- protected void onUnbind() {
- super.onUnbind();
- mDescriptionView.setMaxLines(mOriginalMaxDescriptionLine);
- mDescriptionView = null;
- mMainActivity = null;
- mBoundView = null;
- }
-
- @Override
- protected void onUpdate() {
- super.onUpdate();
- setChecked(!mPreferenceHelper
- .getOptOutPreference(OptOutPreferenceHelper.ANALYTICS_OPT_OUT_DEFAULT_VALUE));
- }
-
- @Override
- protected void onSelected() {
- super.onSelected();
- mPreferenceHelper.setOptOutPreference(!isChecked());
- }
-
- @Override
- public void setChecked(boolean checked) {
- super.setChecked(checked);
- if (mMainActivity != null && mBoundView != null && mBoundView.hasFocus()) {
- // Quick fix for accessibility
- // TODO: Need to change the resource in the future.
- mMainActivity.sendAccessibilityText(
- checked ? mMainActivity.getString(R.string.options_item_pip_on)
- : mMainActivity.getString(R.string.options_item_pip_off));
- }
- }
- }
-
- @Override
- protected String getTitle() {
- return getResources().getString(R.string.side_panel_title_about);
- }
-
- @Override
- public String getTrackerLabel() {
- return TRACKER_LABEL;
- }
-
- @Override
- protected List<Item> getItemList() {
- List<Item> items = new ArrayList<>();
- items.add(new VersionItem());
- Activity activity = getActivity();
- if (LicenseUtils.hasLicenses(activity.getAssets())) {
- items.add(new LicenseActionItem((MainActivity) activity));
- }
- if (Features.ANALYTICS_OPT_OUT.isEnabled(activity)) {
- items.add(new AllowAnalyticsItem(activity));
- }
- boolean developerOptionEnabled = Settings.Secure.getInt(getActivity().getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0) != 0;
- if (Features.DEVELOPER_OPTION.isEnabled(getActivity()) && developerOptionEnabled
- && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Resources res = getActivity().getResources();
- items.add(new ActionItem(res.getString(R.string.side_panel_title_developer)) {
- @Override
- protected void onSelected() {
- getMainActivity().getOverlayManager().getSideFragmentManager().show(
- new DeveloperFragment());
- }
- });
- }
- return items;
- }
-}
diff --git a/src/com/android/tv/ui/sidepanel/ChannelSourcesFragment.java b/src/com/android/tv/ui/sidepanel/ChannelSourcesFragment.java
deleted file mode 100644
index 7289034f..00000000
--- a/src/com/android/tv/ui/sidepanel/ChannelSourcesFragment.java
+++ /dev/null
@@ -1,104 +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.view.View;
-import android.widget.Toast;
-
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.util.SetupUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ChannelSourcesFragment extends SideFragment {
- private static final String TRACKER_LABEL = "channel sources";
-
- private static int ADDITIONAL_DELAY_TO_SHOW_SETUP_DIALOG_MILLIS = 50;
-
- private final long mCurrentChannelId;
-
- public ChannelSourcesFragment(long currentChannelId) {
- mCurrentChannelId = currentChannelId;
- }
-
- @Override
- protected String getTitle() {
- return getString(R.string.side_panel_title_channel_sources);
- }
-
- @Override
- public String getTrackerLabel() {
- return TRACKER_LABEL;
- }
-
- @Override
- protected List<Item> getItemList() {
- List<Item> items = new ArrayList<>();
- final Item customizeChannelListItem = new SubMenuItem(
- getString(R.string.channel_source_item_customize_channels),
- getString(R.string.channel_source_item_customize_channels_description),
- 0, getMainActivity().getOverlayManager().getSideFragmentManager()) {
- @Override
- protected SideFragment getFragment() {
- return new CustomizeChannelListFragment(mCurrentChannelId);
- }
-
- @Override
- protected void onBind(View view) {
- super.onBind(view);
- setEnabled(false);
- }
-
- @Override
- protected void onUpdate() {
- super.onUpdate();
- setEnabled(getChannelDataManager().getChannelCount() != 0);
- }
- };
- customizeChannelListItem.setEnabled(false);
- items.add(customizeChannelListItem);
- final MainActivity activity = getMainActivity();
- boolean hasNewInput = SetupUtils.getInstance(activity).hasNewInput(
- activity.getTvInputManagerHelper());
- items.add(new ActionItem(
- getString(R.string.channel_source_item_setup),
- hasNewInput ? getString(R.string.channel_source_item_setup_new_inputs)
- : null) {
- @Override
- protected void onSelected() {
- closeFragment();
- // Running two animations at the same time causes performance drop.
- // Show the setup dialog with delayed animation.
- activity.getOverlayManager().showSetupDialog(
- activity.getResources().getInteger(R.integer.side_panel_anim_short_duration)
- + ADDITIONAL_DELAY_TO_SHOW_SETUP_DIALOG_MILLIS);
- }
- });
- return items;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (getChannelDataManager().areAllChannelsHidden()) {
- Toast.makeText(getActivity(), R.string.msg_all_channels_hidden, Toast.LENGTH_SHORT)
- .show();
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/ui/sidepanel/DeveloperFragment.java b/src/com/android/tv/ui/sidepanel/DeveloperFragment.java
index 13f6c866..44b4d452 100644
--- a/src/com/android/tv/ui/sidepanel/DeveloperFragment.java
+++ b/src/com/android/tv/ui/sidepanel/DeveloperFragment.java
@@ -18,18 +18,10 @@ package com.android.tv.ui.sidepanel;
import android.app.Activity;
import android.content.Context;
-import android.content.res.Resources;
-import android.provider.Settings;
import android.view.View;
-import android.widget.TextView;
import com.android.tv.Features;
-import com.android.tv.MainActivity;
import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.analytics.OptOutPreferenceHelper;
-import com.android.tv.dialog.WebDialogFragment;
-import com.android.tv.license.LicenseUtils;
import java.util.ArrayList;
import java.util.List;
@@ -67,32 +59,6 @@ public class DeveloperFragment extends SideFragment {
}
}
- /**
- * Shows AC3 capability of the connected TV.
- */
- private static final class Ac3CapabilityItem extends Item {
- @Override
- protected int getResourceId() {
- return R.layout.option_item_simple;
- }
-
- @Override
- protected void onBind(View view) {
- super.onBind(view);
- TextView titleView = (TextView) view.findViewById(R.id.title);
- titleView.setText(R.string.developer_menu_ac3_support);
- TextView descriptionView = (TextView) view.findViewById(R.id.description);
- Resources res = view.getContext().getResources();
- boolean ac3Support = ((MainActivity) view.getContext()).isAc3PassthroughSupported();
- descriptionView.setText(ac3Support ? R.string.developer_menu_ac3_support_yes
- : R.string.developer_menu_ac3_support_no);
- }
-
- @Override
- protected void onSelected() {
- }
- }
-
@Override
protected String getTitle() {
return getResources().getString(R.string.side_panel_title_developer);
@@ -108,7 +74,11 @@ public class DeveloperFragment extends SideFragment {
List<Item> items = new ArrayList<>();
Activity activity = getActivity();
items.add(new UsbTvTunerItem(activity));
- items.add(new Ac3CapabilityItem());
+ boolean ac3Support = getMainActivity().isAc3PassthroughSupported();
+ // Show AC3 passthrough availability.
+ items.add(new SimpleItem(getString(R.string.developer_menu_ac3_support),
+ getString(ac3Support ? R.string.developer_menu_ac3_support_yes
+ : R.string.developer_menu_ac3_support_no)));
return items;
}
}
diff --git a/src/com/android/tv/ui/sidepanel/Item.java b/src/com/android/tv/ui/sidepanel/Item.java
index 4ae6e523..00f16427 100644
--- a/src/com/android/tv/ui/sidepanel/Item.java
+++ b/src/com/android/tv/ui/sidepanel/Item.java
@@ -16,9 +16,11 @@
package com.android.tv.ui.sidepanel;
+import android.support.annotation.UiThread;
import android.view.View;
import android.view.ViewGroup;
+@UiThread
public abstract class Item {
private View mItemView;
private boolean mEnabled = true;
diff --git a/src/com/android/tv/ui/sidepanel/SettingsFragment.java b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
new file mode 100644
index 00000000..6b5b2584
--- /dev/null
+++ b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
@@ -0,0 +1,185 @@
+/*
+ * 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.content.res.Resources;
+import android.os.Build;
+import android.provider.Settings;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.tv.Features;
+import com.android.tv.MainActivity;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+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.util.PermissionUtils;
+import com.android.tv.util.SetupUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Shows Live TV settings.
+ */
+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);
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return TRACKER_LABEL;
+ }
+
+ @Override
+ protected List<Item> getItemList() {
+ 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, getMainActivity().getOverlayManager().getSideFragmentManager()) {
+ @Override
+ protected SideFragment getFragment() {
+ return new CustomizeChannelListFragment(mCurrentChannelId);
+ }
+
+ @Override
+ protected void onBind(View view) {
+ super.onBind(view);
+ setEnabled(false);
+ }
+
+ @Override
+ protected void onUpdate() {
+ super.onUpdate();
+ setEnabled(getChannelDataManager().getChannelCount() != 0);
+ }
+ };
+ customizeChannelListItem.setEnabled(false);
+ items.add(customizeChannelListItem);
+ final MainActivity activity = getMainActivity();
+ boolean hasNewInput = SetupUtils.getInstance(activity).hasNewInput(
+ activity.getTvInputManagerHelper());
+ items.add(new ActionItem(
+ getString(R.string.settings_channel_source_item_setup),
+ hasNewInput ? getString(R.string.settings_channel_source_item_setup_new_inputs)
+ : null) {
+ @Override
+ protected void onSelected() {
+ closeFragment();
+ activity.getOverlayManager().showSetupFragment();
+ }
+ });
+ if (PermissionUtils.hasModifyParentalControls(getMainActivity())) {
+ items.add(new ActionItem(getString(R.string.settings_parental_controls),
+ getString(activity.getParentalControlSettings().isParentalControlsEnabled()
+ ? R.string.option_toggle_parental_controls_on
+ : 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().showDialogFragment(PinDialogFragment.DIALOG_TAG,
+ fragment, true);
+ }
+ });
+ } else {
+ // Note: parental control is turned off, when MODIFY_PARENTAL_CONTROLS is not granted.
+ // 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 developerOptionEnabled = Settings.Secure.getInt(getActivity().getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0) != 0;
+ if (Features.DEVELOPER_OPTION.isEnabled(getActivity()) && developerOptionEnabled
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ Resources res = getActivity().getResources();
+ items.add(new ActionItem(res.getString(R.string.side_panel_title_developer)) {
+ @Override
+ protected void onSelected() {
+ getMainActivity().getOverlayManager().getSideFragmentManager().show(
+ new DeveloperFragment());
+ }
+ });
+ }
+ // Show version.
+ items.add(new SimpleItem(getString(R.string.settings_menu_version),
+ ((TvApplication) activity.getApplicationContext()).getVersionName()));
+ return items;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (getChannelDataManager().areAllChannelsHidden()) {
+ Toast.makeText(getActivity(), R.string.msg_all_channels_hidden, Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+}
diff --git a/src/com/android/tv/ui/sidepanel/SideFragmentManager.java b/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
index b1041629..faccbc66 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
@@ -86,7 +86,17 @@ public class SideFragmentManager {
return mHideAnimator.isStarted();
}
+ /**
+ * Shows the given {@link SideFragment}.
+ */
public void show(SideFragment sideFragment) {
+ show(sideFragment, true);
+ }
+
+ /**
+ * Shows the given {@link SideFragment}.
+ */
+ public void show(SideFragment sideFragment, boolean showEnterAnimation) {
SideFragment.preloadRecycledViews(mActivity);
if (isHiding()) {
mHideAnimator.end();
@@ -101,7 +111,7 @@ public class SideFragmentManager {
FragmentTransaction ft = mFragmentManager.beginTransaction();
if (!isFirst) {
ft.setCustomAnimations(
- R.animator.side_panel_fragment_enter,
+ showEnterAnimation ? R.animator.side_panel_fragment_enter : 0,
R.animator.side_panel_fragment_exit,
R.animator.side_panel_fragment_pop_enter,
R.animator.side_panel_fragment_pop_exit);
diff --git a/src/com/android/tv/ui/sidepanel/SimpleItem.java b/src/com/android/tv/ui/sidepanel/SimpleItem.java
new file mode 100644
index 00000000..52a5f13f
--- /dev/null
+++ b/src/com/android/tv/ui/sidepanel/SimpleItem.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 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/util/BitmapUtils.java b/src/com/android/tv/util/BitmapUtils.java
index fd07507a..78b77e65 100644
--- a/src/com/android/tv/util/BitmapUtils.java
+++ b/src/com/android/tv/util/BitmapUtils.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -37,7 +36,7 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
-public class BitmapUtils {
+public final class BitmapUtils {
private static final String TAG = "BitmapUtils";
private static final boolean DEBUG = false;
@@ -52,12 +51,8 @@ public class BitmapUtils {
private BitmapUtils() { /* cannot be instantiated */ }
public static Bitmap scaleBitmap(Bitmap bm, int maxWidth, int maxHeight) {
- Bitmap result;
Rect rect = calculateNewSize(bm, maxWidth, maxHeight);
- result = Bitmap.createBitmap(rect.right, rect.bottom, bm.getConfig());
- Canvas canvas = new Canvas(result);
- canvas.drawBitmap(bm, null, rect, null);
- return result;
+ return Bitmap.createScaledBitmap(bm, rect.right, rect.bottom, false);
}
private static Rect calculateNewSize(Bitmap bm, int maxWidth, int maxHeight) {
diff --git a/src/com/android/tv/util/ImageCache.java b/src/com/android/tv/util/ImageCache.java
index e849da89..db64d4c9 100644
--- a/src/com/android/tv/util/ImageCache.java
+++ b/src/com/android/tv/util/ImageCache.java
@@ -20,6 +20,7 @@ import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.LruCache;
+import com.android.tv.common.MemoryManageable;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
/**
diff --git a/src/com/android/tv/util/ImageLoader.java b/src/com/android/tv/util/ImageLoader.java
index 8e901dd0..59c4983b 100644
--- a/src/com/android/tv/util/ImageLoader.java
+++ b/src/com/android/tv/util/ImageLoader.java
@@ -22,18 +22,22 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.tv.TvInputInfo;
import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.android.tv.R;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
-import java.util.ArrayList;
+import java.lang.ref.WeakReference;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
@@ -45,15 +49,46 @@ public final class ImageLoader {
private static final String TAG = "ImageLoader";
private static final boolean DEBUG = false;
+ private static Handler sMainHandler;
+
/**
- * Interface definition for a callback to be invoked when image loading is finished.
+ * Handles when image loading is finished.
+ *
+ * <p>Use this to prevent leaking an Activity or other Context while image loading is
+ * still pending. When you extend this class you <strong>MUST NOT</strong> use a non static
+ * inner class, or the containing object will still be leaked.
*/
@UiThread
- public interface ImageLoaderCallback {
+ public static abstract class ImageLoaderCallback<T> {
+ private final WeakReference<T> mWeakReference;
+
+ /**
+ * Creates an callback keeping a weak reference to {@code referent}.
+ *
+ * <p> If the "referent" is no longer valid, it no longer makes sense to run the
+ * callback. The referent is the View, or Activity or whatever that actually needs to
+ * receive the Bitmap. If the referent has been GC, then no need to run the callback.
+ */
+ public ImageLoaderCallback(T referent) {
+ mWeakReference = new WeakReference<>(referent);
+ }
+
/**
* Called when bitmap is loaded.
*/
- void onBitmapLoaded(@Nullable Bitmap bitmap);
+ private void onBitmapLoaded(@Nullable Bitmap bitmap) {
+ T referent = mWeakReference.get();
+ if (referent != null) {
+ onBitmapLoaded(referent, bitmap);
+ } else {
+ if (DEBUG) Log.d(TAG, "onBitmapLoaded not called because weak reference is gone");
+ }
+ }
+
+ /**
+ * Called when bitmap is loaded if the weak reference is still valid.
+ */
+ public abstract void onBitmapLoaded(T referent, @Nullable Bitmap bitmap);
}
private static final Map<String, LoadBitmapTask> sPendingListMap = new HashMap<>();
@@ -62,14 +97,26 @@ public final class ImageLoader {
* Preload a bitmap image into the cache.
*
* <p>Not to make heavy CPU load, AsyncTask.SERIAL_EXECUTOR is used for the image loading.
+ * <p>This method is thread safe.
*/
- @UiThread
- public static void prefetchBitmap(Context context, String uriString,
- int maxWidth, int maxHeight) {
- if (DEBUG) {
- Log.d(TAG, "prefetchBitmap() " + uriString);
+ public static void prefetchBitmap(Context context, final String uriString, final int maxWidth,
+ final int maxHeight) {
+ if (DEBUG) Log.d(TAG, "prefetchBitmap() " + uriString);
+ if (Looper.getMainLooper() == Looper.myLooper()) {
+ doLoadBitmap(context, uriString, maxWidth, maxHeight, null, AsyncTask.SERIAL_EXECUTOR);
+ } else {
+ final Context appContext = context.getApplicationContext();
+ getMainHandler().post(new Runnable() {
+ @Override
+ @MainThread
+ public void run() {
+ // Calling from the main thread prevents a ConcurrentModificationException
+ // in LoadBitmapTask.onPostExecute
+ doLoadBitmap(appContext, uriString, maxWidth, maxHeight, null,
+ AsyncTask.SERIAL_EXECUTOR);
+ }
+ });
}
- doLoadBitmap(context, uriString, maxWidth, maxHeight, null, AsyncTask.SERIAL_EXECUTOR);
}
/**
@@ -138,6 +185,7 @@ public final class ImageLoader {
/**
* @return {@code true} if the load is complete and the callback is executed.
*/
+ @UiThread
private static boolean doLoadBitmap(ImageLoaderCallback callback, Executor executor,
LoadBitmapTask loadBitmapTask) {
ScaledBitmapInfo bitmapInfo = loadBitmapTask.getFromCache();
@@ -149,7 +197,7 @@ public final class ImageLoader {
return true;
}
LoadBitmapTask existingTask = sPendingListMap.get(loadBitmapTask.getKey());
- if (existingTask != null && !loadBitmapTask.isReloadNeeded(existingTask) ) {
+ if (existingTask != null && !loadBitmapTask.isReloadNeeded(existingTask)) {
// The image loading is already scheduled and is large enough.
if (callback != null) {
existingTask.mCallbacks.add(callback);
@@ -169,15 +217,16 @@ public final class ImageLoader {
return false;
}
-/**
- * Loads and caches a a possibly scaled down version of a bitmap.
- *
- * <p>Implement {@link #doGetBitmapInBackground()} to to the actual loading.
- */
+ /**
+ * Loads and caches a a possibly scaled down version of a bitmap.
+ *
+ * <p>Implement {@link #doGetBitmapInBackground} to do the actual loading.
+ */
public static abstract class LoadBitmapTask extends AsyncTask<Void, Void, ScaledBitmapInfo> {
+ protected final Context mAppContext;
protected final int mMaxWidth;
protected final int mMaxHeight;
- private final List<ImageLoader.ImageLoaderCallback> mCallbacks = new ArrayList<>();
+ private final Set<ImageLoaderCallback> mCallbacks = CollectionUtils.createSmallSet();
private final ImageCache mImageCache;
private final String mKey;
@@ -191,11 +240,12 @@ public final class ImageLoader {
.needToReload(mMaxWidth, mMaxHeight);
if (DEBUG) {
if (needToReload) {
- Log.d(TAG, "Bitmap needs to be reloaded. {originalWidth="
- + bitmapInfo.bitmap.getWidth() + ", originalHeight="
- + bitmapInfo.bitmap.getHeight() + ", reqWidth=" + mMaxWidth
- + ", reqHeight="
- + mMaxHeight);
+ Log.d(TAG, "Bitmap needs to be reloaded. {"
+ + "originalWidth=" + bitmapInfo.bitmap.getWidth()
+ + ", originalHeight=" + bitmapInfo.bitmap.getHeight()
+ + ", reqWidth=" + mMaxWidth
+ + ", reqHeight=" + mMaxHeight
+ + "}");
}
}
return needToReload;
@@ -213,11 +263,14 @@ public final class ImageLoader {
return mImageCache.get(mKey);
}
- public LoadBitmapTask(ImageCache imageCache, String key, int maxHeight, int maxWidth) {
+ public LoadBitmapTask(Context context, ImageCache imageCache, String key, int maxHeight,
+ int maxWidth) {
if (maxWidth == 0 || maxHeight == 0) {
- throw new IllegalArgumentException("Image size should not be 0. {width=" + maxWidth
- + ", height=" + maxHeight + "}");
+ throw new IllegalArgumentException(
+ "Image size should not be 0. {width=" + maxWidth + ", height=" + maxHeight
+ + "}");
}
+ mAppContext = context.getApplicationContext();
mKey = key;
mImageCache = imageCache;
mMaxHeight = maxHeight;
@@ -247,9 +300,8 @@ public final class ImageLoader {
@Override
public final void onPostExecute(ScaledBitmapInfo scaledBitmapInfo) {
- if (ImageLoader.DEBUG) {
- Log.d(ImageLoader.TAG, "Bitmap is loaded " + mKey);
- }
+ if (DEBUG) Log.d(ImageLoader.TAG, "Bitmap is loaded " + mKey);
+
for (ImageLoader.ImageLoaderCallback callback : mCallbacks) {
callback.onBitmapLoaded(scaledBitmapInfo == null ? null : scaledBitmapInfo.bitmap);
}
@@ -262,24 +314,22 @@ public final class ImageLoader {
@Override
public String toString() {
- return this.getClass().getSimpleName() + "(" + mKey + " "
- + mMaxWidth + "x" + mMaxHeight + ")";
+ return this.getClass().getSimpleName() + "(" + mKey + " " + mMaxWidth + "x" + mMaxHeight
+ + ")";
}
}
private static final class LoadBitmapFromUriTask extends LoadBitmapTask {
- private final Context mContext;
private LoadBitmapFromUriTask(Context context, ImageCache imageCache, String uriString,
int maxWidth, int maxHeight) {
- super(imageCache, uriString, maxHeight, maxWidth);
- mContext = context;
+ super(context, imageCache, uriString, maxHeight, maxWidth);
}
@Override
@Nullable
public final ScaledBitmapInfo doGetBitmapInBackground() {
return BitmapUtils
- .decodeSampledBitmapFromUriString(mContext, getKey(), mMaxWidth, mMaxHeight);
+ .decodeSampledBitmapFromUriString(mAppContext, getKey(), mMaxWidth, mMaxHeight);
}
}
@@ -288,10 +338,10 @@ public final class ImageLoader {
*/
public static final class LoadTvInputLogoTask extends LoadBitmapTask {
private final TvInputInfo mInfo;
- private final Context mContext;
public LoadTvInputLogoTask(Context context, ImageCache cache, TvInputInfo info) {
- super(cache,
+ super(context,
+ cache,
info.getId() + "-logo",
context.getResources()
.getDimensionPixelSize(R.dimen.channel_banner_input_logo_size),
@@ -299,13 +349,12 @@ public final class ImageLoader {
.getDimensionPixelSize(R.dimen.channel_banner_input_logo_size)
);
mInfo = info;
- mContext = context;
}
@Nullable
@Override
public ScaledBitmapInfo doGetBitmapInBackground() {
- Drawable drawable = mInfo.loadIcon(mContext);
+ Drawable drawable = mInfo.loadIcon(mAppContext);
if (!(drawable instanceof BitmapDrawable)) {
return null;
}
@@ -317,6 +366,13 @@ public final class ImageLoader {
}
}
+ private static synchronized Handler getMainHandler() {
+ if (sMainHandler == null) {
+ sMainHandler = new Handler(Looper.getMainLooper());
+ }
+ return sMainHandler;
+ }
+
private ImageLoader() {
}
}
diff --git a/src/com/android/tv/util/MultiLongSparseArray.java b/src/com/android/tv/util/MultiLongSparseArray.java
index 4c067892..7ed72d61 100644
--- a/src/com/android/tv/util/MultiLongSparseArray.java
+++ b/src/com/android/tv/util/MultiLongSparseArray.java
@@ -19,6 +19,8 @@ package com.android.tv.util;
import android.support.annotation.VisibleForTesting;
import android.util.LongSparseArray;
+import com.android.tv.common.CollectionUtils;
+
import java.util.Collections;
import java.util.Set;
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 0570d590..582a0c9f 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -18,8 +18,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;
@@ -31,7 +33,16 @@ import com.android.tv.data.ChannelDataManager;
*/
public final class OnboardingUtils {
private static final String PREF_KEY_IS_FIRST_BOOT = "pref_onbaording_is_first_boot";
- private static final String PREF_KEY_IS_FIRST_RUN = "pref_onbaording_is_first_run";
+ private static final String PREF_KEY_ONBOARDING_VERSION_CODE = "pref_onbaording_versionCode";
+ private static final int ONBOARDING_VERSION = 1;
+
+ private static final String MERCHANT_COLLECTION_URL_STRING =
+ "https://play.google.com/store/apps/collection/promotion_3001bf9_ATV_livechannels";
+ /**
+ * Intent to show merchant collection in play store.
+ */
+ public static final Intent PLAY_STORE_INTENT = new Intent(Intent.ACTION_VIEW,
+ Uri.parse(MERCHANT_COLLECTION_URL_STRING));
/**
* Checks if this is the first boot after the onboarding experience has been applied.
@@ -52,29 +63,29 @@ public final class OnboardingUtils {
}
/**
- * Checks if this is the first run of {@link com.android.tv.MainActivity} after the
- * onboarding experience has been applied.
+ * Checks if this is the first run of {@link com.android.tv.MainActivity} with the
+ * current onboarding version.
*/
- public static boolean isFirstRun(Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context)
- .getBoolean(PREF_KEY_IS_FIRST_RUN, true);
+ public static boolean isFirstRunWithCurrentVersion(Context context) {
+ int versionCode = PreferenceManager.getDefaultSharedPreferences(context)
+ .getInt(PREF_KEY_ONBOARDING_VERSION_CODE, 0);
+ return versionCode != ONBOARDING_VERSION;
}
/**
- * Marks that the first run of {@link com.android.tv.MainActivity} has been completed.
+ * Marks that the first run of {@link com.android.tv.MainActivity} with the current
+ * onboarding version has been completed.
*/
- public static void setFirstRunCompleted(Context context) {
- PreferenceManager.getDefaultSharedPreferences(context)
- .edit()
- .putBoolean(PREF_KEY_IS_FIRST_RUN, false)
- .apply();
+ public static void setFirstRunWithCurrentVersionCompleted(Context context) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putInt(PREF_KEY_ONBOARDING_VERSION_CODE, ONBOARDING_VERSION).apply();
}
/**
* Checks whether the onboarding screen should be shown or not.
*/
public static boolean needToShowOnboarding(Context context) {
- return isFirstRun(context) || !areChannelsAvailable(context);
+ return isFirstRunWithCurrentVersion(context) || !areChannelsAvailable(context);
}
/**
@@ -93,4 +104,12 @@ public final class OnboardingUtils {
return 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;
+ }
}
diff --git a/src/com/android/tv/util/PipInputManager.java b/src/com/android/tv/util/PipInputManager.java
index 3e4db654..dddc82b6 100644
--- a/src/com/android/tv/util/PipInputManager.java
+++ b/src/com/android/tv/util/PipInputManager.java
@@ -24,6 +24,7 @@ import android.util.Log;
import com.android.tv.ChannelTuner;
import com.android.tv.R;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.data.Channel;
import java.util.ArrayList;
diff --git a/src/com/android/tv/util/RecurringRunner.java b/src/com/android/tv/util/RecurringRunner.java
index dcede666..2a006f9e 100644
--- a/src/com/android/tv/util/RecurringRunner.java
+++ b/src/com/android/tv/util/RecurringRunner.java
@@ -23,6 +23,8 @@ import android.os.Handler;
import android.support.annotation.WorkerThread;
import android.util.Log;
+import com.android.tv.common.SharedPreferencesUtils;
+
import java.util.Date;
/**
@@ -38,13 +40,16 @@ public final class RecurringRunner {
private final Handler mHandler;
private final long mIntervalMs;
private final Runnable mRunnable;
+ private final Runnable mOnStopRunnable;
private final Context mContext;
private final String mName;
private boolean mRunning;
- public RecurringRunner(Context context, long intervalMs, Runnable runnable) {
+ public RecurringRunner(Context context, long intervalMs, Runnable runnable,
+ Runnable onStopRunnable) {
mContext = context.getApplicationContext();
mRunnable = runnable;
+ mOnStopRunnable = onStopRunnable;
mIntervalMs = intervalMs;
if (DEBUG) Log.i(TAG, "Delaying " + (intervalMs / 1000.0) + " seconds");
mName = runnable.getClass().getCanonicalName();
@@ -73,6 +78,9 @@ public final class RecurringRunner {
public void stop() {
mRunning = false;
mHandler.removeCallbacksAndMessages(null);
+ if (mOnStopRunnable != null) {
+ mOnStopRunnable.run();
+ }
}
private void postAt(long next) {
@@ -102,7 +110,7 @@ public final class RecurringRunner {
}
private SharedPreferences getSharedPreferences() {
- return mContext.getSharedPreferences(RecurringRunner.class.getCanonicalName(),
+ return mContext.getSharedPreferences(SharedPreferencesUtils.SHARED_PREF_RECURRING_RUNNER,
Context.MODE_PRIVATE);
}
diff --git a/src/com/android/tv/util/SearchManagerHelper.java b/src/com/android/tv/util/SearchManagerHelper.java
index bd5db6ec..5ec1b455 100644
--- a/src/com/android/tv/util/SearchManagerHelper.java
+++ b/src/com/android/tv/util/SearchManagerHelper.java
@@ -52,7 +52,7 @@ public final class SearchManagerHelper {
public void launchAssistAction() {
try {
- if (Build.VERSION.SDK_INT >= 23) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
SearchManager.class.getDeclaredMethod(
"launchLegacyAssist", String.class, Integer.TYPE, Bundle.class).invoke(
mSearchManager, null, UserHandle.myUserId(), null);
diff --git a/src/com/android/tv/util/SetupUtils.java b/src/com/android/tv/util/SetupUtils.java
index 0fbbce1e..d337139b 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -25,13 +25,17 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.os.Build;
import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
import android.util.Log;
import com.android.tv.ApplicationSingletons;
import com.android.tv.TvApplication;
+import com.android.tv.common.CollectionUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -47,6 +51,8 @@ public class SetupUtils {
private static final String PREF_KEY_KNOWN_INPUTS = "known_inputs";
// Set up inputs are inputs whose setup activity has been launched and finished successfully.
private static final String PREF_KEY_SET_UP_INPUTS = "set_up_inputs";
+ // Recognized inputs means that the user already knows the inputs are installed.
+ private static final String PREF_KEY_RECOGNIZED_INPUTS = "recognized_inputs";
private static final String PREF_KEY_IS_FIRST_TUNE = "is_first_tune";
private static SetupUtils sSetupUtils;
@@ -54,16 +60,22 @@ public class SetupUtils {
private final SharedPreferences mSharedPreferences;
private final Set<String> mKnownInputs;
private final Set<String> mSetUpInputs;
+ private final Set<String> mRecognizedInputs;
private boolean mIsFirstTune;
private final String mUsbTunerInputId;
private SetupUtils(TvApplication tvApplication) {
mTvApplication = tvApplication;
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(tvApplication);
- mSetUpInputs = new HashSet<>(mSharedPreferences.getStringSet(PREF_KEY_SET_UP_INPUTS,
- new HashSet<String>()));
- mKnownInputs = new HashSet<>(mSharedPreferences.getStringSet(PREF_KEY_KNOWN_INPUTS,
- new HashSet<String>()));
+ mSetUpInputs = CollectionUtils.createSmallSet();
+ mSetUpInputs.addAll(mSharedPreferences.getStringSet(PREF_KEY_SET_UP_INPUTS,
+ Collections.<String>emptySet()));
+ mKnownInputs = CollectionUtils.createSmallSet();
+ mKnownInputs.addAll(mSharedPreferences.getStringSet(PREF_KEY_KNOWN_INPUTS,
+ Collections.<String>emptySet()));
+ mRecognizedInputs = CollectionUtils.createSmallSet();
+ mRecognizedInputs.addAll(mSharedPreferences.getStringSet(PREF_KEY_RECOGNIZED_INPUTS,
+ mKnownInputs));
mIsFirstTune = mSharedPreferences.getBoolean(PREF_KEY_IS_FIRST_TUNE, true);
mUsbTunerInputId = TvContract.buildInputId(new ComponentName(tvApplication,
com.android.usbtuner.tvinput.UsbTunerTvInputService.class));
@@ -83,7 +95,8 @@ public class SetupUtils {
/**
* Additional work after the setup of TV input.
*/
- public void onTvInputSetupFinished(final String inputId, final Runnable postRunnable) {
+ public void onTvInputSetupFinished(final String inputId,
+ @Nullable final Runnable postRunnable) {
// When TIS adds several channels, ChannelDataManager.Listener.onChannelList
// Updated() can be called several times. In this case, it is hard to detect
// which one is the last callback. To reduce error prune, we update channel
@@ -136,6 +149,37 @@ public class SetupUtils {
});
}
+ /**
+ * Marks the channels in newly installed inputs browsable.
+ */
+ @UiThread
+ public void markNewChannelsBrowsable() {
+ Set<String> newInputsWithChannels = new HashSet<>();
+ TvInputManagerHelper tvInputManagerHelper = mTvApplication.getTvInputManagerHelper();
+ ChannelDataManager channelDataManager = mTvApplication.getChannelDataManager();
+ SoftPreconditions.checkState(channelDataManager.isDbLoadFinished());
+ for (TvInputInfo input : tvInputManagerHelper.getTvInputInfos(true, true)) {
+ String inputId = input.getId();
+ if (!isSetupDone(inputId) && channelDataManager.getChannelCountForInput(inputId) > 0) {
+ onSetupDone(inputId);
+ newInputsWithChannels.add(inputId);
+ if (DEBUG) {
+ Log.d(TAG, "New input " + inputId + " has "
+ + channelDataManager.getChannelCountForInput(inputId)
+ + " channels");
+ }
+ }
+ }
+ if (!newInputsWithChannels.isEmpty()) {
+ for (Channel channel : channelDataManager.getChannelList()) {
+ if (newInputsWithChannels.contains(channel.getInputId())) {
+ channelDataManager.updateBrowsable(channel.getId(), true);
+ }
+ }
+ channelDataManager.applyUpdatedValuesToDb();
+ }
+ }
+
public boolean isFirstTune() {
return mIsFirstTune;
}
@@ -153,7 +197,9 @@ public class SetupUtils {
*/
public void markAsKnownInput(String inputId) {
mKnownInputs.add(inputId);
- mSharedPreferences.edit().putStringSet(PREF_KEY_KNOWN_INPUTS, mKnownInputs).apply();
+ mRecognizedInputs.add(inputId);
+ mSharedPreferences.edit().putStringSet(PREF_KEY_KNOWN_INPUTS, mKnownInputs)
+ .putStringSet(PREF_KEY_RECOGNIZED_INPUTS, mRecognizedInputs).apply();
}
/**
@@ -180,6 +226,37 @@ public class SetupUtils {
}
/**
+ * Checks whether the given input is already recognized by the user or not.
+ */
+ private boolean isRecognizedInput(String inputId) {
+ return mRecognizedInputs.contains(inputId);
+ }
+
+ /**
+ * Marks all the inputs as recognized inputs. Once it is marked, {@link #isRecognizedInput} will
+ * return {@code true}.
+ */
+ public void markAllInputsRecognized(TvInputManagerHelper inputManager) {
+ for (TvInputInfo input : inputManager.getTvInputInfos(true, true)) {
+ mRecognizedInputs.add(input.getId());
+ }
+ mSharedPreferences.edit().putStringSet(PREF_KEY_RECOGNIZED_INPUTS, mRecognizedInputs)
+ .apply();
+ }
+
+ /**
+ * Checks whether there are any unrecognized inputs.
+ */
+ public boolean hasUnrecognizedInput(TvInputManagerHelper inputManager) {
+ for (TvInputInfo input : inputManager.getTvInputInfos(true, true)) {
+ if (!isRecognizedInput(input.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Grants permission for writing EPG data to all verified packages.
*
* @param context The Context used for granting permission.
@@ -251,8 +328,8 @@ public class SetupUtils {
* Called when input list is changed. It mainly handles input removals.
*/
public void onInputListUpdated(TvInputManager manager) {
- // mKnownInputs is a super set of mSetUpInputs.
- Set<String> removedInputList = new HashSet<>(mKnownInputs);
+ // mRecognizedInputs > mKnownInputs > mSetUpInputs.
+ Set<String> removedInputList = new HashSet<>(mRecognizedInputs);
for (TvInputInfo input : manager.getTvInputList()) {
removedInputList.remove(input.getId());
}
@@ -263,12 +340,13 @@ public class SetupUtils {
if (!removedInputList.isEmpty()) {
for (String input : removedInputList) {
+ mRecognizedInputs.remove(input);
mSetUpInputs.remove(input);
mKnownInputs.remove(input);
}
- mSharedPreferences.edit()
- .putStringSet(PREF_KEY_SET_UP_INPUTS, mSetUpInputs).apply();
- mSharedPreferences.edit().putStringSet(PREF_KEY_KNOWN_INPUTS, mKnownInputs).apply();
+ mSharedPreferences.edit().putStringSet(PREF_KEY_SET_UP_INPUTS, mSetUpInputs)
+ .putStringSet(PREF_KEY_KNOWN_INPUTS, mKnownInputs)
+ .putStringSet(PREF_KEY_RECOGNIZED_INPUTS, mKnownInputs).apply();
}
}
@@ -279,12 +357,20 @@ public class SetupUtils {
public void onSetupDone(String inputId) {
SoftPreconditions.checkState(inputId != null);
if (DEBUG) Log.d(TAG, "onSetupDone: input=" + inputId);
+ if (!mRecognizedInputs.contains(inputId)) {
+ Log.i(TAG, "An unrecognized input's setup has been done. inputId=" + inputId);
+ mRecognizedInputs.add(inputId);
+ mSharedPreferences.edit().putStringSet(PREF_KEY_RECOGNIZED_INPUTS, mKnownInputs)
+ .apply();
+ }
if (!mKnownInputs.contains(inputId)) {
Log.i(TAG, "An unknown input's setup has been done. inputId=" + inputId);
mKnownInputs.add(inputId);
+ mSharedPreferences.edit().putStringSet(PREF_KEY_KNOWN_INPUTS, mKnownInputs).apply();
+ }
+ if (!mSetUpInputs.contains(inputId)) {
+ mSetUpInputs.add(inputId);
+ mSharedPreferences.edit().putStringSet(PREF_KEY_SET_UP_INPUTS, mSetUpInputs).apply();
}
- mSetUpInputs.add(inputId);
- mSharedPreferences.edit()
- .putStringSet(PREF_KEY_SET_UP_INPUTS, mSetUpInputs).apply();
}
}
diff --git a/src/com/android/tv/util/SoftPreconditions.java b/src/com/android/tv/util/SoftPreconditions.java
index b00027a8..3643fca4 100644
--- a/src/com/android/tv/util/SoftPreconditions.java
+++ b/src/com/android/tv/util/SoftPreconditions.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.BuildConfig;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.feature.Feature;
/**
@@ -147,8 +147,10 @@ public final class SoftPreconditions {
tag = TAG;
}
String logMessage;
- if (msg == null) {
+ if (TextUtils.isEmpty(msg)) {
logMessage = prefix;
+ } else if (TextUtils.isEmpty(prefix)) {
+ logMessage = msg;
} else {
logMessage = prefix + ": " + msg;
}
diff --git a/src/com/android/tv/util/SystemProperties.java b/src/com/android/tv/util/SystemProperties.java
index 235161b6..1dc70fd5 100644
--- a/src/com/android/tv/util/SystemProperties.java
+++ b/src/com/android/tv/util/SystemProperties.java
@@ -58,6 +58,13 @@ public final class SystemProperties {
public static final BooleanSystemProperty USE_TRACKER = new BooleanSystemProperty(
"tv_use_tracker", true);
+ /**
+ * Selects using {@link com.android.tv.dvr.DvrDataManagerInMemoryImpl}
+ * instead of {@link com.android.tv.dvr.DvrDataManagerImpl}
+ */
+ public static final BooleanSystemProperty USE_IN_MEMORY_DVR_DB = new BooleanSystemProperty(
+ "tv_use_in_memory_dvr_db", false); // STOPSHIP(DVR)
+
static {
updateSystemProperties();
}
diff --git a/src/com/android/tv/util/TvSettings.java b/src/com/android/tv/util/TvSettings.java
index 788a7d60..133fdd72 100644
--- a/src/com/android/tv/util/TvSettings.java
+++ b/src/com/android/tv/util/TvSettings.java
@@ -103,6 +103,7 @@ public final class TvSettings {
* {@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(
@@ -128,6 +129,7 @@ public final class TvSettings {
* {@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(
@@ -227,6 +229,7 @@ public final class TvSettings {
}
@ContentRatingLevel
+ @SuppressWarnings("ResourceType")
public static int getContentRatingLevel(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getInt(
PREF_CONTENT_RATING_LEVEL, CONTENT_RATING_LEVEL_NONE);
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index 5c6d5345..44d601c5 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -50,8 +50,10 @@ import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.usbtuner.tvinput.UsbTunerTvInputService;
+
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@@ -75,6 +77,7 @@ public class Utils {
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";
+ public static final String EXTRA_KEY_RECORDING_URI = "recording_uri";
// Query parameter in the intent of starting MainActivity.
public static final String PARAM_SOURCE = "source";
@@ -450,36 +453,6 @@ public class Utils {
metadata.toString());
}
- public static TvContentRating[] stringToContentRatings(String commaSeparatedRatings) {
- if (TextUtils.isEmpty(commaSeparatedRatings)) {
- return null;
- }
- String[] ratings = commaSeparatedRatings.split("\\s*,\\s*");
- List<TvContentRating> contentRatings = new ArrayList<>();
- for (String rating : ratings) {
- try {
- contentRatings.add(TvContentRating.unflattenFromString(rating));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Can't parse the content rating: '" + rating + "'", e);
- }
- }
- return contentRatings.size() == 0 ?
- null : contentRatings.toArray(new TvContentRating[contentRatings.size()]);
- }
-
- public static String contentRatingsToString(TvContentRating[] contentRatings) {
- if (contentRatings == null || contentRatings.length == 0) {
- return null;
- }
- final String DELIMITER = ",";
- StringBuilder ratings = new StringBuilder(contentRatings[0].flattenToString());
- for (int i = 1; i < contentRatings.length; ++i) {
- ratings.append(DELIMITER);
- ratings.append(contentRatings[i].flattenToString());
- }
- return ratings.toString();
- }
-
public static boolean isEqualLanguage(String lang1, String lang2) {
if (lang1 == null) {
return lang2 == null;
diff --git a/src/com/android/usbtuner/UsbInputController.java b/src/com/android/usbtuner/UsbInputController.java
index 7ff82589..6d6fccc2 100644
--- a/src/com/android/usbtuner/UsbInputController.java
+++ b/src/com/android/usbtuner/UsbInputController.java
@@ -31,6 +31,7 @@ import android.util.Log;
import com.android.tv.Features;
import com.android.tv.TvApplication;
+import com.android.usbtuner.setup.TunerSetupActivity;
import com.android.usbtuner.tvinput.UsbTunerTvInputService;
import java.util.Map;
@@ -157,7 +158,7 @@ public class UsbInputController 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) context.getApplicationContext()).hasMainActivity()
+ int flags = TvApplication.getSingletons(context).getMainActivityWrapper().isCreated()
? PackageManager.DONT_KILL_APP : 0;
int newState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
diff --git a/tests/common/src/com/android/tv/MockTvApplication.java b/tests/common/src/com/android/tv/MockTvApplication.java
index 7060e6b0..24c47a6a 100644
--- a/tests/common/src/com/android/tv/MockTvApplication.java
+++ b/tests/common/src/com/android/tv/MockTvApplication.java
@@ -16,11 +16,9 @@
package com.android.tv;
-import android.app.Application;
import android.test.mock.MockApplication;
import com.android.tv.analytics.Analytics;
-import com.android.tv.analytics.OptOutPreferenceHelper;
import com.android.tv.analytics.Tracker;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
@@ -60,11 +58,6 @@ public class MockTvApplication extends MockApplication implements ApplicationSin
}
@Override
- public OptOutPreferenceHelper getOptPreferenceHelper() {
- return mDelegate.getOptPreferenceHelper();
- }
-
- @Override
public ChannelDataManager getChannelDataManager() {
return mDelegate.getChannelDataManager();
}
@@ -83,4 +76,9 @@ public class MockTvApplication extends MockApplication implements ApplicationSin
public TvInputManagerHelper getTvInputManagerHelper() {
return mDelegate.getTvInputManagerHelper();
}
+
+ @Override
+ public MainActivityWrapper getMainActivityWrapper() {
+ return mDelegate.getMainActivityWrapper();
+ }
}
diff --git a/tests/common/src/com/android/tv/testing/ChannelUtils.java b/tests/common/src/com/android/tv/testing/ChannelUtils.java
index 00881c86..e09843a6 100644
--- a/tests/common/src/com/android/tv/testing/ChannelUtils.java
+++ b/tests/common/src/com/android/tv/testing/ChannelUtils.java
@@ -96,7 +96,7 @@ public class ChannelUtils {
} else {
values.putNull(Channels.COLUMN_VIDEO_FORMAT);
}
- if (Build.VERSION.SDK_INT >= 23) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!TextUtils.isEmpty(channel.appLinkText)) {
values.put(Channels.COLUMN_APP_LINK_TEXT, channel.appLinkText);
}
diff --git a/tests/common/src/com/android/tv/testing/ProgramUtils.java b/tests/common/src/com/android/tv/testing/ProgramUtils.java
index 493891b6..227eb84a 100644
--- a/tests/common/src/com/android/tv/testing/ProgramUtils.java
+++ b/tests/common/src/com/android/tv/testing/ProgramUtils.java
@@ -25,6 +25,8 @@ import android.media.tv.TvContract.Programs;
import android.net.Uri;
import android.util.Log;
+import com.android.tv.common.TvContentRatingCache;
+
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@@ -48,7 +50,7 @@ public class ProgramUtils {
values.put(Programs.COLUMN_CHANNEL_ID, channelId);
values.put(Programs.COLUMN_SHORT_DESCRIPTION, program.description);
values.put(Programs.COLUMN_CONTENT_RATING,
- Utils.contentRatingsToString(program.contentRatings));
+ TvContentRatingCache.contentRatingsToString(program.contentRatings));
long currentTimeMs = System.currentTimeMillis();
long targetEndTimeMs = currentTimeMs + PROGRAM_INSERT_DURATION_MS;
diff --git a/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java b/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java
index 0795a89c..71af8297 100644
--- a/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java
+++ b/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java
@@ -33,6 +33,8 @@ public final class TvContentRatingConstants {
public static final TvContentRating CONTENT_RATING_US_TV_Y7_US_TV_FV =
TvContentRating.createRating("com.android.tv", "US_TV", "US_TV_Y7", "US_TV_FV");
+ public static String STRING_US_TV_Y7_US_TV_FV = "com.android.tv/US_TV/US_TV_Y7/US_TV_FV";
+
/**
* A content rating object.
*
@@ -43,6 +45,8 @@ public final class TvContentRatingConstants {
public static final TvContentRating CONTENT_RATING_US_TV_MA =
TvContentRating.createRating("com.android.tv", "US_TV", "US_TV_MA");
+ public static String STRING_US_TV_MA = "com.android.tv/US_TV/US_TV_MA";
+
/**
* A content rating object.
*
@@ -54,4 +58,7 @@ public final class TvContentRatingConstants {
public static final TvContentRating CONTENT_RATING_US_TV_PG_US_TV_L_US_TV_S =
TvContentRating.createRating("com.android.tv", "US_TV", "US_TV_PG", "US_TV_L",
"US_TV_S");
+
+ public static String STRING_US_TV_PG_US_TV_L_US_TV_S
+ = "com.android.tv/US_TV/US_TV_Y7/US_TV_L/US_TV_S";
}
diff --git a/tests/common/src/com/android/tv/testing/Utils.java b/tests/common/src/com/android/tv/testing/Utils.java
index 9e1bd3e9..6bc4e24e 100644
--- a/tests/common/src/com/android/tv/testing/Utils.java
+++ b/tests/common/src/com/android/tv/testing/Utils.java
@@ -95,31 +95,6 @@ public final class Utils {
return null;
}
- public static TvContentRating[] stringToContentRatings(String commaSeparatedRatings) {
- if (TextUtils.isEmpty(commaSeparatedRatings)) {
- return null;
- }
- String[] ratings = commaSeparatedRatings.split("\\s*,\\s*");
- TvContentRating[] contentRatings = new TvContentRating[ratings.length];
- for (int i = 0; i < contentRatings.length; ++i) {
- contentRatings[i] = TvContentRating.unflattenFromString(ratings[i]);
- }
- return contentRatings;
- }
-
- public static String contentRatingsToString(TvContentRating[] contentRatings) {
- if (contentRatings == null || contentRatings.length == 0) {
- return null;
- }
- final String DELIMITER = ",";
- StringBuilder ratings = new StringBuilder(contentRatings[0].flattenToString());
- for (int i = 1; i < contentRatings.length; ++i) {
- ratings.append(DELIMITER);
- ratings.append(contentRatings[i].flattenToString());
- }
- return ratings.toString();
- }
-
/**
* Return the Random class which is needed to make random data for testing.
* Default seed of the random is today's date.
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 30e21e2e..458c9f2c 100644
--- a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
+++ b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
@@ -16,19 +16,47 @@
package com.android.tv.testing.dvr;
+import android.support.annotation.RequiresPermission;
+
import com.android.tv.data.Channel;
import com.android.tv.dvr.Recording;
+import junit.framework.Assert;
+
import java.util.Collections;
/**
* Static utils for using {@link Recording} in tests.
*/
-public class RecordingTestUtils {
- public static Recording createTestRecordingWithPeriod(long id, long startTime, long endTime) {
+public final class RecordingTestUtils {
+ public static Recording createTestRecordingWithIdAndPeriod(long id, long startTime,
+ long endTime) {
return Recording.builder(new Channel.Builder().build(), startTime, endTime)
.setId(id)
.setPrograms(Collections.EMPTY_LIST)
.build();
}
+
+ public static Recording createTestRecordingWithPeriod(long startTime, long endTime) {
+ return createTestRecordingWithIdAndPeriod(Recording.ID_NOT_SET, startTime, endTime);
+ }
+
+ public static Recording normalizePriority(Recording orig){
+ return Recording.buildFrom(orig).setPriority(orig.getId()).build();
+ }
+
+ public static void assertRecordingEquals(Recording expected, Recording actual) {
+ Assert.assertEquals("id", expected.getId(), actual.getId());
+ Assert.assertEquals("uri", expected.getUri(), actual.getUri());
+ Assert.assertEquals("channel", expected.getChannel(), actual.getChannel());
+ Assert.assertEquals("programs", expected.getPrograms(), actual.getPrograms());
+ Assert.assertEquals("start time", expected.getStartTimeMs(), actual.getStartTimeMs());
+ Assert.assertEquals("end time", expected.getEndTimeMs(), actual.getEndTimeMs());
+ Assert.assertEquals("media size", expected.getSize(), actual.getSize());
+ Assert.assertEquals("state", expected.getState(), actual.getState());
+ Assert.assertEquals("parent season recording", expected.getParentSeasonRecording(),
+ actual.getParentSeasonRecording());
+ }
+
+ private RecordingTestUtils() { }
}
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 3d992618..ea5360a3 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
@@ -116,14 +116,9 @@ public class MenuHelper extends BaseUiDeviceHelper {
Direction.RIGHT);
}
- public UiObject2 assertPressOptionsChannelSources() {
+ public UiObject2 assertPressOptionsSettings() {
return assertPressMenuItem(R.string.menu_title_options,
- R.string.options_item_channel_sources);
- }
-
- public UiObject2 assertPressOptionsAbout() {
- return assertPressMenuItem(R.string.menu_title_options,
- R.string.options_item_about);
+ R.string.options_item_settings);
}
public UiObject2 assertPressOptionsClosedCaptions() {
@@ -139,11 +134,6 @@ public class MenuHelper extends BaseUiDeviceHelper {
return assertPressMenuItem(R.string.menu_title_options, R.string.options_item_multi_audio);
}
- public UiObject2 assertPressOptionsParentalControls() {
- return assertPressMenuItem(R.string.menu_title_options,
- R.string.options_item_parental_controls);
- }
-
public UiObject2 assertPressProgramGuide() {
return assertPressMenuItem(R.string.menu_title_channels,
R.string.channels_item_program_guide);
diff --git a/tests/func/src/com/android/tv/tests/ui/AboutFragmentTest.java b/tests/func/src/com/android/tv/tests/ui/AboutFragmentTest.java
deleted file mode 100644
index cd7a5718..00000000
--- a/tests/func/src/com/android/tv/tests/ui/AboutFragmentTest.java
+++ /dev/null
@@ -1,57 +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.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.tv.Features;
-import com.android.tv.R;
-import com.android.tv.testing.uihelper.ByResource;
-import com.android.tv.testing.uihelper.SidePanelHelper;
-
-/**
- * Test for the About menu.
- */
-@LargeTest
-public class AboutFragmentTest extends LiveChannelsTestCase {
- private SidePanelHelper mSidePanelHelper;
- private BySelector mAboutSidePanel;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mSidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
- mAboutSidePanel = mSidePanelHelper.bySidePanelTitled(R.string.side_panel_title_about);
- }
-
- public void testAllowAnalytics_present() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressOptionsAbout();
- assertWaitForCondition(mDevice, Until.hasObject(mAboutSidePanel));
- BySelector improveSelector = ByResource
- .text(mTargetResources, R.string.about_menu_improve_summary);
- if (Features.ANALYTICS_OPT_OUT.isEnabled(getInstrumentation().getContext())) {
- assertWaitForCondition(mDevice, Until.hasObject(improveSelector));
- } else {
- assertFalse(mDevice.hasObject(improveSelector));
- }
- mDevice.pressBack();
- }
-}
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 9959185f..27d8824e 100644
--- a/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
@@ -23,36 +23,48 @@ import android.test.suitebuilder.annotation.LargeTest;
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
-import com.android.tv.testing.uihelper.SidePanelHelper;
/**
* Tests for channel sources.
*/
@LargeTest
public class ChannelSourcesTest extends LiveChannelsTestCase {
- private SidePanelHelper mSidePanelHelper;
- private BySelector mByChannelSourceSidePanel;
+ private BySelector mBySettingsSidePanel;
@Override
protected void setUp() throws Exception {
super.setUp();
- mSidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
- mByChannelSourceSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.side_panel_title_channel_sources);
+ mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_settings);
}
//TODO: create a cancelable test channel setup.
public void testSetup_cancel() {
mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressOptionsChannelSources();
- assertWaitForCondition(mDevice, Until.hasObject(mByChannelSourceSidePanel));
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.channel_source_item_setup);
+ mSidePanelHelper.assertNavigateToItem(R.string.settings_channel_source_item_setup);
mDevice.pressDPadCenter();
assertWaitForCondition(mDevice,
- Until.hasObject(ByResource.text(mTargetResources, R.string.setup_title)));
+ Until.hasObject(ByResource.text(mTargetResources, R.string.setup_sources_text)));
+ mDevice.pressBack();
+ }
+
+ // SetupSourcesFragment should have no errors if side fragment item is clicked multiple times.
+ public void testSetupTwice_cancel() {
+ mLiveChannelsHelper.assertAppStarted();
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+
+ mSidePanelHelper.assertNavigateToItem(R.string.settings_channel_source_item_setup);
+ mDevice.pressDPadCenter();
+ mDevice.pressDPadCenter();
+
+ assertWaitForCondition(mDevice,
+ Until.hasObject(ByResource.text(mTargetResources, R.string.setup_sources_text)));
mDevice.pressBack();
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java b/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
index 28b54bae..b48968ad 100644
--- a/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
@@ -28,28 +28,28 @@ import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.testing.uihelper.Constants;
import com.android.tv.testing.uihelper.DialogHelper;
-import com.android.tv.testing.uihelper.SidePanelHelper;
/**
* Basic tests for the LiveChannels app.
*/
@LargeTest
public class LiveChannelsAppTest extends LiveChannelsTestCase {
- private SidePanelHelper mSidePanelHelper;
+ private BySelector mBySettingsSidePanel;
@Override
protected void setUp() throws Exception {
super.setUp();
- mSidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
mLiveChannelsHelper.assertAppStarted();
pressKeysForChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
getInstrumentation().waitForIdleSync();
+ mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_settings);
}
- public void testChannelSourcesCancel() {
- mMenuHelper.assertPressOptionsChannelSources();
+ public void testSettingsCancel() {
+ mMenuHelper.assertPressOptionsSettings();
BySelector byChannelSourcesSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.channel_source_item_customize_channels);
+ .bySidePanelTitled(R.string.settings_channel_source_item_customize_channels);
assertWaitForCondition(mDevice, Until.hasObject(byChannelSourcesSidePanel));
mDevice.pressBack();
assertWaitForCondition(mDevice, Until.gone(byChannelSourcesSidePanel));
@@ -105,7 +105,10 @@ public class LiveChannelsAppTest extends LiveChannelsTestCase {
public void testPinCancel() {
mMenuHelper.showMenu();
- mMenuHelper.assertPressOptionsParentalControls();
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
+ mDevice.pressDPadCenter();
DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
dialogHelper.assertWaitForPinDialogOpen();
mDevice.pressBack();
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 96f0e1f8..25c7909b 100644
--- a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
+++ b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
@@ -31,6 +31,7 @@ import com.android.tv.testing.testinput.TestInputControlUtils;
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.SidePanelHelper;
import com.android.tv.testing.uihelper.UiDeviceUtils;
/**
@@ -42,6 +43,7 @@ public abstract class LiveChannelsTestCase extends InstrumentationTestCase {
protected UiDevice mDevice;
protected Resources mTargetResources;
protected MenuHelper mMenuHelper;
+ protected SidePanelHelper mSidePanelHelper;
protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
@Override
@@ -53,6 +55,7 @@ public abstract class LiveChannelsTestCase extends InstrumentationTestCase {
mDevice = UiDevice.getInstance(getInstrumentation());
mTargetResources = getInstrumentation().getTargetContext().getResources();
mMenuHelper = new MenuHelper(mDevice, mTargetResources);
+ mSidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources, context);
}
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 8b7eaeae..40ccf267 100644
--- a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
@@ -30,13 +30,14 @@ import android.view.KeyEvent;
import com.android.tv.R;
import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.testing.uihelper.DialogHelper;
-import com.android.tv.testing.uihelper.SidePanelHelper;
@SmallTest
@SdkSuppress(minSdkVersion = 23)
public class PlayControlsRowViewTest extends LiveChannelsTestCase {
private static final int BUTTON_INDEX_PLAY_PAUSE = 2;
+ private BySelector mBySettingsSidePanel;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -45,6 +46,8 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
// Tune to a new channel to ensure that the channel is changed.
mDevice.pressDPadUp();
getInstrumentation().waitForIdleSync();
+ mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_settings);
}
/**
@@ -110,17 +113,21 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
mMenuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
// Show parental controls fragment.
- mMenuHelper.assertPressOptionsParentalControls();
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
+ mDevice.pressDPadCenter();
DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
dialogHelper.assertWaitForPinDialogOpen();
dialogHelper.enterPinCodes();
dialogHelper.assertWaitForPinDialogClose();
- SidePanelHelper sidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
- BySelector bySidePanel = sidePanelHelper.bySidePanelTitled(R.string.menu_parental_controls);
+ BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.menu_parental_controls);
assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
mDevice.pressEnter();
mDevice.pressEnter();
mDevice.pressBack();
+ mDevice.pressBack();
// Return to the main menu.
mMenuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputService.java b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
index a81977d6..b20e0331 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputService.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
@@ -27,6 +27,7 @@ import android.media.tv.TvInputManager;
import android.media.tv.TvInputService;
import android.media.tv.TvTrackInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -34,7 +35,6 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.Surface;
-import com.android.tv.common.TvCommonConstants;
import com.android.tv.testing.ChannelInfo;
import com.android.tv.testing.testinput.ChannelState;
@@ -47,6 +47,8 @@ public class TestTvInputService extends TvInputService {
private static final String TAG = "TestTvInputServices";
private static final int REFRESH_DELAY_MS = 1000 / 5;
private static final boolean DEBUG = false;
+ private static final boolean HAS_TIME_SHIFT_API = Build.VERSION.SDK_INT
+ >= Build.VERSION_CODES.M;
private final TestInputControl mBackend = TestInputControl.getInstance();
public static String buildInputId(Context context) {
@@ -194,7 +196,7 @@ public class TestTvInputService extends TvInputService {
} else {
Log.i(TAG, "Tuning to " + mChannel);
}
- if (TvCommonConstants.HAS_TIME_SHIFT_API) {
+ if (HAS_TIME_SHIFT_API) {
notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
mRecordStartTimeMs = mCurrentPositionMs = mLastCurrentPositionUpdateTimeMs
= System.currentTimeMillis();
@@ -319,7 +321,7 @@ public class TestTvInputService extends TvInputService {
private void draw(Surface surface, ChannelInfo currentChannel) {
if (surface != null) {
- String now = TvCommonConstants.HAS_TIME_SHIFT_API
+ String now = HAS_TIME_SHIFT_API
? new Date(mCurrentPositionMs).toString() : new Date().toString();
String name = currentChannel == null ? "Null" : currentChannel.name;
Canvas c = surface.lockCanvas(null);
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 1de5e944..bec933ca 100644
--- a/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
@@ -18,14 +18,14 @@ package com.android.tv.tests.jank;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
import android.content.res.Resources;
-import android.os.SystemClock;
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
import android.support.test.jank.JankTestBase;
-import android.support.test.jank.WindowContentFrameStatsMonitor;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
@@ -38,12 +38,25 @@ import com.android.tv.testing.uihelper.UiDeviceUtils;
* Jank tests for the program guide.
*/
@MediumTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
public class ProgramGuideJankTest extends JankTestBase {
private static final boolean DEBUG = false;
private static final String TAG = "ProgramGuideJank";
private static final String STARTING_CHANNEL = "13";
- private static final int EXPECTED_FRAMES = 5;
+ public static final String LIVE_CHANNELS_PROCESS_NAME = "com.android.tv";
+
+ /**
+ * The minimum number of frames expected during each jank test.
+ * If there is less the test will fail. To be safe we loop the action in each test to create
+ * twice this many frames under normal conditions.
+ * <p>200 is chosen so there will be enough frame for the 90th, 95th, and 98th percentile
+ * measurements are significant.
+ *
+ * @see <a href="http://go/janktesthelper-best-practices">Jank Test Helper Best Practices</a>
+ */
+ private static final int EXPECTED_FRAMES = 200;
+ public static final String LIVE_CHANNELS_PACKAGE = "com.android.tv";
protected UiDevice mDevice;
@@ -51,7 +64,6 @@ public class ProgramGuideJankTest extends JankTestBase {
protected MenuHelper mMenuHelper;
protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
-
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -64,81 +76,40 @@ public class ProgramGuideJankTest extends JankTestBase {
pressKeysForChannelNumber(STARTING_CHANNEL);
}
- @JankTest(expectedFrames = 7,
- beforeTest = "warmProgramGuide",
- beforeLoop = "selectProgramGuideMenuItem",
- afterLoop = "clearProgramGuide")
- @WindowContentFrameStatsMonitor
- public void testShowProgramGuide() {
- mDevice.pressDPadCenter();
-
- // Full show has two animations.
- long delay = mTargetResources.getInteger(R.integer.program_guide_anim_duration) * 2;
- waitForIdleAtLeast(delay);
- }
@JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeLoop = "showProgramGuide")
- @WindowContentFrameStatsMonitor
- public void testClearProgramGuide() {
- mDevice.pressBack();
- // Full show has two animations.
- waitForIdleAtLeast(mTargetResources.getInteger(R.integer.program_guide_anim_duration) * 2);
+ beforeTest = "warmProgramGuide")
+ @GfxMonitor(processName = LIVE_CHANNELS_PACKAGE)
+ public void testShowClearProgramGuide() {
+ int frames = 53; // measured by hand
+ int repeat = EXPECTED_FRAMES * 2 / frames;
+ for (int i = 0; i < repeat; i++) {
+ showProgramGuide();
+ clearProgramGuide();
+ }
}
@JankTest(expectedFrames = EXPECTED_FRAMES,
beforeLoop = "showProgramGuide",
afterLoop = "clearProgramGuide")
- @WindowContentFrameStatsMonitor
+ @GfxMonitor(processName = LIVE_CHANNELS_PROCESS_NAME)
public void testScrollDown() {
- mDevice.pressDPadDown();
- waitForIdleAtLeast(mTargetResources
- .getInteger(R.integer.program_guide_table_detail_toggle_anim_duration));
+ int frames = 20; // measured by hand
+ int repeat = EXPECTED_FRAMES * 2 / frames;
+ for (int i = 0; i < repeat; i++) {
+ mDevice.pressDPadDown();
+ }
}
@JankTest(expectedFrames = EXPECTED_FRAMES,
beforeLoop = "showProgramGuide",
afterLoop = "clearProgramGuide")
- @WindowContentFrameStatsMonitor
+ @GfxMonitor(processName = LIVE_CHANNELS_PROCESS_NAME)
public void testScrollRight() {
- mDevice.pressDPadRight();
- waitForIdleAtLeast(mTargetResources
- .getInteger(R.integer.program_guide_table_detail_toggle_anim_duration));
- }
-
- /**
- * {@link UiDevice#waitForIdle() Wait for idle} , then sleep if needed, then wait for idle
- * again.
- *
- * @param delayInMillis The minimum amount of time to delay. This is usually the expected
- * duration of the animation.
- */
- private void waitForIdleAtLeast(long delayInMillis) {
-
- // This seems to give the most reliable numbers.
- // The first wait until idle usually returned in 1ms.
- // Sometimes it would take the whole duration. If we sleep after that we get bad fps
- // because nothing is happening after the idle ends.
- //
- // So sleeping only for the remaining about ensure there is at least enough time for the
- // animation to complete. If we sleep then wait for idle again. This will usually allow
- // the animation to complete.
-
- long startTime = SystemClock.uptimeMillis();
- mDevice.waitForIdle();
-
- long idle = SystemClock.uptimeMillis() - startTime;
- if (DEBUG) {
- Log.d(TAG, "Waited for idle " + (idle) / 1000.0 + " sec");
- }
- if (idle < delayInMillis) {
- long more = delayInMillis - idle;
- SystemClock.sleep(more);
- Log.d(TAG, "Slept " + (more) / 1000.0 + " sec");
- mDevice.waitForIdle();
- }
- if (DEBUG) {
- Log.d(TAG, "Total wait " + (SystemClock.uptimeMillis() - startTime) / 1000.0 + " sec");
+ int frames = 30; // measured by hand
+ int repeat = EXPECTED_FRAMES * 2 / frames;
+ for (int i = 0; i < repeat; i++) {
+ mDevice.pressDPadRight();
}
}
diff --git a/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java b/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java
new file mode 100644
index 00000000..cad1e7ca
--- /dev/null
+++ b/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.SmallTest;
+
+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;
+ 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/common/ui/setup/leanback/PagingIndicatorTest.java b/tests/unit/src/com/android/tv/common/ui/setup/leanback/PagingIndicatorTest.java
new file mode 100644
index 00000000..b342de66
--- /dev/null
+++ b/tests/unit/src/com/android/tv/common/ui/setup/leanback/PagingIndicatorTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.ui.setup.leanback;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.tv.testing.Utils;
+
+/**
+ * Tests for {@link PagingIndicator}.
+ */
+@SmallTest
+public class PagingIndicatorTest extends AndroidTestCase {
+ private PagingIndicator mIndicator;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Utils.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mIndicator = new PagingIndicator(getContext());
+ }
+ });
+ }
+
+ public void testDotPosition() {
+ mIndicator.setPageCount(3);
+ assertDotPosition();
+ mIndicator.setPageCount(6);
+ assertDotPosition();
+ mIndicator.setPageCount(9);
+ assertDotPosition();
+ }
+
+ private void assertDotPosition() {
+ assertSymmetry();
+ assertDistance();
+ }
+
+ private void assertSymmetry() {
+ int pageCount = mIndicator.getPageCount();
+ int mid = pageCount / 2;
+ int[] selectedX = mIndicator.getDotSelectedX();
+ int sum = selectedX[0] + selectedX[pageCount - 1];
+ for (int i = 1; i <= mid; ++i) {
+ assertEquals("Selected dots are not symmetric", sum,
+ selectedX[i] + selectedX[pageCount - i - 1]);
+ }
+ int[] leftX = mIndicator.getDotSelectedLeftX();
+ int[] rightX = mIndicator.getDotSelectedRightX();
+ sum = leftX[0] + rightX[pageCount - 1];
+ for (int i = 1; i < pageCount - 1; ++i) {
+ assertEquals("Deselected dots are not symmetric", sum,
+ leftX[i] + rightX[pageCount - i - 1]);
+ }
+ }
+
+ private void assertDistance() {
+ int pageCount = mIndicator.getPageCount();
+ int[] selectedX = mIndicator.getDotSelectedX();
+ int[] leftX = mIndicator.getDotSelectedLeftX();
+ int[] rightX = mIndicator.getDotSelectedRightX();
+ int distance = selectedX[1] - selectedX[0];
+ for (int i = 2; i < pageCount; ++i) {
+ assertEquals("Gaps between selected dots are not even", distance,
+ selectedX[i] - selectedX[i - 1]);
+ }
+ distance = leftX[1] - leftX[0];
+ for (int i = 2; i < pageCount - 1; ++i) {
+ assertEquals("Gaps between left dots are not even", distance,
+ leftX[i] - leftX[i - 1]);
+ }
+ distance = rightX[2] - rightX[1];
+ for (int i = 3; i < pageCount; ++i) {
+ assertEquals("Gaps between right dots are not even", distance,
+ rightX[i] - rightX[i - 1]);
+ }
+ }
+}
diff --git a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
index fa127369..4dc91ce3 100644
--- a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
@@ -36,7 +36,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
-import com.android.tv.analytics.StubTracker;
import com.android.tv.testing.ChannelInfo;
import com.android.tv.testing.Constants;
import com.android.tv.testing.Utils;
@@ -89,7 +88,7 @@ public class ChannelDataManagerTest extends AndroidTestCase {
TvInputManagerHelper mockHelper = Mockito.mock(TvInputManagerHelper.class);
Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString())).thenReturn(true);
mChannelDataManager = new ChannelDataManager(getContext(), mockHelper,
- new StubTracker(), mContentResolver);
+ mContentResolver);
mChannelDataManager.addListener(mListener);
}
});
diff --git a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
index bc239a8a..0914f804 100644
--- a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
+++ b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
@@ -20,6 +20,7 @@ import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
import com.android.tv.testing.ComparatorTester;
import com.android.tv.util.SetupUtils;
@@ -40,12 +41,14 @@ import java.util.LinkedHashMap;
@SmallTest
public class TvInputNewComparatorTest extends AndroidTestCase {
public void testComparator() throws Exception {
- final LinkedHashMap<String, Boolean> INPUT_ID_TO_NEW_INPUT = new LinkedHashMap<>();
- INPUT_ID_TO_NEW_INPUT.put("2_new_input", true);
- INPUT_ID_TO_NEW_INPUT.put("4_new_input", true);
- INPUT_ID_TO_NEW_INPUT.put("0_old_input", false);
- INPUT_ID_TO_NEW_INPUT.put("1_old_input", false);
- INPUT_ID_TO_NEW_INPUT.put("3_old_input", false);
+ 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));
SetupUtils setupUtils = Mockito.mock(SetupUtils.class);
Mockito.when(setupUtils.isNewInput(Matchers.anyString())).thenAnswer(
@@ -53,7 +56,16 @@ 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);
+ return INPUT_ID_TO_NEW_INPUT.get(inputId).first;
+ }
+ }
+ );
+ Mockito.when(setupUtils.isSetupDone(Matchers.anyString())).thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ return INPUT_ID_TO_NEW_INPUT.get(inputId).second;
}
}
);
diff --git a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
index e5da60eb..eb99cb88 100644
--- a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
@@ -19,6 +19,7 @@ package com.android.tv.data;
import android.test.AndroidTestCase;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.tv.data.WatchedHistoryManager.WatchedRecord;
import com.android.tv.testing.Utils;
@@ -30,6 +31,7 @@ import java.util.concurrent.TimeUnit;
* Test for {@link com.android.tv.data.WatchedHistoryManagerTest}
*/
@SmallTest
+@Suppress // http://b/27156462
public class WatchedHistoryManagerTest extends AndroidTestCase {
private static final boolean DEBUG = false;
private static final String TAG = "WatchedHistoryManager";
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
index 06cf7315..204f7cec 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
+++ b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
@@ -34,22 +34,22 @@ public class DvrDataManagerImplTest extends TestCase {
long id = 1;
List<Recording> recordings = new ArrayList<>();
assertNextStartTime(recordings, 0L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 10L, 20L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 10L, 20L));
assertNextStartTime(recordings, 9L, 10L);
assertNextStartTime(recordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 20L, 30L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 20L, 30L));
assertNextStartTime(recordings, 9L, 10L);
assertNextStartTime(recordings, 10L, 20L);
assertNextStartTime(recordings, 20L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 30L, 40L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 30L, 40L));
assertNextStartTime(recordings, 9L, 10L);
assertNextStartTime(recordings, 10L, 20L);
assertNextStartTime(recordings, 20L, 30L);
assertNextStartTime(recordings, 30L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
recordings.clear();
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 10L, 20L));
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 10L, 20L));
- recordings.add(RecordingTestUtils.createTestRecordingWithPeriod(id++, 10L, 20L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 10L, 20L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 10L, 20L));
+ recordings.add(RecordingTestUtils.createTestRecordingWithIdAndPeriod(id++, 10L, 20L));
assertNextStartTime(recordings, 9L, 10L);
assertNextStartTime(recordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
}
diff --git a/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java b/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java
index 85c2f661..418caa7e 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java
+++ b/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java
@@ -23,8 +23,8 @@ import android.test.ServiceTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.tv.ApplicationSingletons;
-import com.android.tv.Features;
import com.android.tv.MockTvApplication;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.feature.TestableFeature;
import org.mockito.Mock;
@@ -39,7 +39,7 @@ public class DvrRecordingServiceTest extends ServiceTestCase<DvrRecordingService
@Mock Scheduler mMockScheduler;
@Mock ApplicationSingletons mApplicationSingletons;
- private final TestableFeature mDvrFeature = Features.DVR;
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
private DvrDataManagerInMemoryImpl mDataManager;
private DvrRecordingService mService;
diff --git a/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java b/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java
index 063cd61f..8e3b4fd4 100644
--- a/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java
+++ b/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java
@@ -16,97 +16,169 @@
package com.android.tv.dvr;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.longThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.support.test.filters.SdkSuppress;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.tv.common.dvr.DvrSessionClient;
+import com.android.tv.common.recording.TvRecording;
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.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests for {@link RecordingTask}.
*/
@SmallTest
+@SdkSuppress(minSdkVersion = 23)
public class RecordingTaskTest extends AndroidTestCase {
+ private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
+ private static final long START_OFFSET = Scheduler.MS_TO_WAKE_BEFORE_START;
+
private FakeClock mFakeClock;
private DvrDataManagerInMemoryImpl mDataManager;
@Mock
+ Handler mMockHandler;
+ @Mock
DvrSessionManager mMockSessionManager;
@Mock
- DvrSessionClient mMockDvrSessionClient;
+ TvRecording.TvRecordingClient mMockTvRecordingClient;
@Override
protected void setUp() throws Exception {
super.setUp();
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithTimeOne();
+ mFakeClock = FakeClock.createWithCurrentTime();
mDataManager = new DvrDataManagerInMemoryImpl(getContext());
}
- public void testRun_sleepUntil() {
- long startTime = mFakeClock.currentTimeMillis();
- long endTime = startTime + 1;
- Recording r = RecordingTestUtils.createTestRecordingWithPeriod(1, startTime, endTime);
- RecordingTask task = new RecordingTask(r, mMockSessionManager, mDataManager,
- mFakeClock);
+ public void testHandle_init() {
+ Recording r = createRecording();
+ RecordingTask task = createRecordingTask(r);
Channel channel = r.getChannel();
String inputId = channel.getInputId();
- when(mMockSessionManager.canAcquireDvrSession(inputId, channel))
- .thenReturn(true);
+ when(mMockSessionManager.canAcquireDvrSession(inputId, channel)).thenReturn(true);
when(mMockSessionManager.acquireDvrSession(inputId, channel))
- .thenReturn(mMockDvrSessionClient);
- task.run();
- assertEquals("Recording " + r + "finish time", endTime + RecordingTask.MS_AFTER_END,
- mFakeClock.currentTimeMillis());
- }
+ .thenReturn(mMockTvRecordingClient);
+ when(mMockHandler.sendEmptyMessageDelayed(anyInt(), anyLong())).thenReturn(true);
- public void testRun_connectAndRelease() {
- long startTime = mFakeClock.currentTimeMillis();
- long endTime = startTime + 1;
- Recording r = RecordingTestUtils.createTestRecordingWithPeriod(1, startTime, endTime);
- RecordingTask task = new RecordingTask(r, mMockSessionManager, mDataManager,
- mFakeClock);
-
- Channel channel = r.getChannel();
- String inputId = channel.getInputId();
- when(mMockSessionManager.canAcquireDvrSession(inputId, channel))
- .thenReturn(true);
- when(mMockSessionManager.acquireDvrSession(inputId, channel))
- .thenReturn(mMockDvrSessionClient);
- task.run();
+ long delay = START_OFFSET - RecordingTask.MS_BEFORE_START;
+ long uptime = SystemClock.uptimeMillis();
+ assertTrue(task.handleMessage(createMessage(RecordingTask.MESSAGE_INIT)));
+ assertEquals(State.CONNECTION_PENDING, task.getState());
verify(mMockSessionManager).canAcquireDvrSession(inputId, channel);
verify(mMockSessionManager).acquireDvrSession(inputId, channel);
- verify(mMockDvrSessionClient).connect(inputId, task);
- verify(mMockDvrSessionClient).startRecord(channel.getUri(),
- RecordingTask.getIdAsMediaUri(r));
- verify(mMockDvrSessionClient).stopRecord();
- verify(mMockSessionManager).releaseDvrSession(mMockDvrSessionClient);
- verifyNoMoreInteractions(mMockDvrSessionClient, mMockSessionManager);
- }
-
-
- public void testRun_cannotAcquireSession() {
- long startTime = mFakeClock.currentTimeMillis();
- long endTime = startTime + 1;
- Recording r = RecordingTestUtils.createTestRecordingWithPeriod(1, startTime, endTime);
- mDataManager.addRecording(r);
- RecordingTask task = new RecordingTask(r, mMockSessionManager, mDataManager,
- mFakeClock);
+ verify(mMockTvRecordingClient).connect(eq(inputId), any(TvRecording.ClientCallback.class));
+
+ verifySendMessageAt(RecordingTask.MESSAGE_START_RECORDING, uptime + delay);
+ verifyNoMoreInteractions(mMockHandler, mMockTvRecordingClient, mMockSessionManager);
+ }
+
+
+ public void testHandle_init_cannotAcquireSession() {
+ Recording r = createRecording();
+ r = mDataManager.addRecordingInternal(r);
+ RecordingTask task = createRecordingTask(r);
when(mMockSessionManager.canAcquireDvrSession(r.getChannel().getInputId(), r.getChannel()))
.thenReturn(false);
- task.run();
+
+ assertTrue(task.handleMessage(createMessage(RecordingTask.MESSAGE_INIT)));
+
+ assertEquals(State.ERROR, task.getState());
+ verifySendMessage(Scheduler.HandlerWrapper.MESSAGE_REMOVE);
Recording updatedRecording = mDataManager.getRecording(r.getId());
- assertEquals("status",Recording.STATE_RECORDING_FAILED, updatedRecording.getState() );
+ assertEquals("status", Recording.STATE_RECORDING_FAILED, updatedRecording.getState());
+ }
+
+ public void testOnConnected() {
+ Recording r = createRecording();
+ mDataManager.addRecording(r);
+ RecordingTask task = createRecordingTask(r);
+
+ task.onConnected();
+
+ assertEquals(State.CONNECTED, task.getState());
+ }
+
+ private Recording createRecording() {
+ long startTime = mFakeClock.currentTimeMillis() + START_OFFSET;
+ long endTime = startTime + DURATION;
+ return RecordingTestUtils.createTestRecordingWithPeriod(startTime, endTime);
+ }
+
+ private RecordingTask createRecordingTask(Recording r) {
+ RecordingTask recordingTask = new RecordingTask(r, mMockSessionManager, mDataManager,
+ mFakeClock);
+ recordingTask.setHandler(mMockHandler);
+ return recordingTask;
+ }
+
+ private void verifySendMessage(int what) {
+ verify(mMockHandler).sendMessageAtTime(argThat(messageMatchesWhat(what)), anyLong());
+ }
+
+ 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;
+ }
+
+ public static ArgumentMatcher<Message> messageMatchesWhat(final int what) {
+ return new ArgumentMatcher<Message>() {
+ @Override
+ public boolean matches(Object argument) {
+ Message message = (Message) argument;
+ return message.what == what;
+ }
+ };
}
} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/RecordingTest.java b/tests/unit/src/com/android/tv/dvr/RecordingTest.java
index ef012248..e5ffaa3b 100644
--- a/tests/unit/src/com/android/tv/dvr/RecordingTest.java
+++ b/tests/unit/src/com/android/tv/dvr/RecordingTest.java
@@ -16,20 +16,31 @@
package com.android.tv.dvr;
+import static com.android.tv.testing.dvr.RecordingTestUtils.createTestRecordingWithIdAndPeriod;
+import static com.android.tv.testing.dvr.RecordingTestUtils.normalizePriority;
+
+import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Range;
+import com.android.tv.data.Channel;
+import com.android.tv.data.Program;
import com.android.tv.testing.dvr.RecordingTestUtils;
import junit.framework.TestCase;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
/**
* Tests for {@link RecordingTest}
*/
@SmallTest
public class RecordingTest extends TestCase {
public void testIsOverLapping() throws Exception {
- Recording r = RecordingTestUtils.createTestRecordingWithPeriod(1, 10L, 20L);
+ Recording r = createTestRecordingWithIdAndPeriod(1, 10L, 20L);
assertOverLapping(false, 1L, 9L, r);
assertOverLapping(true, 1L, 20L, r);
@@ -43,6 +54,43 @@ public class RecordingTest extends TestCase {
assertOverLapping(false, 21L, 29L, r);
}
+ public void testBuildProgram() {
+ Channel c = new Channel.Builder().build();
+ Program p = new Program.Builder().build();
+ Recording actual = Recording.builder(c, p).build();
+ assertEquals("type", Recording.TYPE_PROGRAM, actual.getType());
+ }
+
+ public void testBuildTime() {
+ Recording actual = createTestRecordingWithIdAndPeriod(1, 10L, 20L);
+ assertEquals("type", Recording.TYPE_TIMED, actual.getType());
+ }
+
+ public void testBuildFrom() {
+ Recording expected = createTestRecordingWithIdAndPeriod(1, 10L, 20L);
+ Recording actual = Recording.buildFrom(expected).build();
+ RecordingTestUtils.assertRecordingEquals(expected, actual);
+ }
+
+ public void testBuild_priority() {
+ Recording a = normalizePriority(createTestRecordingWithIdAndPeriod(1, 10L, 20L));
+ Recording b = normalizePriority(createTestRecordingWithIdAndPeriod(2, 10L, 20L));
+ Recording c = normalizePriority(createTestRecordingWithIdAndPeriod(3, 10L, 20L));
+
+ // default priority
+ MoreAsserts.assertContentsInOrder(sortByPriority(c,b,a), a, b, c);
+
+ // make C preferred over B
+ c = Recording.buildFrom(c).setPriority(b.getPriority() - 1).build();
+ MoreAsserts.assertContentsInOrder(sortByPriority(c,b,a), a, c, b);
+ }
+
+ public Collection<Recording> sortByPriority(Recording a, Recording b, Recording c) {
+ List<Recording> list = Arrays.asList(a, b, c);
+ Collections.sort(list, Recording.PRIORITY_COMPARATOR);
+ return list;
+ }
+
private void assertOverLapping(boolean expected, long lower, long upper, Recording r) {
assertEquals("isOverlapping(Range(" + lower + "," + upper + "), recording " + r, expected,
r.isOverLapping(new Range<Long>(lower, upper)));
diff --git a/tests/unit/src/com/android/tv/dvr/SchedulerTest.java b/tests/unit/src/com/android/tv/dvr/SchedulerTest.java
index 281b055a..6748eddb 100644
--- a/tests/unit/src/com/android/tv/dvr/SchedulerTest.java
+++ b/tests/unit/src/com/android/tv/dvr/SchedulerTest.java
@@ -24,6 +24,8 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.os.Looper;
+import android.support.test.filters.SdkSuppress;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -39,6 +41,7 @@ import java.util.concurrent.TimeUnit;
* Tests for {@link Scheduler}.
*/
@SmallTest
+@SdkSuppress(minSdkVersion = 23)
public class SchedulerTest extends AndroidTestCase {
private FakeClock mClock;
private DvrDataManagerInMemoryImpl mDataManager;
@@ -52,8 +55,8 @@ public class SchedulerTest extends AndroidTestCase {
MockitoAnnotations.initMocks(this);
mClock = FakeClock.createWithCurrentTime();
mDataManager = new DvrDataManagerInMemoryImpl(getContext());
- mScheduler = new Scheduler(mSessionManager, mDataManager, getContext(), mClock,
- mMockAlarmManager);
+ mScheduler = new Scheduler(Looper.myLooper(), mSessionManager, mDataManager, getContext(),
+ mClock, mMockAlarmManager);
}
public void testUpdate_none() throws Exception {
@@ -64,7 +67,7 @@ public class SchedulerTest extends AndroidTestCase {
public void testUpdate_nextIn12Hours() throws Exception {
long now = mClock.currentTimeMillis();
long startTime = now + TimeUnit.HOURS.toMillis(12);
- Recording r = RecordingTestUtils.createTestRecordingWithPeriod(1, startTime,
+ Recording r = RecordingTestUtils.createTestRecordingWithPeriod(startTime,
startTime + TimeUnit.HOURS.toMillis(1));
mDataManager.addRecording(r);
mScheduler.update();
@@ -78,7 +81,7 @@ public class SchedulerTest extends AndroidTestCase {
long now = mClock.currentTimeMillis();
long startTime = now + 3;
Recording r = RecordingTestUtils
- .createTestRecordingWithPeriod(1, startTime, startTime + 100);
+ .createTestRecordingWithPeriod(startTime, startTime + 100);
assertFalse(mScheduler.startsWithin(r, 2));
assertTrue(mScheduler.startsWithin(r, 3));
}
diff --git a/tests/unit/src/com/android/tv/util/TestUtils.java b/tests/unit/src/com/android/tv/util/TestUtils.java
index db5e93cc..09d32779 100644
--- a/tests/unit/src/com/android/tv/util/TestUtils.java
+++ b/tests/unit/src/com/android/tv/util/TestUtils.java
@@ -32,7 +32,7 @@ public class TestUtils {
// Create a mock TvInputInfo by using private constructor
// TODO: Find better way to mock TvInputInfo.
// Note that mockito doesn't support mock/spy on final object.
- if (Build.VERSION.SDK_INT < 23) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return createTvInputInfoForLmp(service, id, parentId, type);
}
return createTvInputInfoForMnc(service, id, parentId, type, isHardwareInput);
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 162ff63d..42667bee 100644
--- a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
+++ b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
@@ -35,9 +35,9 @@ import java.util.Locale;
public class UtilsTest_GetDurationString extends AndroidTestCase {
// TODO: Mock Context so we can specify current time and locale for test.
private Locale mLocale;
- private static final long DATE_2015_2_1_MS = getFeb2015InMillis(1, 0, 0);
+ private static final long DATE_THIS_YEAR_2_1_MS = getFebOfThisYearInMillis(1, 0, 0);
- // All possible list for a paramter to test parameter independent result.
+ // All possible list for a parameter to test parameter independent result.
private static final boolean[] PARAM_USE_SHORT_FORMAT = {false, true};
@Override
@@ -49,192 +49,197 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
}
/**
- * Return time in millis assuming that whose year is 2015 and month is Jan.
+ * Return time in millis assuming that whose year is this year and month is Jan.
*/
- private static long getJan2015InMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(
- 2015, Calendar.JANUARY, date, hour, minutes).getTimeInMillis();
+ private static long getJanOfThisYearInMillis(int date, int hour, int minutes) {
+ return new GregorianCalendar(getThisYear(), Calendar.JANUARY, date, hour, minutes)
+ .getTimeInMillis();
}
- private static long getJan2015InMillis(int date, int hour) {
- return getJan2015InMillis(date, hour, 0);
+ private static long getJanOfThisYearInMillis(int date, int hour) {
+ return getJanOfThisYearInMillis(date, hour, 0);
}
/**
- * Return time in millis assuming that whose year is 2015 and month is Feb.
+ * Return time in millis assuming that whose year is this year and month is Feb.
*/
- private static long getFeb2015InMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(
- 2015, Calendar.FEBRUARY, date, hour, minutes).getTimeInMillis();
+ private static long getFebOfThisYearInMillis(int date, int hour, int minutes) {
+ return new GregorianCalendar(getThisYear(), Calendar.FEBRUARY, date, hour, minutes)
+ .getTimeInMillis();
}
- private static long getFeb2015InMillis(int date, int hour) {
- return getFeb2015InMillis(date, hour, 0);
+ private static long getFebOfThisYearInMillis(int date, int hour) {
+ return getFebOfThisYearInMillis(date, hour, 0);
+ }
+
+ private static int getThisYear() {
+ return new GregorianCalendar().get(GregorianCalendar.YEAR);
}
public void testSameDateAndTime() {
- assertEquals("3:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(1, 3), false,
+ assertEquals("3:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(1, 3), false,
DateUtils.FORMAT_12HOUR));
- assertEquals("03:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(1, 3), false,
+ assertEquals("03:00", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(1, 3), false,
DateUtils.FORMAT_24HOUR));
}
public void testDurationWithinToday() {
assertEquals("12:00 – 3:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, getFeb2015InMillis(1, 3), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), false,
DateUtils.FORMAT_12HOUR));
assertEquals("00:00 – 03:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, getFeb2015InMillis(1, 3), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), false,
DateUtils.FORMAT_24HOUR));
}
public void testDurationFromYesterdayToToday() {
assertEquals("Jan 31, 3:00 AM – Feb 1, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getJan2015InMillis(31, 3), getFeb2015InMillis(1, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getJanOfThisYearInMillis(31, 3), getFebOfThisYearInMillis(1, 4), false,
DateUtils.FORMAT_12HOUR));
assertEquals("Jan 31, 03:00 – Feb 1, 04:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getJan2015InMillis(31, 3), getFeb2015InMillis(1, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getJanOfThisYearInMillis(31, 3), getFebOfThisYearInMillis(1, 4), false,
DateUtils.FORMAT_24HOUR));
assertEquals("1/31, 11:30 PM – 12:30 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getJan2015InMillis(31, 23, 30), getFeb2015InMillis(1, 0, 30), true,
- DateUtils.FORMAT_12HOUR));
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getJanOfThisYearInMillis(31, 23, 30), getFebOfThisYearInMillis(1, 0, 30),
+ true, DateUtils.FORMAT_12HOUR));
assertEquals("1/31, 23:30 – 00:30",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getJan2015InMillis(31, 23, 30), getFeb2015InMillis(1, 0, 30), true,
- DateUtils.FORMAT_24HOUR));
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getJanOfThisYearInMillis(31, 23, 30), getFebOfThisYearInMillis(1, 0, 30),
+ true, DateUtils.FORMAT_24HOUR));
}
public void testDurationFromTodayToTomorrow() {
assertEquals("Feb 1, 3:00 AM – Feb 2, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(2, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), false,
DateUtils.FORMAT_12HOUR));
assertEquals("Feb 1, 03:00 – Feb 2, 04:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(2, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), false,
DateUtils.FORMAT_24HOUR));
assertEquals("2/1, 3:00 AM – 2/2, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(2, 4), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), true,
DateUtils.FORMAT_12HOUR));
assertEquals("2/1, 03:00 – 2/2, 04:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 3), getFeb2015InMillis(2, 4), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), true,
DateUtils.FORMAT_24HOUR));
assertEquals("Feb 1, 11:30 PM – Feb 2, 12:30 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23, 30), getFeb2015InMillis(2, 0, 30), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
+ false,
DateUtils.FORMAT_12HOUR));
assertEquals("Feb 1, 23:30 – Feb 2, 00:30",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23, 30), getFeb2015InMillis(2, 0, 30), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
+ false,
DateUtils.FORMAT_24HOUR));
assertEquals("11:30 PM – 12:30 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23, 30), getFeb2015InMillis(2, 0, 30), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
+ true,
DateUtils.FORMAT_12HOUR));
- assertEquals("23:30 – 00:30",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23, 30), getFeb2015InMillis(2, 0, 30), true,
+ assertEquals("23:30 – 00:30", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
+ true,
DateUtils.FORMAT_24HOUR));
}
public void testDurationWithinTomorrow() {
assertEquals("Feb 2, 2:00 – 4:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 2), getFeb2015InMillis(2, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), false,
DateUtils.FORMAT_12HOUR));
assertEquals("Feb 2, 02:00 – 04:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 2), getFeb2015InMillis(2, 4), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), false,
DateUtils.FORMAT_24HOUR));
assertEquals("2/2, 2:00 – 4:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 2), getFeb2015InMillis(2, 4), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), true,
DateUtils.FORMAT_12HOUR));
assertEquals("2/2, 02:00 – 04:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 2), getFeb2015InMillis(2, 4), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), true,
DateUtils.FORMAT_24HOUR));
}
public void testStartOfDay() {
assertEquals("12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, getFeb2015InMillis(1, 1), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 1), false,
DateUtils.FORMAT_12HOUR));
assertEquals("00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, getFeb2015InMillis(1, 1), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 1), false,
DateUtils.FORMAT_24HOUR));
assertEquals("Feb 2, 12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 0), getFeb2015InMillis(2, 1), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), false,
DateUtils.FORMAT_12HOUR));
assertEquals("Feb 2, 00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 0), getFeb2015InMillis(2, 1), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), false,
DateUtils.FORMAT_24HOUR));
assertEquals("2/2, 12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 0), getFeb2015InMillis(2, 1), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), true,
DateUtils.FORMAT_12HOUR));
assertEquals("2/2, 00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 0), getFeb2015InMillis(2, 1), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), true,
DateUtils.FORMAT_24HOUR));
}
public void testEndOfDay() {
for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
assertEquals("11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23), getFeb2015InMillis(2, 0), useShortFormat,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23), getFebOfThisYearInMillis(2, 0),
+ useShortFormat,
DateUtils.FORMAT_12HOUR));
assertEquals("23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(1, 23), getFeb2015InMillis(2, 0), useShortFormat,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(1, 23), getFebOfThisYearInMillis(2, 0),
+ useShortFormat,
DateUtils.FORMAT_24HOUR));
}
assertEquals("Feb 2, 11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 23), getFeb2015InMillis(3, 0), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), false,
DateUtils.FORMAT_12HOUR));
assertEquals("Feb 2, 23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 23), getFeb2015InMillis(3, 0), false,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), false,
DateUtils.FORMAT_24HOUR));
assertEquals("2/2, 11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 23), getFeb2015InMillis(3, 0), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), true,
DateUtils.FORMAT_12HOUR));
assertEquals("2/2, 23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- getFeb2015InMillis(2, 23), getFeb2015InMillis(3, 0), true,
+ Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), true,
DateUtils.FORMAT_24HOUR));
}
public void testMidnight() {
for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
- assertEquals("12:00 AM",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, DATE_2015_2_1_MS, useShortFormat,
+ assertEquals("12:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS, useShortFormat,
DateUtils.FORMAT_12HOUR));
- assertEquals("00:00",
- Utils.getDurationString(getContext(), DATE_2015_2_1_MS,
- DATE_2015_2_1_MS, DATE_2015_2_1_MS, useShortFormat,
+ assertEquals("00:00", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
+ DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS, useShortFormat,
DateUtils.FORMAT_24HOUR));
}
}
diff --git a/usbtuner/Android.mk b/usbtuner/Android.mk
index 27391cec..6f59b0d6 100644
--- a/usbtuner/Android.mk
+++ b/usbtuner/Android.mk
@@ -20,35 +20,25 @@ LOCAL_MODULE_TAGS := optional
LOCAL_PRIVILEGED_MODULE := true
LOCAL_SDK_VERSION := system_current
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-proto-files-under, proto)
-
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
- android-support-v7-recyclerview \
- android-support-v17-leanback \
- icu4j-usbtuner \
- libprotobuf-java-nano \
- tv-common
-
+ usbtuner-tvinput
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/res \
+ $(LOCAL_PATH)/../common/res \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res
LOCAL_AAPT_FLAGS := --auto-add-overlay \
- --extra-packages android.support.v17.leanback
+ --extra-packages android.support.v7.recyclerview \
+ --extra-packages android.support.v17.leanback \
+ --extra-packages com.android.tv.common
LOCAL_JNI_SHARED_LIBRARIES := \
libusbtuner_jni
LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/proto/
-
include $(BUILD_PACKAGE)
# --------------------------------------------------------------
@@ -78,11 +68,13 @@ LOCAL_PROGUARD_ENABLED := disabled
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/res \
+ $(LOCAL_PATH)/../common/res \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res
LOCAL_AAPT_FLAGS := --auto-add-overlay \
- --extra-packages android.support.v17.leanback
+ --extra-packages android.support.v17.leanback \
+ --extra-packages com.android.tv.common \
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/proto/
diff --git a/usbtuner/AndroidManifest.xml b/usbtuner/AndroidManifest.xml
index 2931650f..a763ed2d 100644
--- a/usbtuner/AndroidManifest.xml
+++ b/usbtuner/AndroidManifest.xml
@@ -34,17 +34,14 @@
<application
android:allowBackup="true">
<activity
- android:name="com.android.usbtuner.TunerSetupActivity"
+ android:name=".setup.TunerSetupActivity"
android:label="@string/ut_app_name"
- android:theme="@style/Theme.UsbTunerSetup.Leanback.GuidedStep"
+ android:theme="@style/Theme.Setup.GuidedStep"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
- <activity
- android:name="com.android.usbtuner.ScanActivity"
- android:process="com.android.usbtuner" />
<service
android:name="com.android.usbtuner.tvinput.UsbTunerTvInputService"
android:permission="android.permission.BIND_TV_INPUT" >
diff --git a/usbtuner/jni/Android.mk b/usbtuner/jni/Android.mk
index 5bf829b4..684830c9 100644
--- a/usbtuner/jni/Android.mk
+++ b/usbtuner/jni/Android.mk
@@ -3,8 +3,8 @@ LOCAL_PATH := $(call my-dir)
# --------------------------------------------------------------
include $(CLEAR_VARS)
-LOCAL_MODULE := libusbtuner_jni
-LOCAL_SRC_FILES += usbtuner_jni.cpp DvbManager.cpp
+LOCAL_MODULE := libtunertvinput_jni
+LOCAL_SRC_FILES += tunertvinput_jni.cpp DvbManager.cpp
LOCAL_SDK_VERSION := 21
LOCAL_NDK_STL_VARIANT := stlport_static
LOCAL_LDLIBS := -llog
diff --git a/usbtuner/jni/DvbManager.cpp b/usbtuner/jni/DvbManager.cpp
index 64c6bc32..fef756e3 100644
--- a/usbtuner/jni/DvbManager.cpp
+++ b/usbtuner/jni/DvbManager.cpp
@@ -44,7 +44,7 @@ DvbManager::DvbManager(JNIEnv *env, jobject)
mPatFilterFd(-1),
mFeHasLock(false) {
jclass clazz = env->FindClass(
- "com/android/usbtuner/UsbTunerInterface");
+ "com/android/usbtuner/TunerHal");
mOpenDvbFrontEndMethodID = env->GetMethodID(
clazz, "openDvbFrontEndFd", "()I");
mOpenDvbDemuxMethodID = env->GetMethodID(
@@ -66,7 +66,7 @@ bool DvbManager::isFeLocked() {
return false;
}
-int DvbManager::tuneAtsc(JNIEnv *env, jobject thiz,
+int DvbManager::tune(JNIEnv *env, jobject thiz,
const int frequency, const char *modulationStr, int timeout_ms) {
resetExceptFe();
diff --git a/usbtuner/jni/DvbManager.h b/usbtuner/jni/DvbManager.h
index 2bf46aba..c626335a 100644
--- a/usbtuner/jni/DvbManager.h
+++ b/usbtuner/jni/DvbManager.h
@@ -21,7 +21,7 @@
#include <map>
#include "mutex.h"
-#include "usbtuner_jni.h"
+#include "tunertvinput_jni.h"
class DvbManager {
static const int NUM_POLLFDS = 1;
@@ -32,13 +32,13 @@ class DvbManager {
static const int PAT_PID = 0;
static const int FILTER_TYPE_OTHER =
- com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_OTHER;
+ com_android_usbtuner_TunerHal_FILTER_TYPE_OTHER;
static const int FILTER_TYPE_AUDIO =
- com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_AUDIO;
+ com_android_usbtuner_TunerHal_FILTER_TYPE_AUDIO;
static const int FILTER_TYPE_VIDEO =
- com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_VIDEO;
+ com_android_usbtuner_TunerHal_FILTER_TYPE_VIDEO;
static const int FILTER_TYPE_PCR =
- com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_PCR;
+ com_android_usbtuner_TunerHal_FILTER_TYPE_PCR;
int mFeFd;
int mDemuxFd;
@@ -54,7 +54,7 @@ class DvbManager {
public:
DvbManager(JNIEnv *env, jobject thiz);
~DvbManager();
- int tuneAtsc(JNIEnv *env, jobject thiz,
+ int tune(JNIEnv *env, jobject thiz,
const int frequency, const char *modulationStr, int timeout_ms);
int stopTune();
int readTsStream(JNIEnv *env, jobject thiz,
diff --git a/usbtuner/jni/gen_jni.sh b/usbtuner/jni/gen_jni.sh
index 612bcf58..e81f9cb8 100755
--- a/usbtuner/jni/gen_jni.sh
+++ b/usbtuner/jni/gen_jni.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-javah -jni -classpath ../bin:../../../../../prebuilts/sdk/current/android.jar -o usbtuner_jni.h com.android.usbtuner.UsbTunerInterface
+javah -jni -classpath ../../bin/classes:../../../../../../prebuilts/sdk/current/android.jar -o tunertvinput_jni.h com.android.usbtuner.TunerHal
diff --git a/usbtuner/jni/usbtuner_jni.cpp b/usbtuner/jni/tunertvinput_jni.cpp
index cbbe8707..b72afbdb 100644
--- a/usbtuner/jni/usbtuner_jni.cpp
+++ b/usbtuner/jni/tunertvinput_jni.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include "usbtuner_jni.h"
+#include "tunertvinput_jni.h"
#include <map>
#include "DvbManager.h"
-#define LOG_TAG "usbtuner_jni"
+#define LOG_TAG "tunertvinput_jni"
#include "logging.h"
//-------------------------------------------------------------------------------
@@ -33,12 +33,12 @@ static int sTotalBytesFetched = 0;
static std::map<jlong, DvbManager *> sDvbManagers;
/*
- * Class: com_android_usbtuner_UsbTunerInterface
+ * Class: com_android_usbtuner_TunerHal
* Method: nativeFinalize
- * Signature: ()V
+ * Signature: (J)V
*/
JNIEXPORT void JNICALL
-Java_com_android_usbtuner_UsbTunerInterface_nativeFinalize
+Java_com_android_usbtuner_TunerHal_nativeFinalize
(JNIEnv *, jobject, jlong deviceId) {
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
if (it != sDvbManagers.end()) {
@@ -48,12 +48,12 @@ Java_com_android_usbtuner_UsbTunerInterface_nativeFinalize
}
/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeTuneAtsc
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeTune
* Signature: (JILjava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL
-Java_com_android_usbtuner_UsbTunerInterface_nativeTuneAtsc
+Java_com_android_usbtuner_TunerHal_nativeTune
(JNIEnv *env, jobject thiz, jlong deviceId, jint frequency, jstring modulation, jint timeout_ms) {
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
DvbManager *dvbManager;
@@ -63,17 +63,17 @@ Java_com_android_usbtuner_UsbTunerInterface_nativeTuneAtsc
} else {
dvbManager = it->second;
}
- int res = dvbManager->tuneAtsc(env, thiz,
+ int res = dvbManager->tune(env, thiz,
frequency, env->GetStringUTFChars(modulation, 0), timeout_ms);
return (res == 0);
}
/*
- * Class: com_android_usbtuner_UsbTunerInterface
+ * Class: com_android_usbtuner_TunerHal
* Method: nativeCloseAllPidFilters
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeCloseAllPidFilters
+JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeCloseAllPidFilters
(JNIEnv *, jobject, jlong deviceId) {
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
if (it != sDvbManagers.end()) {
@@ -82,12 +82,12 @@ JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeCloseAl
}
/*
- * Class: com_android_usbtuner_UsbTunerInterface
+ * Class: com_android_usbtuner_TunerHal
* Method: nativeStopTune
* Signature: (J)V
*/
JNIEXPORT void JNICALL
-Java_com_android_usbtuner_UsbTunerInterface_nativeStopTune
+Java_com_android_usbtuner_TunerHal_nativeStopTune
(JNIEnv *, jobject, jlong deviceId) {
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
if (it != sDvbManagers.end()) {
@@ -96,12 +96,12 @@ Java_com_android_usbtuner_UsbTunerInterface_nativeStopTune
}
/*
- * Class: com_android_usbtuner_UsbTunerInterface
+ * Class: com_android_usbtuner_TunerHal
* Method: nativeAddPidFilter
* Signature: (JII)V
*/
JNIEXPORT void JNICALL
-Java_com_android_usbtuner_UsbTunerInterface_nativeAddPidFilter
+Java_com_android_usbtuner_TunerHal_nativeAddPidFilter
(JNIEnv *env, jobject thiz, jlong deviceId, jint pid, jint filterType) {
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
if (it != sDvbManagers.end()) {
@@ -110,12 +110,12 @@ Java_com_android_usbtuner_UsbTunerInterface_nativeAddPidFilter
}
/*
- * Class: com_android_usbtuner_UsbTunerInterface
+ * Class: com_android_usbtuner_TunerHal
* Method: nativeWriteInBuffer
* Signature: (J[BI)I
*/
JNIEXPORT jint JNICALL
-Java_com_android_usbtuner_UsbTunerInterface_nativeWriteInBuffer
+Java_com_android_usbtuner_TunerHal_nativeWriteInBuffer
(JNIEnv *env, jobject thiz, jlong deviceId, jbyteArray javaBuffer, jint javaBufferSize) {
uint8_t tsBuffer[TS_PAYLOAD_SIZE];
std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
diff --git a/usbtuner/jni/tunertvinput_jni.h b/usbtuner/jni/tunertvinput_jni.h
new file mode 100644
index 00000000..5878740e
--- /dev/null
+++ b/usbtuner/jni/tunertvinput_jni.h
@@ -0,0 +1,90 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_usbtuner_TunerHal */
+
+#ifndef _Included_com_android_usbtuner_TunerHal
+#define _Included_com_android_usbtuner_TunerHal
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_android_usbtuner_TunerHal_DEBUG
+#define com_android_usbtuner_TunerHal_DEBUG 0L
+#undef com_android_usbtuner_TunerHal_FILTER_TYPE_OTHER
+#define com_android_usbtuner_TunerHal_FILTER_TYPE_OTHER 0L
+#undef com_android_usbtuner_TunerHal_FILTER_TYPE_AUDIO
+#define com_android_usbtuner_TunerHal_FILTER_TYPE_AUDIO 1L
+#undef com_android_usbtuner_TunerHal_FILTER_TYPE_VIDEO
+#define com_android_usbtuner_TunerHal_FILTER_TYPE_VIDEO 2L
+#undef com_android_usbtuner_TunerHal_FILTER_TYPE_PCR
+#define com_android_usbtuner_TunerHal_FILTER_TYPE_PCR 3L
+#undef com_android_usbtuner_TunerHal_PID_PAT
+#define com_android_usbtuner_TunerHal_PID_PAT 0L
+#undef com_android_usbtuner_TunerHal_PID_ATSC_SI_BASE
+#define com_android_usbtuner_TunerHal_PID_ATSC_SI_BASE 8187L
+#undef com_android_usbtuner_TunerHal_DEFAULT_VSB_TUNE_TIMEOUT_MS
+#define com_android_usbtuner_TunerHal_DEFAULT_VSB_TUNE_TIMEOUT_MS 2000L
+#undef com_android_usbtuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS
+#define com_android_usbtuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS 4000L
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeFinalize
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeFinalize
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeTune
+ * Signature: (JILjava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_android_usbtuner_TunerHal_nativeTune
+ (JNIEnv *, jobject, jlong, jint, jstring, jint);
+
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeAddPidFilter
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeAddPidFilter
+ (JNIEnv *, jobject, jlong, jint, jint);
+
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeCloseAllPidFilters
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeCloseAllPidFilters
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeStopTune
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeStopTune
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_android_usbtuner_TunerHal
+ * Method: nativeWriteInBuffer
+ * Signature: (J[BI)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_usbtuner_TunerHal_nativeWriteInBuffer
+ (JNIEnv *, jobject, jlong, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class com_android_usbtuner_TunerHal_FilterType */
+
+#ifndef _Included_com_android_usbtuner_TunerHal_FilterType
+#define _Included_com_android_usbtuner_TunerHal_FilterType
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/usbtuner/jni/usbtuner_jni.h b/usbtuner/jni/usbtuner_jni.h
deleted file mode 100644
index ba16b667..00000000
--- a/usbtuner/jni/usbtuner_jni.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class com_android_usbtuner_UsbTunerInterface */
-
-#ifndef _Included_com_android_usbtuner_UsbTunerInterface
-#define _Included_com_android_usbtuner_UsbTunerInterface
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef com_android_usbtuner_UsbTunerInterface_DEBUG
-#define com_android_usbtuner_UsbTunerInterface_DEBUG 0L
-#undef com_android_usbtuner_UsbTunerInterface_PROGRAM_NO_UNDEFINED
-#define com_android_usbtuner_UsbTunerInterface_PROGRAM_NO_UNDEFINED -1L
-#undef com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_OTHER
-#define com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_OTHER 0L
-#undef com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_AUDIO
-#define com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_AUDIO 1L
-#undef com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_VIDEO
-#define com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_VIDEO 2L
-#undef com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_PCR
-#define com_android_usbtuner_UsbTunerInterface_FILTER_TYPE_PCR 3L
-#undef com_android_usbtuner_UsbTunerInterface_PID_PAT
-#define com_android_usbtuner_UsbTunerInterface_PID_PAT 0L
-#undef com_android_usbtuner_UsbTunerInterface_PID_ATSC_SI_BASE
-#define com_android_usbtuner_UsbTunerInterface_PID_ATSC_SI_BASE 8187L
-#undef com_android_usbtuner_UsbTunerInterface_DEFAULT_TUNE_TIMEOUT_MS
-#define com_android_usbtuner_UsbTunerInterface_DEFAULT_TUNE_TIMEOUT_MS 4000L
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeFinalize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeFinalize
- (JNIEnv *, jobject, jlong);
-
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeTuneAtsc
- * Signature: (JILjava/lang/String;I)Z
- */
-JNIEXPORT jboolean JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeTuneAtsc
- (JNIEnv *, jobject, jlong, jint, jstring, jint);
-
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeAddPidFilter
- * Signature: (JII)V
- */
-JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeAddPidFilter
- (JNIEnv *, jobject, jlong, jint, jint);
-
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeCloseAllPidFilters
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeCloseAllPidFilters
- (JNIEnv *, jobject, jlong);
-
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeStopTune
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeStopTune
- (JNIEnv *, jobject, jlong);
-
-/*
- * Class: com_android_usbtuner_UsbTunerInterface
- * Method: nativeWriteInBuffer
- * Signature: (J[BI)I
- */
-JNIEXPORT jint JNICALL Java_com_android_usbtuner_UsbTunerInterface_nativeWriteInBuffer
- (JNIEnv *, jobject, jlong, jbyteArray, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/usbtuner/res/layout/ut_channel_scan.xml b/usbtuner/res/layout/ut_channel_scan.xml
index 5f9b5e76..4579b81b 100644
--- a/usbtuner/res/layout/ut_channel_scan.xml
+++ b/usbtuner/res/layout/ut_channel_scan.xml
@@ -15,12 +15,10 @@
~ limitations under the License.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
- android:background="@color/ut_guidedstep_background"
android:animateLayoutChanges="true"
android:keepScreenOn="true" >
<LinearLayout
@@ -66,6 +64,7 @@
android:progressDrawable="@drawable/ut_scan_progress" />
<TextView
android:id="@+id/tune_description"
+ android:accessibilityLiveRegion="polite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/ut_scan_description_margin_top"
@@ -81,12 +80,13 @@
android:layout_width="wrap_content"
android:layout_height="@dimen/ut_scan_button_height"
android:layout_marginTop="@dimen/ut_scan_button_margin_top"
- android:layout_marginLeft="@dimen/ut_scan_icon_margin_right_for_button"
+ android:layout_marginLeft="@dimen/ut_scan_icon_margin_right"
android:layout_below="@id/tune_description"
android:layout_toRightOf="@id/tune_icon"
android:paddingLeft="@dimen/ut_scan_button_padding"
android:paddingRight="@dimen/ut_scan_button_padding"
android:textAllCaps="false"
+ android:focusable="true"
android:fontFamily="sans-serif-condensed"
android:textColor="@color/ut_scan_button_text"
android:textSize="@dimen/ut_scan_button_text_size"
@@ -98,7 +98,10 @@
android:id="@+id/channel_holder"
android:layout_width="@dimen/ut_scan_channellist_width"
android:layout_height="match_parent"
- android:animateLayoutChanges="true" >
+ android:focusable="false"
+ android:descendantFocusability="blocksDescendants"
+ android:animateLayoutChanges="true"
+ android:visibility="gone">
<ListView
android:id="@+id/channel_list"
android:layout_width="match_parent"
@@ -108,6 +111,7 @@
android:paddingStart="@dimen/ut_scan_channellist_padding_start"
android:divider="@android:color/transparent"
android:scrollbars="none"
- android:dividerHeight="7dp" />
+ android:dividerHeight="7dp"
+ android:transcriptMode="alwaysScroll" />
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/usbtuner/res/values-af/strings.xml b/usbtuner/res/values-af/strings.xml
index a57d3714..67571ec2 100644
--- a/usbtuner/res/values-af/strings.xml
+++ b/usbtuner/res/values-af/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Opstelling van USB-kanaalinstemmer"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Dit kan \'n paar minute neem"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanaal gevind"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanale gevind"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanale is gevind</item>
+ <item quantity="one">%1$d kanaal is gevind</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOP KANAALSKANDERING"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanaal gevind"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanale gevind"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Mooi! %1$d kanaal is tydens die kanaalskandering gevind. As dit nie reg lyk nie, probeer die antennaposisie verstel en skandeer weer."</item>
- <item quantity="other" msgid="8098777464551209564">"Mooi! %1$d kanale is tydens die kanaalskandering gevind. As dit nie reg lyk nie, probeer die antennaposisie verstel en skandeer weer."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanale is gevind</item>
+ <item quantity="one">%1$d kanaal is gevind</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Lekker! %1$d kanale is tydens die kanaalsoektog gevind. As dit nie reg lyk nie, probeer die antennaposisie verstel en soek weer.</item>
+ <item quantity="one">Lekker! %1$d kanaal is tydens die kanaalsoektog gevind. As dit nie reg lyk nie, probeer die antennaposisie verstel en soek weer.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Klaar"</item>
<item msgid="496688122303154468">"Skandeer weer"</item>
diff --git a/usbtuner/res/values-am/strings.xml b/usbtuner/res/values-am/strings.xml
index ca120c8c..cfcfed06 100644
--- a/usbtuner/res/values-am/strings.xml
+++ b/usbtuner/res/values-am/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"የዩኤስቢ ሰርጥ ማስተካከያ ቅንብር"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ይሄ በርካታ ደቂቃዎችን ሊወስድ ይችላል"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ሰርጥ ተገኝቷል"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ሰርጦች ተገኝተዋል"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d ሰርጦች ተገኝቷል</item>
+ <item quantity="other">%1$d ሰርጦች ተገኝቷል</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"የጣቢያ ቅኝትን አቁም"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ሰርጥ ተገኝቷል"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ሰርጦች ተገኝተዋል"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"በጣም ጥሩ! በጣቢያ መቃኘት ጊዜ %1$d ጣቢያ ተገኝቷል። ልክ ካልመሰለ የአንቴናውን አቀማመጥ አስተካክለው ይሞክሩና እንደገና ይቃኙ።"</item>
- <item quantity="other" msgid="8098777464551209564">"በጣም ጥሩ! በጣቢያ መቃኘት ጊዜ %1$d ጣቢያዎች ተገኝተዋል። ልክ ካልመሰለ የአንቴናውን አቀማመጥ አስተካክለው ይሞክሩና እንደገና ይቃኙ።"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d ሰርጦች ተገኝተዋል</item>
+ <item quantity="other">%1$d ሰርጦች ተገኝተዋል</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">ግሩም! በሰርጥ ቅኝት ጊዜ %1$d ሰርጦች ተገኝተዋል። ትክክል የማይመስል ከሆነ የአንቴናውን አቀማመጥ አስተካክለው እንደገና ለመቃኘት ይሞክሩ።</item>
+ <item quantity="other">ግሩም! በሰርጥ ቅኝት ጊዜ %1$d ሰርጦች ተገኝተዋል። ትክክል የማይመስል ከሆነ የአንቴናውን አቀማመጥ አስተካክለው እንደገና ለመቃኘት ይሞክሩ።</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"ተከናውኗል"</item>
<item msgid="496688122303154468">"እንደገና ቃኝ"</item>
diff --git a/usbtuner/res/values-ar/strings.xml b/usbtuner/res/values-ar/strings.xml
index 9041e6d4..7210ec13 100644
--- a/usbtuner/res/values-ar/strings.xml
+++ b/usbtuner/res/values-ar/strings.xml
@@ -50,19 +50,31 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"‏إعداد موالف قنوات USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"قد يستغرق هذا عدة دقائق"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"‏تم العثور على قناة واحدة (%1$d)"</item>
- <item quantity="other" msgid="7340557317633613">"‏تم العثور على %1$d من القنوات"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="zero">‏تم العثور على %1$d قناة</item>
+ <item quantity="two">‏تم العثور على قناتين (%1$d)</item>
+ <item quantity="few">‏تم العثور على %1$d قنوات</item>
+ <item quantity="many">‏تم العثور على %1$d قناة</item>
+ <item quantity="other">‏تم العثور على %1$d قناة</item>
+ <item quantity="one">‏تم العثور على %1$d قناة</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"إيقاف البحث عن القنوات"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"‏تم العثور على قناة واحدة (%1$d)"</item>
- <item quantity="other" msgid="4331542666115153576">"‏تم العثور على %1$d من القنوات"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"‏حسنًا! تم العثور على قناة واحدة (%1$d) أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فحاول تعديل موضع الهوائي ثم أعِدْ البحث."</item>
- <item quantity="other" msgid="8098777464551209564">"‏حسنًا! تم العثور على %1$d من القنوات أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فحاول تعديل موضع الهوائي ثم أعِدْ البحث."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="zero">‏تم العثور على %1$d قناة</item>
+ <item quantity="two">‏تم العثور على قناتين (%1$d)</item>
+ <item quantity="few">‏تم العثور على %1$d قنوات</item>
+ <item quantity="many">‏تم العثور على %1$d قناة</item>
+ <item quantity="other">‏تم العثور على %1$d قناة</item>
+ <item quantity="one">‏تم العثور على %1$d قناة</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="zero">‏جيد! تم العثور على %1$d قناة أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ <item quantity="two">‏جيد! تم العثور على قناتين (%1$d) أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ <item quantity="few">‏جيد! تم العثور على %1$d قنوات أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ <item quantity="many">‏جيد! تم العثور على %1$d قناة أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ <item quantity="other">‏جيد! تم العثور على %1$d قناة أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ <item quantity="one">‏جيد! تم العثور على %1$d قناة أثناء البحث عن القنوات. إذا كان ذلك لا يبدو صحيحًا، فجرِّب ضبط موضع الهوائي وإعادة البحث.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"تم"</item>
<item msgid="496688122303154468">"بحث مرة أخرى"</item>
diff --git a/usbtuner/res/values-az-rAZ/strings.xml b/usbtuner/res/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..30da5e32
--- /dev/null
+++ b/usbtuner/res/values-az-rAZ/strings.xml
@@ -0,0 +1,78 @@
+<?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="ut_app_name" msgid="1442714127635348166">"USB Sazlayıcı TV Daxiletməsi"</string>
+ <string name="ut_setup_on" msgid="4957025496015647961">"Aktiv"</string>
+ <string name="ut_setup_off" msgid="806521579574068484">"Deaktiv"</string>
+ <string name="ut_setup_cancel" msgid="6173771946434222551">"Lütfən, prosesi başa çatdırmaq üçün gözləyin"</string>
+ <string name="ut_select_channel_map" msgid="5007263088526410938">"Kanal mənbəyinizi seçin"</string>
+ <string name="ut_no_signal" msgid="6484545357071124354">"Siqnal Yoxdur"</string>
+ <string name="ut_fail_to_tune" msgid="3995508747351098234">"<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="5601031631838024181">"Sazlamaq uğursuz oldu"</string>
+ <string name="ut_rescan_needed" msgid="6652963050118174284">"USB sazlayıcı proqram təminatı yenicə güncəllənib. Kanalları yenidən skan edin."</string>
+ <string name="ut_ac3_passthrough_unavailable" msgid="1511045190687189559">"AC3 audiosu mövcud deyil"</string>
+ <string name="ut_setup_breadcrumb" msgid="3057650688133018018">"Kanal kökləyici quraşdırması"</string>
+ <string name="ut_setup_new_title" msgid="4919412630138697597">"USB kanal kökləyici quraşdırmas"</string>
+ <string name="ut_setup_new_description" msgid="3950618124169419729">"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="4294610848989236664">"Davam edin"</item>
+ <item msgid="7745727658174773453">"İndi yox"</item>
+ </string-array>
+ <string name="ut_setup_again_title" msgid="7493163856853246710">"Kanal quraşdırması yenidən işə salınsın?"</string>
+ <string name="ut_setup_again_description" msgid="6974243332718382952">"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="8729290093918719208">"Davam edin"</item>
+ <item msgid="4432431398374089710">"Ləğv edin"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="1689960211113015793">"Bağlantı növünü seçin"</string>
+ <string name="ut_connection_description" msgid="3218265227667113165">"Ə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="1633072563555330217">"Antena"</item>
+ <item msgid="2445879869338877559">"Kabel"</item>
+ <item msgid="597328838068074806">"Əmin deyiləm"</item>
+ <item msgid="3613410733017077040">"Yalnız inkişaf"</item>
+ </string-array>
+ <string name="ut_channel_scan" msgid="5275436876483779315">"USB Kanal kökləyici quraşdırması"</string>
+ <string name="ut_channel_scan_time" msgid="5108578893396614867">"Bu bir neçə dəqiqə çəkə bilər"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <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="8358794117343664624">"KANAL SKANINI DAYANDIRIN"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Hazırdır"</item>
+ <item msgid="496688122303154468">"Yenidən skan edin"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="3367485970267699896">"Kanal tapılmadı"</string>
+ <string name="ut_result_not_found_description" msgid="2230088613315287072">"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="6593834378620684951">"Yenidən skan edin"</item>
+ <item msgid="6784975565864102291">"Hazırdır"</item>
+ </string-array>
+ <string name="ut_setup_recommendation_card_focused_title" msgid="1003442802579648042">"TV kanalları üçün Skan"</string>
+ <string name="ut_setup_recommendation_card_title" msgid="4192974818384769494">"USB Kanal kökləyici quraşdırması"</string>
+</resources>
diff --git a/usbtuner/res/values-bg/strings.xml b/usbtuner/res/values-bg/strings.xml
index 35737ea1..9f7393a8 100644
--- a/usbtuner/res/values-bg/strings.xml
+++ b/usbtuner/res/values-bg/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Настройване на USB тунера за канали"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Това може да отнеме няколко минути"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Намерен е %1$d канал"</item>
- <item quantity="other" msgid="7340557317633613">"Намерени са %1$d каналa"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Намерени са %1$d канала</item>
+ <item quantity="one">Намерен е %1$d канал</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"СПИРАНЕ НА СКАНИРАНЕТО ЗА КАНАЛИ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Намерен е %1$d канал"</item>
- <item quantity="other" msgid="4331542666115153576">"Намерени са %1$d каналa"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Много добре! По време на сканирането бе намерен %1$d канал. Ако това не изглежда вярно, опитайте да коригирате позицията на антената и сканирайте отново."</item>
- <item quantity="other" msgid="8098777464551209564">"Много добре! По време на сканирането бяха намерени %1$d канала. Ако това не изглежда вярно, опитайте да коригирате позицията на антената и сканирайте отново."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">Намерени са %1$d канала</item>
+ <item quantity="one">Намерен е %1$d канал</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Много добре! По време на сканирането бяха намерени %1$d канала. Ако това не изглежда вярно, опитайте да коригирате позицията на антената и сканирайте отново.</item>
+ <item quantity="one">Много добре! По време на сканирането бе намерен %1$d канал. Ако това не изглежда вярно, опитайте да коригирате позицията на антената и сканирайте отново.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Готово"</item>
<item msgid="496688122303154468">"Повторно сканиране"</item>
diff --git a/usbtuner/res/values-bn-rBD/strings.xml b/usbtuner/res/values-bn-rBD/strings.xml
index 93c55e71..e15fefd3 100644
--- a/usbtuner/res/values-bn-rBD/strings.xml
+++ b/usbtuner/res/values-bn-rBD/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB চ্যানেল টিউনার সেটআপ"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"এটি কয়েক মিনিট সময় নিতে পারে"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$dটি চ্যানেল পাওয়া গেছে"</item>
- <item quantity="other" msgid="7340557317633613">"%1$dটি চ্যানেল পাওয়া গেছে"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"চ্যানেল স্ক্যান করা থামান"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$dটি চ্যানেল পাওয়া গেছে"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$dটি চ্যানেল পাওয়া গেছে"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"খুব ভাল! চ্যানেলে স্ক্যান করার সময় %1$dটি চ্যানেলে খুঁজে পাওয়া গেছে৷ এটিকে যদি সঠিক বলে মনে না হয় তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন এবং আবার স্ক্যান করুন৷"</item>
- <item quantity="other" msgid="8098777464551209564">"খুব ভাল! চ্যানেলে স্ক্যান করার সময় %1$dটি চ্যানেলে খুঁজে পাওয়া গেছে৷ এটিকে যদি সঠিক বলে মনে না হয় তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন এবং আবার স্ক্যান করুন৷"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
+ <item quantity="other">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"সম্পন্ন"</item>
<item msgid="496688122303154468">"আবার স্ক্যান করুন"</item>
diff --git a/usbtuner/res/values-ca/strings.xml b/usbtuner/res/values-ca/strings.xml
index 672387a7..026ad147 100644
--- a/usbtuner/res/values-ca/strings.xml
+++ b/usbtuner/res/values-ca/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuració del sintonitzador de canals USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Aquesta acció pot tardar uns quants minuts"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"S\'ha trobat %1$d canal"</item>
- <item quantity="other" msgid="7340557317633613">"S\'han trobat %1$d canals"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">S\'han trobat %1$d canals</item>
+ <item quantity="one">S\'ha trobat %1$d canal</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ATURA LA CERCA DE CANALS"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"S\'ha trobat %1$d canal"</item>
- <item quantity="other" msgid="4331542666115153576">"S\'han trobat %1$d canals"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Fantàstic. S\'ha trobat %1$d canal durant la cerca de canals. Si no et sembla correcte, prova d\'ajustar la posició de l\'antena i torna a cercar."</item>
- <item quantity="other" msgid="8098777464551209564">"Fantàstic. S\'han trobat %1$d canals durant la cerca de canals. Si no et sembla correcte, prova d\'ajustar la posició de l\'antena i torna a cercar."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">S\'han trobat %1$d canals</item>
+ <item quantity="one">S\'ha trobat %1$d canal</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Molt bé! S\'han trobat %1$d canals durant la cerca de canals. Si creus que no és correcte, prova d\'ajustar la posició de l\'antena i torna a cercar.</item>
+ <item quantity="one">Molt bé! S\'ha trobat %1$d canal durant la cerca de canals. Si creus que no és correcte, prova d\'ajustar la posició de l\'antena i torna a cercar.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Fet"</item>
<item msgid="496688122303154468">"Torna a cercar"</item>
diff --git a/usbtuner/res/values-cs/strings.xml b/usbtuner/res/values-cs/strings.xml
index d2254d09..6a6c94b2 100644
--- a/usbtuner/res/values-cs/strings.xml
+++ b/usbtuner/res/values-cs/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Nastavení tuneru kanálů USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Tato akce může trvat několik minut"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Byl nalezen %1$d kanál"</item>
- <item quantity="other" msgid="7340557317633613">"Počet nalezených kanálů: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="few">Byly nalezeny %1$d kanály</item>
+ <item quantity="many">Bylo nalezeno %1$d kanálu</item>
+ <item quantity="other">Bylo nalezeno %1$d kanálů</item>
+ <item quantity="one">Byl nalezen %1$d kanál</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ZASTAVIT VYHLEDÁVÁNÍ KANÁLŮ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Byl nalezen %1$d kanál"</item>
- <item quantity="other" msgid="4331542666115153576">"Počet nalezených kanálů: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Úspěch! Při vyhledávání byl nalezen %1$d kanál. Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu."</item>
- <item quantity="other" msgid="8098777464551209564">"Úspěch! Při vyhledávání bylo nalezeno více kanálů (%1$d). Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="few">Byly nalezeny %1$d kanály</item>
+ <item quantity="many">Bylo nalezeno %1$d kanálu</item>
+ <item quantity="other">Bylo nalezeno %1$d kanálů</item>
+ <item quantity="one">Byl nalezen %1$d kanál</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="few">Úspěch! Při vyhledávání byly nalezeny %1$d kanály. Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu.</item>
+ <item quantity="many">Úspěch! Při vyhledávání bylo nalezeno %1$d kanálu. Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu.</item>
+ <item quantity="other">Úspěch! Při vyhledávání bylo nalezeno %1$d kanálů. Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu.</item>
+ <item quantity="one">Úspěch! Při vyhledávání byl nalezen %1$d kanál. Pokud vám to nepřipadá správně, zkuste upravit pozici antény a provést vyhledávání znovu.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Hotovo"</item>
<item msgid="496688122303154468">"Znovu prohledat"</item>
diff --git a/usbtuner/res/values-da/strings.xml b/usbtuner/res/values-da/strings.xml
index d52afca7..1eb72373 100644
--- a/usbtuner/res/values-da/strings.xml
+++ b/usbtuner/res/values-da/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Konfiguration af USB-kanaltuneren"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Dette kan tage flere minutter"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanal blev fundet"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanaler blev fundet"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Der blev fundet %1$d kanal</item>
+ <item quantity="other">Der blev fundet %1$d kanaler</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOP KANALSCANNINGEN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanal blev fundet"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanaler blev fundet"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Sådan! %1$d kanal blev fundet under kanalscanningen. Hvis du mener, at antallet er forkert, kan du prøve at justere antennens position og scanne igen."</item>
- <item quantity="other" msgid="8098777464551209564">"Sådan! %1$d kanaler blev fundet under kanalscanningen. Hvis du mener, at antallet er forkert, kan du prøve at justere antennens position og scanne igen."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Der blev fundet %1$d kanal</item>
+ <item quantity="other">Der blev fundet %1$d kanaler</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Sådan! Der blev fundet %1$d kanal ved kanalsøgningen. Hvis du mener, det er forkert, kan du prøve at justere antennens position og søge igen.</item>
+ <item quantity="other">Sådan! Der blev fundet %1$d kanaler ved kanalsøgningen. Hvis du mener, det er forkert, kan du prøve at justere antennens position og søge igen.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Udført"</item>
<item msgid="496688122303154468">"Scan igen"</item>
diff --git a/usbtuner/res/values-de/strings.xml b/usbtuner/res/values-de/strings.xml
index 95f269c6..85c54fed 100644
--- a/usbtuner/res/values-de/strings.xml
+++ b/usbtuner/res/values-de/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Kanaleinrichtung über den USB-Tuner"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Dies kann einige Minuten dauern."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d Kanal gefunden"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d Kanäle gefunden"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d Kanäle gefunden</item>
+ <item quantity="one">%1$d Kanal gefunden</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"KANALSUCHE STOPPEN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d Kanal gefunden"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d Kanäle gefunden"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bei der Kanalsuche wurde %1$d Kanal gefunden. Wenn Sie vermuten, dass dies nicht korrekt ist, ändern Sie die Antennenposition und versuchen Sie es erneut."</item>
- <item quantity="other" msgid="8098777464551209564">"Bei der Kanalsuche wurden %1$d Kanäle gefunden. Wenn Sie vermuten, dass dies nicht korrekt ist, ändern Sie die Antennenposition und versuchen Sie es erneut."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d Kanäle gefunden</item>
+ <item quantity="one">%1$d Kanal gefunden</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Bei der Kanalsuche wurden %1$d Kanäle gefunden. Wenn Sie vermuten, dass dies nicht korrekt ist, ändern Sie die Antennenposition und versuchen Sie es noch einmal.</item>
+ <item quantity="one">Bei der Kanalsuche wurde %1$d Kanal gefunden. Wenn Sie vermuten, dass dies nicht korrekt ist, ändern Sie die Antennenposition und versuchen Sie es noch einmal.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Fertig"</item>
<item msgid="496688122303154468">"Erneut suchen"</item>
diff --git a/usbtuner/res/values-el/strings.xml b/usbtuner/res/values-el/strings.xml
index b19af481..f447ef7e 100644
--- a/usbtuner/res/values-el/strings.xml
+++ b/usbtuner/res/values-el/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Ρύθμιση δέκτη καναλιών USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Αυτό μπορεί να διαρκέσει αρκετά λεπτά"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Βρέθηκε %1$d κανάλι"</item>
- <item quantity="other" msgid="7340557317633613">"Βρέθηκαν %1$d κανάλια"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Βρέθηκαν %1$d κανάλια</item>
+ <item quantity="one">Βρέθηκε %1$d κανάλι</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ΔΙΑΚΟΠΗ ΣΑΡΩΣΗΣ ΚΑΝΑΛΙΩΝ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Βρέθηκε %1$d κανάλι"</item>
- <item quantity="other" msgid="4331542666115153576">"Βρέθηκαν %1$d κανάλια"</item>
- </plurals>
- <!-- String.format failed for translation -->
- <!-- no translation found for ut_result_found_description:one (3464139901043217695) -->
- <!-- String.format failed for translation -->
- <!-- no translation found for ut_result_found_description:other (8098777464551209564) -->
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">Βρέθηκαν %1$d κανάλια</item>
+ <item quantity="one">Βρέθηκε %1$d κανάλι</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Ωραία! Βρέθηκαν %1$d κανάλια κατά τη σάρωση καναλιών. Εάν αυτό δεν φαίνεται σωστό, δοκιμάστε να ρυθμίσετε τη θέση της κεραίας και επαναλάβετε τη σάρωση.</item>
+ <item quantity="one">Ωραία! Βρέθηκε %1$d κανάλι κατά τη σάρωση καναλιών. Εάν αυτό δεν φαίνεται σωστό, δοκιμάστε να ρυθμίσετε τη θέση της κεραίας και επαναλάβετε τη σάρωση.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Τέλος"</item>
<item msgid="496688122303154468">"Εκ νέου σάρωση"</item>
diff --git a/usbtuner/res/values-en-rAU/strings.xml b/usbtuner/res/values-en-rAU/strings.xml
index 8506b180..78e4598b 100644
--- a/usbtuner/res/values-en-rAU/strings.xml
+++ b/usbtuner/res/values-en-rAU/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"This may take several minutes"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d channel found"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d channels found"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOP CHANNEL SCAN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d channel found"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d channels found"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- <item quantity="other" msgid="8098777464551209564">"Nice! %1$d channels were found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">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="one">Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the antenna position and scan again.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Finished"</item>
<item msgid="496688122303154468">"Scan again"</item>
diff --git a/usbtuner/res/values-en-rGB/strings.xml b/usbtuner/res/values-en-rGB/strings.xml
index 8506b180..78e4598b 100644
--- a/usbtuner/res/values-en-rGB/strings.xml
+++ b/usbtuner/res/values-en-rGB/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"This may take several minutes"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d channel found"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d channels found"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOP CHANNEL SCAN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d channel found"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d channels found"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- <item quantity="other" msgid="8098777464551209564">"Nice! %1$d channels were found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">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="one">Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the antenna position and scan again.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Finished"</item>
<item msgid="496688122303154468">"Scan again"</item>
diff --git a/usbtuner/res/values-en-rIN/strings.xml b/usbtuner/res/values-en-rIN/strings.xml
index 8506b180..78e4598b 100644
--- a/usbtuner/res/values-en-rIN/strings.xml
+++ b/usbtuner/res/values-en-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"This may take several minutes"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d channel found"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d channels found"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOP CHANNEL SCAN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d channel found"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d channels found"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- <item quantity="other" msgid="8098777464551209564">"Nice! %1$d channels were found during the channel scan. If this doesn’t seem right, try adjusting the aerial position and scan again."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d channels found</item>
+ <item quantity="one">%1$d channel found</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">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="one">Nice! %1$d channel was found during the channel scan. If this doesn’t seem right, try adjusting the antenna position and scan again.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Finished"</item>
<item msgid="496688122303154468">"Scan again"</item>
diff --git a/usbtuner/res/values-es-rUS/strings.xml b/usbtuner/res/values-es-rUS/strings.xml
index f1e64a09..cf2a28d4 100644
--- a/usbtuner/res/values-es-rUS/strings.xml
+++ b/usbtuner/res/values-es-rUS/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuración del sintonizador de canales USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Este proceso podría demorar varios minutos"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Se encontró %1$d canal"</item>
- <item quantity="other" msgid="7340557317633613">"Se encontraron %1$d canales"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Se encontraron %1$d canales</item>
+ <item quantity="one">Se encontró %1$d canal</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"DETENER LA BÚSQUEDA DE CANALES"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Se encontró %1$d canal"</item>
- <item quantity="other" msgid="4331542666115153576">"Se encontraron %1$d canales"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Se encontró %1$d canal durante la búsqueda de canales. Si crees que el resultado no es correcto, ajusta la posición de la antena y vuelve a hacer la búsqueda."</item>
- <item quantity="other" msgid="8098777464551209564">"Se encontraron %1$d canales durante la búsqueda de canales. Si crees que el resultado no es correcto, ajusta la posición de la antena y vuelve a hacer la búsqueda."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">Se encontraron %1$d canales</item>
+ <item quantity="one">Se encontró %1$d canal</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Genial. Se encontraron %1$d canales durante la búsqueda de canales. Si crees que el resultado es incorrecto, ajusta la posición de la antena y vuelve a realizar la búsqueda.</item>
+ <item quantity="one">Genial. Se encontró %1$d canal durante la búsqueda de canales. Si crees que el resultado es incorrecto, ajusta la posición de la antena y vuelve a realizar la búsqueda.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Listo"</item>
<item msgid="496688122303154468">"Volver a buscar"</item>
diff --git a/usbtuner/res/values-es/strings.xml b/usbtuner/res/values-es/strings.xml
index a11d8084..00913ad0 100644
--- a/usbtuner/res/values-es/strings.xml
+++ b/usbtuner/res/values-es/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuración de sintonizador de canales USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Este proceso puede tardar varios minutos"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d canales encontrados"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d canales encontrados</item>
+ <item quantity="one">%1$d canal encontrado</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"DETENER LA BÚSQUEDA DE CANALES"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d canales encontrados"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"¡Genial! Se ha encontrado %1$d canal durante la búsqueda de canales. Si no se ve correctamente, modifica la posición de la antena y vuelve a realizar la búsqueda."</item>
- <item quantity="other" msgid="8098777464551209564">"¡Genial! Se han encontrado %1$d canales durante la búsqueda de canales. Si no se ven correctamente, modifica la posición de la antena y vuelve a realizar la búsqueda."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d canales encontrados</item>
+ <item quantity="one">%1$d canal encontrado</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">¡Genial! Se han encontrado %1$d canales durante la búsqueda de canales. Si no se ven correctamente, modifica la posición de la antena y vuelve a realizar la búsqueda.</item>
+ <item quantity="one">¡Genial! Se ha encontrado %1$d canal durante la búsqueda de canales. Si no se ve correctamente, modifica la posición de la antena y vuelve a realizar la búsqueda.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Listo"</item>
<item msgid="496688122303154468">"Volver a buscar"</item>
diff --git a/usbtuner/res/values-et-rEE/strings.xml b/usbtuner/res/values-et-rEE/strings.xml
index 2d479b41..9ffb7227 100644
--- a/usbtuner/res/values-et-rEE/strings.xml
+++ b/usbtuner/res/values-et-rEE/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB-kanalituuneri seadistus"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"See võib võtta mitu minutit"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Leiti %1$d kanal"</item>
- <item quantity="other" msgid="7340557317633613">"Leiti %1$d kanalit"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Leiti %1$d kanalit</item>
+ <item quantity="one">Leiti %1$d kanal</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"PEATA KANALITE OTSIMINE"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Leiti %1$d kanal"</item>
- <item quantity="other" msgid="4331542666115153576">"Leiti %1$d kanalit"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Suurepärane! Kanalite otsimisel leiti %1$d kanal. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti."</item>
- <item quantity="other" msgid="8098777464551209564">"Suurepärane! Kanalite otsimisel leiti %1$d kanalit. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Valmis"</item>
<item msgid="496688122303154468">"Otsi uuesti"</item>
diff --git a/usbtuner/res/values-eu-rES/strings.xml b/usbtuner/res/values-eu-rES/strings.xml
index b7dfc59b..4f81259e 100644
--- a/usbtuner/res/values-eu-rES/strings.xml
+++ b/usbtuner/res/values-eu-rES/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB kanal-sintonizadorearen konfigurazioa"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Zenbait minutu beharko dira"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanal aurkitu da"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanal aurkitu dira"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <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="8358794117343664624">"UTZI KANALAK BILATZEARI"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanal aurkitu da"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanal aurkitu dira"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Primeran! %1$d kanal aurkitu da kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro."</item>
- <item quantity="other" msgid="8098777464551209564">"Primeran! %1$d kanal aurkitu dira kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Eginda"</item>
<item msgid="496688122303154468">"Bilatu berriro"</item>
diff --git a/usbtuner/res/values-fa/strings.xml b/usbtuner/res/values-fa/strings.xml
index 61078a30..899e4f67 100644
--- a/usbtuner/res/values-fa/strings.xml
+++ b/usbtuner/res/values-fa/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"‏نصب تنظیم‌کننده کانال USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ممکن است چند دقیقه طول بکشد"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"‏%1$d کانال پیدا شد"</item>
- <item quantity="other" msgid="7340557317633613">"‏%1$d کانال پیدا شد"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">‏%1$d کانال پیدا شد</item>
+ <item quantity="other">‏%1$d کانال پیدا شد</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"توقف اسکن کانال"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"‏%1$d کانال پیدا شد"</item>
- <item quantity="other" msgid="4331542666115153576">"‏%1$d کانال پیدا شد"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"‏عالی است! در طول اسکن کانال، %1$d کانال پیدا شد. اگر این تعداد درست به نظر نمی‌رسد، موقعیت آنتن را تنظیم کنید و دوباره اسکن کنید."</item>
- <item quantity="other" msgid="8098777464551209564">"‏عالی است! در طول اسکن کانال، %1$d کانال پیدا شد. اگر این تعداد درست به نظر نمی‌رسد، موقعیت آنتن را تنظیم کنید و دوباره اسکن کنید."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">‏%1$d کانال پیدا شد</item>
+ <item quantity="other">‏%1$d کانال پیدا شد</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">‏خوب است! در طول اسکن کانال %1$d کانال پیدا شد. اگر این تعداد درست به نظر نمی‌رسد، موقعیت آنتن را تنظیم کنید و دوباره اسکن کنید.</item>
+ <item quantity="other">‏خوب است! در طول اسکن کانال %1$d کانال پیدا شد. اگر این تعداد درست به نظر نمی‌رسد، موقعیت آنتن را تنظیم کنید و دوباره اسکن کنید.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"تمام"</item>
<item msgid="496688122303154468">"اسکن دوباره"</item>
diff --git a/usbtuner/res/values-fi/strings.xml b/usbtuner/res/values-fi/strings.xml
index f72c0ed1..35be3248 100644
--- a/usbtuner/res/values-fi/strings.xml
+++ b/usbtuner/res/values-fi/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB-kanavavirittimen määritys"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Tämä voi kestää useita minuutteja."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanava löytyi."</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanavaa löytyi."</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanavaa löytyi</item>
+ <item quantity="one">%1$d kanava löytyi</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"LOPETA KANAVAHAKU"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanava löytyi"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanavaa löytyi"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Hienoa! Kanavahaun aikana löytyi %1$d kanava. Jos tämä tulos ei vaikuta oikealta, säädä antennia ja tee haku uudelleen."</item>
- <item quantity="other" msgid="8098777464551209564">"Hienoa! Kanavahaun aikana löytyi %1$d kanavaa. Jos tämä tulos ei vaikuta oikealta, säädä antennia ja tee haku uudelleen."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanavaa löytyi</item>
+ <item quantity="one">%1$d kanava löytyi</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Hienoa! Kanavahaussa löytyi %1$d kanavaa. Jos tämä tulos ei vaikuta oikealta, säädä antennin asentoa ja tee haku uudelleen.</item>
+ <item quantity="one">Hienoa! Kanavahaussa löytyi %1$d kanava. Jos tämä tulos ei vaikuta oikealta, säädä antennin asentoa ja tee haku uudelleen.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Valmis"</item>
<item msgid="496688122303154468">"Hae uudelleen"</item>
diff --git a/usbtuner/res/values-fr-rCA/strings.xml b/usbtuner/res/values-fr-rCA/strings.xml
index 526ef9e9..557aee53 100644
--- a/usbtuner/res/values-fr-rCA/strings.xml
+++ b/usbtuner/res/values-fr-rCA/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configurer les chaînes du syntoniseur USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Cela peut prendre plusieurs minutes"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d chaîne détectée"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d chaînes détectées"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d chaîne détectée</item>
+ <item quantity="other">%1$d chaînes détectées</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ARRÊTER LA RECHERCHE DE CHAÎNES"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d chaîne détectée"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d chaînes détectées"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bravo! %1$d chaîne a été détectée pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche."</item>
- <item quantity="other" msgid="8098777464551209564">"Bravo! %1$d chaînes ont été détectées pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d chaîne détectée</item>
+ <item quantity="other">%1$d chaînes détectées</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Excellent! %1$d chaîne a été détectée pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche.</item>
+ <item quantity="other">Excellent! %1$d chaînes ont été détectées pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Terminé"</item>
<item msgid="496688122303154468">"Rechercher à nouveau"</item>
diff --git a/usbtuner/res/values-fr/strings.xml b/usbtuner/res/values-fr/strings.xml
index 8a2a08b3..8227dd84 100644
--- a/usbtuner/res/values-fr/strings.xml
+++ b/usbtuner/res/values-fr/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuration du tuner de chaînes USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Cette opération peut prendre plusieurs minutes."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d chaîne détectée"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d chaînes détectées"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d chaîne a été détectée.</item>
+ <item quantity="other">%1$d chaînes ont été détectées.</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ARRÊTER LA RECHERCHE DE CHAÎNES"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d chaîne détectée"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d chaînes détectées"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bravo ! %1$d chaîne a été détectée pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche."</item>
- <item quantity="other" msgid="8098777464551209564">"Bravo ! %1$d chaînes ont été détectées pendant la recherche de chaînes. Si cela vous semble incorrect, essayez d\'ajuster la position de l\'antenne et d\'effectuer une nouvelle recherche."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d chaîne détectée</item>
+ <item quantity="other">%1$d chaînes détectées</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Bravo ! %1$d chaîne a été détectée pendant la recherche de chaînes. Si cela vous semble incorrect, veuillez ajuster la position de l\'antenne et effectuez une nouvelle recherche.</item>
+ <item quantity="other">Bravo ! %1$d chaînes ont été détectées pendant la recherche de chaînes. Si cela vous semble incorrect, veuillez ajuster la position de l\'antenne et effectuez une nouvelle recherche.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"OK"</item>
<item msgid="496688122303154468">"Rechercher à nouveau"</item>
diff --git a/usbtuner/res/values-gl-rES/strings.xml b/usbtuner/res/values-gl-rES/strings.xml
index 4ee5c6a9..89e2e827 100644
--- a/usbtuner/res/values-gl-rES/strings.xml
+++ b/usbtuner/res/values-gl-rES/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuración do sintonizador de canles USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Esta acción pode tardar varios minutos"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Atopouse %1$d canle"</item>
- <item quantity="other" msgid="7340557317633613">"Atopáronse %1$d canles"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <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="8358794117343664624">"DETER BUSCA DE CANLES"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Atopouse %1$d canle"</item>
- <item quantity="other" msgid="4331542666115153576">"Atopáronse %1$d canles"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"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>
- <item quantity="other" msgid="8098777464551209564">"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>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Feito"</item>
<item msgid="496688122303154468">"Buscar de novo"</item>
diff --git a/usbtuner/res/values-hi/strings.xml b/usbtuner/res/values-hi/strings.xml
index 66db026b..6118629e 100644
--- a/usbtuner/res/values-hi/strings.xml
+++ b/usbtuner/res/values-hi/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB चैनल ट्यूनर सेटअप"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"इसमें कई मिनट लग सकते हैं"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d चैनल मिला"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d चैनल मिले"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d चैनल मिले</item>
+ <item quantity="other">%1$d चैनल मिले</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"चैनल स्कैन रोकें"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d चैनल मिला"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d चैनल मिले"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"बढ़िया! चैनल स्‍कैन के दौरान %1$d चैनल मिला था. यदि यह सही नहीं लग रहा है, तो एंटेना की स्‍थिति एडजस्‍ट करके देखें और पुन: स्‍कैन करें."</item>
- <item quantity="other" msgid="8098777464551209564">"बढ़िया! चैनल स्कैन के दौरान %1$d चैनल मिले थे. यदि यह सही नहीं लग रहा है, तो एंटेना की स्थिति एडजस्ट करके देखें और पुनः स्कैन करें."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d चैनल मिले</item>
+ <item quantity="other">%1$d चैनल मिले</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">बढ़िया! चैनल स्कैन करने के दौरान %1$d चैनल मिले. यदि यह सही नहीं लग रहा है, तो एंटेना की स्थिति एडजस्ट करके देखें और पुनः स्कैन करें.</item>
+ <item quantity="other">बढ़िया! चैनल स्कैन करने के दौरान %1$d चैनल मिले. यदि यह सही नहीं लग रहा है, तो एंटेना की स्थिति एडजस्ट करके देखें और पुनः स्कैन करें.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"हो गया"</item>
<item msgid="496688122303154468">"पुन: स्‍कैन करें"</item>
diff --git a/usbtuner/res/values-hr/strings.xml b/usbtuner/res/values-hr/strings.xml
index 39c5f2b1..ff7f68b2 100644
--- a/usbtuner/res/values-hr/strings.xml
+++ b/usbtuner/res/values-hr/strings.xml
@@ -50,19 +50,22 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Postavljanje USB prijamnika za kanale"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"To može potrajati nekoliko minuta"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Pronađen je %1$d kanal"</item>
- <item quantity="other" msgid="7340557317633613">"Broj pronađenih kanala: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Pronađen je %1$d kanal</item>
+ <item quantity="few">Pronađena su %1$d kanala</item>
+ <item quantity="other">Pronađeno je %1$d kanala</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ZAUSTAVI PRETRAŽIVANJE KANALA"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Pronađen je %1$d kanal"</item>
- <item quantity="other" msgid="4331542666115153576">"Broj pronađenih kanala: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Odlično! Tijekom pretraživanja kanala pronađen je %1$d kanal. Ako mislite da to nije u redu, promijenite položaj antene i pretražite ponovo."</item>
- <item quantity="other" msgid="8098777464551209564">"Odlično! Tijekom pretraživanja pronađen je sljedeći broj kanala: %1$d. Ako mislite da to nije u redu, promijenite položaj antene i pretražite ponovo."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Pronađen je %1$d kanal</item>
+ <item quantity="few">Pronađena su %1$d kanala</item>
+ <item quantity="other">Pronađeno je %1$d kanala</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Lijepo! Tijekom pretraživanja kanala pronađen je %1$d kanal. Ako mislite da to nije u redu, promijenite položaj antene i pretražite ponovo.</item>
+ <item quantity="few">Lijepo! Tijekom pretraživanja kanala pronađena su %1$d kanala. Ako mislite da to nije u redu, promijenite položaj antene i pretražite ponovo.</item>
+ <item quantity="other">Lijepo! Tijekom pretraživanja kanala pronađeno je %1$d kanala. Ako mislite da to nije u redu, promijenite položaj antene i pretražite ponovo.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Gotovo"</item>
<item msgid="496688122303154468">"Pretraži ponovo"</item>
diff --git a/usbtuner/res/values-hu/strings.xml b/usbtuner/res/values-hu/strings.xml
index 95e70e23..860ea368 100644
--- a/usbtuner/res/values-hu/strings.xml
+++ b/usbtuner/res/values-hu/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB-csatorna tunerbeállítása"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Ez néhány percet is igénybe vehet"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d csatorna észlelve"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d csatorna észlelve"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d csatorna észlelve</item>
+ <item quantity="one">%1$d csatorna észlelve</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"CSATORNAKERESÉS LEÁLLÍTÁSA"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d csatorna észlelve"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d csatorna észlelve"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Ügyes! A rendszer %1$d csatornát talált a keresés során. Ha ez nem tűnik megfelelőnek, állítson az antenna helyzetén, majd végezze el újra a keresést."</item>
- <item quantity="other" msgid="8098777464551209564">"Ügyes! A rendszer %1$d csatornát talált a csatornakeresés során. Ha ez nem tűnik megfelelőnek, állítson az antenna helyzetén, majd végezze el újra a keresést."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d csatorna észlelve</item>
+ <item quantity="one">%1$d csatorna észlelve</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Remek! A rendszer %1$d csatornát talált a keresés során. Ha ez nem tűnik megfelelőnek, állítson az antenna helyzetén, majd végezze el újra a keresést.</item>
+ <item quantity="one">Remek! A rendszer %1$d csatornát talált a keresés során. Ha ez nem tűnik megfelelőnek, állítson az antenna helyzetén, majd végezze el újra a keresést.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Kész"</item>
<item msgid="496688122303154468">"Keresés újra"</item>
diff --git a/usbtuner/res/values-hy-rAM/strings.xml b/usbtuner/res/values-hy-rAM/strings.xml
index 04976380..cde49c93 100644
--- a/usbtuner/res/values-hy-rAM/strings.xml
+++ b/usbtuner/res/values-hy-rAM/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Ալիքների USB կարգավորիչի տեղադրում"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Դա կարող է տևել մի քանի րոպե"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ալիք է գտնվել"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ալիք է գտնվել"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Գտնվել է %1$d ալիք</item>
+ <item quantity="other">Գտնվել է %1$d ալիք</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ԴԱԴԱՐԵՑՆԵԼ ԱԼԻՔՆԵՐԻ ՈՐՈՆՈՒՄԸ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ալիք է գտնվել"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ալիք է գտնվել"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Ալիքների որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:"</item>
- <item quantity="other" msgid="8098777464551209564">"Որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Գտնվել է %1$d ալիք</item>
+ <item quantity="other">Գտնվել է %1$d ալիք</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Գերազանց է: Ալիքների որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:</item>
+ <item quantity="other">Գերազանց է: Ալիքների որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Պատրաստ է"</item>
<item msgid="496688122303154468">"Կրկին որոնել"</item>
diff --git a/usbtuner/res/values-in/strings.xml b/usbtuner/res/values-in/strings.xml
index f6baa6e2..b14710dd 100644
--- a/usbtuner/res/values-in/strings.xml
+++ b/usbtuner/res/values-in/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Penyiapan tuner saluran USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Proses ini dapat memakan waktu beberapa menit"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d saluran ditemukan"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d saluran ditemukan"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d saluran ditemukan</item>
+ <item quantity="one">%1$d saluran ditemukan</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"HENTIKAN PEMINDAIAN SALURAN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d saluran ditemukan"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d saluran ditemukan"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bagus! %1$d saluran ditemukan saat pemindaian saluran. Jika ada yang tidak beres, coba sesuaikan posisi antena dan pindai lagi."</item>
- <item quantity="other" msgid="8098777464551209564">"Bagus! %1$d saluran ditemukan saat pemindaian saluran. Jika ada yang tidak beres, cobalah sesuaikan posisi antena dan pindai lagi."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d saluran ditemukan</item>
+ <item quantity="one">%1$d saluran ditemukan</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Bagus! %1$d saluran ditemukan selama pemindaian saluran. Jika ada yang tidak beres, cobalah menyesuaikan posisi antena dan pindai lagi.</item>
+ <item quantity="one">Bagus! %1$d saluran ditemukan selama pemindaian saluran. Jika ada yang tidak beres, cobalah menyesuaikan posisi antena dan pindai lagi.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Selesai"</item>
<item msgid="496688122303154468">"Pindai lagi"</item>
diff --git a/usbtuner/res/values-is-rIS/strings.xml b/usbtuner/res/values-is-rIS/strings.xml
index ba7edc0b..5bdb9e71 100644
--- a/usbtuner/res/values-is-rIS/strings.xml
+++ b/usbtuner/res/values-is-rIS/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Uppsetning USB-sjónvarpsrásakorts"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Þetta getur tekið nokkrar mínútur"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d rás fannst"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d rásir fundust"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <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="8358794117343664624">"STÖÐVA RÁSALEIT"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d rás fannst"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d rásir fundust"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Flott! %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" msgid="8098777464551209564">"Flott! %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>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Lokið"</item>
<item msgid="496688122303154468">"Leita aftur"</item>
diff --git a/usbtuner/res/values-it/strings.xml b/usbtuner/res/values-it/strings.xml
index 7b3a59e3..3c4f7e46 100644
--- a/usbtuner/res/values-it/strings.xml
+++ b/usbtuner/res/values-it/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configurazione del sintonizzatore di canali USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"L\'operazione potrebbe richiedere alcuni minuti"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d canale trovato"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d canali trovati"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d canali trovati</item>
+ <item quantity="one">%1$d canale trovato</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"INTERROMPI RICERCA CANALI"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d canale trovato"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d canali trovati"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bene! È stato trovato %1$d canale durante la ricerca dei canali. Se non è corretto, prova a regolare la posizione dell\'antenna ed esegui nuovamente la ricerca."</item>
- <item quantity="other" msgid="8098777464551209564">"Bene! Sono stati trovati %1$d canali durante la ricerca dei canali. Se non è corretto, prova a regolare la posizione dell\'antenna ed esegui nuovamente la ricerca."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d canali trovati</item>
+ <item quantity="one">%1$d canale trovato</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Bene! Sono stati trovati %1$d canali durante la ricerca dei canali. Se non è corretto, prova a regolare la posizione dell\'antenna ed esegui nuovamente la ricerca.</item>
+ <item quantity="one">Bene! È stato trovato %1$d canale durante la ricerca dei canali. Se non è corretto, prova a regolare la posizione dell\'antenna ed esegui nuovamente la ricerca.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Fine"</item>
<item msgid="496688122303154468">"Cerca di nuovo"</item>
diff --git a/usbtuner/res/values-iw/strings.xml b/usbtuner/res/values-iw/strings.xml
index f39bbe99..8e006448 100644
--- a/usbtuner/res/values-iw/strings.xml
+++ b/usbtuner/res/values-iw/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"‏הגדרת טיונר ערוצים בחיבור USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"פעולה זו עשויה להימשך מספר דקות"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"נמצא ערוץ אחד"</item>
- <item quantity="other" msgid="7340557317633613">"‏נמצאו %1$d ערוצים"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="two">‏נמצאו %1$d ערוצים</item>
+ <item quantity="many">‏נמצאו %1$d ערוצים</item>
+ <item quantity="other">‏נמצאו %1$d ערוצים</item>
+ <item quantity="one">נמצא ערוץ אחד</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"הפסק סריקת ערוצים"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"נמצא ערוץ אחד"</item>
- <item quantity="other" msgid="4331542666115153576">"‏נמצאו %1$d ערוצים"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"יופי! נמצא ערוץ אחד במהלך סריקת הערוצים. אם הדבר נראה שגוי, נסה לכוונן את מיקום האנטנה ולסרוק שוב."</item>
- <item quantity="other" msgid="8098777464551209564">"‏יופי! נמצאו %1$d ערוצים במהלך סריקת הערוצים. אם הדבר נראה שגוי, נסה לכוונן את מיקום האנטנה ולסרוק שוב."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="two">‏נמצאו %1$d ערוצים</item>
+ <item quantity="many">‏נמצאו %1$d ערוצים</item>
+ <item quantity="other">‏נמצאו %1$d ערוצים</item>
+ <item quantity="one">נמצא ערוץ אחד</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="two">‏לא רע! במהלך סריקה הערוצים, נמצאו %1$d ערוצים. אם הקליטה לא תקינה, נסה לכוונן את מיקום האנטנה ובצע סריקה נוספת.</item>
+ <item quantity="many">‏לא רע! במהלך סריקה הערוצים, נמצאו %1$d ערוצים. אם הקליטה לא תקינה, נסה לכוונן את מיקום האנטנה ובצע סריקה נוספת.</item>
+ <item quantity="other">‏לא רע! במהלך סריקה הערוצים, נמצאו %1$d ערוצים. אם הקליטה לא תקינה, נסה לכוונן את מיקום האנטנה ובצע סריקה נוספת.</item>
+ <item quantity="one">לא רע! במהלך סריקת הערוצים נמצא ערוץ אחד. אם הקליטה לא תקינה, נסה לכוונן את מיקום האנטנה ובצע סריקה נוספת.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"בוצע"</item>
<item msgid="496688122303154468">"סרוק שוב"</item>
diff --git a/usbtuner/res/values-ja/strings.xml b/usbtuner/res/values-ja/strings.xml
index 87ec19fb..61a3d7ff 100644
--- a/usbtuner/res/values-ja/strings.xml
+++ b/usbtuner/res/values-ja/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB チャンネル チューナーのセットアップ"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"この処理には数分かかることがあります"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d 件のチャンネルが見つかりました"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d 件のチャンネルが見つかりました"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d 件のチャンネルが見つかりました</item>
+ <item quantity="one">%1$d 件のチャンネルが見つかりました</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"チャンネルのスキャンを停止"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d 件のチャンネルが見つかりました"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d 件のチャンネルが見つかりました"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"チャンネルのスキャン中に %1$d 件のチャンネルが見つかりました。この件数が正しくないと思われる場合は、アンテナの位置を調整してもう一度スキャンしてください。"</item>
- <item quantity="other" msgid="8098777464551209564">"チャンネルのスキャン中に %1$d 件のチャンネルが見つかりました。この件数が正しくないと思われる場合は、アンテナの位置を調整してもう一度スキャンしてください。"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d 件のチャンネルが見つかりました</item>
+ <item quantity="one">%1$d 件のチャンネルが見つかりました</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">チャンネルのスキャン中に %1$d 件のチャンネルが見つかりました。この件数が正しくないと思われる場合は、アンテナの位置を調整してもう一度スキャンしてください。</item>
+ <item quantity="one">チャンネルのスキャン中に %1$d 件のチャンネルが見つかりました。この件数が正しくないと思われる場合は、アンテナの位置を調整してもう一度スキャンしてください。</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"完了"</item>
<item msgid="496688122303154468">"再スキャン"</item>
diff --git a/usbtuner/res/values-ka-rGE/strings.xml b/usbtuner/res/values-ka-rGE/strings.xml
index 1464fe7e..cfb7f34f 100644
--- a/usbtuner/res/values-ka-rGE/strings.xml
+++ b/usbtuner/res/values-ka-rGE/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"არხების USB ტუნერის დაყენება"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ამას შეიძლება რამდენიმე წუთი დასჭირდეს"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"მოიძებნა %1$d არხი"</item>
- <item quantity="other" msgid="7340557317633613">"მოიძებნა %1$d არხი"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">მოიძებნა %1$d არხი</item>
+ <item quantity="one">მოიძებნა %1$d არხი</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"არხების სკანირების შეწყვეტა"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"მოიძებნა %1$d არხი"</item>
- <item quantity="other" msgid="4331542666115153576">"მოიძებნა %1$d არხი"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"ძალიან კარგი! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ."</item>
- <item quantity="other" msgid="8098777464551209564">"ძალიან კარგი! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">მოიძებნა %1$d არხი</item>
+ <item quantity="one">მოიძებნა %1$d არხი</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
+ <item quantity="one">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"მზადაა"</item>
<item msgid="496688122303154468">"ხელახლა სკანირება"</item>
diff --git a/usbtuner/res/values-kk-rKZ/strings.xml b/usbtuner/res/values-kk-rKZ/strings.xml
index f7ec968b..19dbdf7f 100644
--- a/usbtuner/res/values-kk-rKZ/strings.xml
+++ b/usbtuner/res/values-kk-rKZ/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB арна тюнерін орнату"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Бұл бірнеше минутты алуы мүмкін"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d арна табылды"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d арна табылды"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d арна табылды</item>
+ <item quantity="one">%1$d арна табылды</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"АРНА ІЗДЕУДІ ТОҚТАТУ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d арна табылды"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d арна табылды"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз."</item>
- <item quantity="other" msgid="8098777464551209564">"Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d арна табылды</item>
+ <item quantity="one">%1$d арна табылды</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
+ <item quantity="one">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Орындалды"</item>
<item msgid="496688122303154468">"Қайта іздеу"</item>
diff --git a/usbtuner/res/values-km-rKH/strings.xml b/usbtuner/res/values-km-rKH/strings.xml
index c757d2f6..ee8062f1 100644
--- a/usbtuner/res/values-km-rKH/strings.xml
+++ b/usbtuner/res/values-km-rKH/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"ការដំឡើងឧបករណ៍ចាប់ប៉ុស្តិ៍ USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"វាអាចចំណាយពេលច្រើននាទី"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"រកឃើញប៉ុស្តិ៍ %1$d"</item>
- <item quantity="other" msgid="7340557317633613">"រកឃើញប៉ុស្តិ៍ %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"បញ្ឈប់ការស្កេនរកប៉ុស្តិ៍"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"រកឃើញប៉ុស្តិ៍ %1$d"</item>
- <item quantity="other" msgid="4331542666115153576">"រកឃើញប៉ុស្តិ៍ %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"ល្អ! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេនរកប៉ុស្តិ៍។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។"</item>
- <item quantity="other" msgid="8098777464551209564">"ល្អ! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេនរកប៉ុស្តិ៍។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
+ <item quantity="one">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"រួចរាល់"</item>
<item msgid="496688122303154468">"ស្កេនម្តងទៀត"</item>
diff --git a/usbtuner/res/values-kn-rIN/strings.xml b/usbtuner/res/values-kn-rIN/strings.xml
index 8efc955f..9de7810b 100644
--- a/usbtuner/res/values-kn-rIN/strings.xml
+++ b/usbtuner/res/values-kn-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ಇದಕ್ಕೆ ಹಲವಾರು ನಿಮಿಷಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ಚಾನಲ್ ಪತ್ತೆಯಾಗಿವೆ"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ಚಾನಲ್‌ಗಳು ಪತ್ತೆಯಾಗಿವೆ"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಮಾಡುವುದನ್ನು ನಿಲ್ಲಿಸು"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ಚಾನಲ್ ಪತ್ತೆಯಾಗಿವೆ"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ಚಾನಲ್‌ಗಳು ಪತ್ತೆಯಾಗಿವೆ"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್ ಪತ್ತೆಯಾಗಿದೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</item>
- <item quantity="other" msgid="8098777464551209564">"ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಪತ್ತೆಯಾಗಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಾನವನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
+ <item quantity="other">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"ಮುಗಿದಿದೆ"</item>
<item msgid="496688122303154468">"ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡು"</item>
diff --git a/usbtuner/res/values-ko/strings.xml b/usbtuner/res/values-ko/strings.xml
index bcd61162..eb213561 100644
--- a/usbtuner/res/values-ko/strings.xml
+++ b/usbtuner/res/values-ko/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB 채널 튜너 설정"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"이 작업은 몇 분 정도 걸릴 수 있습니다."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d개 채널 발견"</item>
- <item quantity="other" msgid="7340557317633613">"채널 %1$d개 발견"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">채널 %1$d개 발견</item>
+ <item quantity="one">채널 %1$d개 발견</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"채널 스캔 중지"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d개 채널 발견"</item>
- <item quantity="other" msgid="4331542666115153576">"채널 %1$d개 발견"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"채널을 스캔하는 동안 채널 %1$d개를 발견했습니다. 맞지 않는 것 같다면 안테나 위치를 조정한 후 다시 스캔하세요."</item>
- <item quantity="other" msgid="8098777464551209564">"채널을 스캔하는 동안 채널 %1$d개를 발견했습니다. 맞지 않는 것 같다면 안테나 위치를 조정한 후 다시 스캔하세요."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">채널 %1$d개 발견</item>
+ <item quantity="one">채널 %1$d개 발견</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">좋습니다. 채널 스캔 중에 채널 %1$d개를 발견했습니다. 맞지 않는 것 같다면 안테나 위치를 조정한 후 다시 스캔하세요.</item>
+ <item quantity="one">좋습니다. 채널 스캔 중에 채널 %1$d개를 발견했습니다. 맞지 않는 것 같다면 안테나 위치를 조정한 후 다시 스캔하세요.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"완료"</item>
<item msgid="496688122303154468">"다시 스캔"</item>
diff --git a/usbtuner/res/values-ky-rKG/strings.xml b/usbtuner/res/values-ky-rKG/strings.xml
index 0838bf19..85c84be4 100644
--- a/usbtuner/res/values-ky-rKG/strings.xml
+++ b/usbtuner/res/values-ky-rKG/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB канал тюнер жөндөөсү"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Бир нече мүнөт созулушу мүмкүн"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d канал табылды"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d канал табылды"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d канал табылды</item>
+ <item quantity="one">%1$d канал табылды</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"КАНАЛ ИЗДӨӨНҮ ТОКТОТУУ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d канал табылды"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d канал табылды"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Эң жакшы! Канал издөө учурунда %1$d канал табылды. Ал туура эмес болсо, антеннанын багытын өзгөртүп, кайра издеп көрүңүз."</item>
- <item quantity="other" msgid="8098777464551209564">"Эң жакшы! Канал издөө учурунда %1$d канал табылды. Ал туура эмес болсо, антеннанын багытын өзгөртүп, кайра издеп көрүңүз."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d канал табылды</item>
+ <item quantity="one">%1$d канал табылды</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Сонун! Канал издөө учурунда %1$d канал табылды. Ал туура эмес болсо, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
+ <item quantity="one">Сонун! Канал издөө учурунда %1$d канал табылды. Ал туура эмес болсо, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Бүттү"</item>
<item msgid="496688122303154468">"Кайра издөө"</item>
diff --git a/usbtuner/res/values-lo-rLA/strings.xml b/usbtuner/res/values-lo-rLA/strings.xml
index 5ac54236..8b85bf42 100644
--- a/usbtuner/res/values-lo-rLA/strings.xml
+++ b/usbtuner/res/values-lo-rLA/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"ການ​ຕັ້ງ​ເຄື່ອງຮັບສັນຍານ​ຊ່ອງ USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ອັນ​ນີ້​ອາດ​ຈະ​ໃຊ້​ເວ​ລາ​ຫຼາຍ​ນາ​ທີ"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"ພົບເຫັນ %1$d ຊ່ອງ"</item>
- <item quantity="other" msgid="7340557317633613">"ພົບເຫັນ %1$d ຊ່ອງ"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
+ <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ຢຸດ​ການ​ສະ​ແກນ​ຊ່ອງ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"ພົບເຫັນ %1$d ຊ່ອງ"</item>
- <item quantity="other" msgid="4331542666115153576">"ພົບເຫັນ %1$d ຊ່ອງ"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"ດີ​ຫຼາຍ! ພົບ​ %1$d ຊ່ອງ​ໃນ​ລະ​ຫວ່າງ​ການ​ສະ​ແກນ​ຫາ​ຊ່ອງ. ຖ້າ​​ເຫັນ​ວ່າ ອັນ​ນີ້​ບໍ່​ຖືກ​ຕ້ອງ, ລອງ​ປັບ​ຕ​ຳ​ແໜ່ງ​ເສົາອາກາດ ແລະ ສະ​ແກນ​ອີກ."</item>
- <item quantity="other" msgid="8098777464551209564">"ດີ​ຫຼາຍ! ພົບ %1$d ຊ່ອງ​ໃນ​ລະ​ຫວ່າງ​ການ​ສະ​ແກນ​ຫາ​ຊ່ອງ. ຖ້າ​ເຫັນ​ວ່າ ອັນ​ນີ້​ບໍ່​ຖືກ​ຕ້ອງ, ລອງ​ປັບ​ຕ​ຳ​ແໜ່ງ​ເສົາອາກາດ ແລະ ສະ​ແກນ​ອີກ."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
+ <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
+ <item quantity="one">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"ສຳເລັດແລ້ວ"</item>
<item msgid="496688122303154468">"ສະແກນອີກ"</item>
diff --git a/usbtuner/res/values-lt/strings.xml b/usbtuner/res/values-lt/strings.xml
index c97e0849..33ddddf3 100644
--- a/usbtuner/res/values-lt/strings.xml
+++ b/usbtuner/res/values-lt/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB kanalų imtuvo sąranka"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Tai gali užtrukti kelias minutes"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Surasta kanalų: %1$d"</item>
- <item quantity="other" msgid="7340557317633613">"Surasta kanalų: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Rastas %1$d kanalas</item>
+ <item quantity="few">Rasti %1$d kanalai</item>
+ <item quantity="many">Rasta %1$d kanalo</item>
+ <item quantity="other">Rasta %1$d kanalų</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"SUSTABDYTI KANALŲ NUSKAITYMĄ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Surasta kanalų: %1$d"</item>
- <item quantity="other" msgid="4331542666115153576">"Surasta kanalų: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Puiku! Atlikę kanalų nuskaitymą radome %1$d kanal. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą."</item>
- <item quantity="other" msgid="8098777464551209564">"Puiku! Atlikę kanalų nuskaitymą radome %1$d kanal. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Rastas %1$d kanalas</item>
+ <item quantity="few">Rasti %1$d kanalai</item>
+ <item quantity="many">Rasta %1$d kanalo</item>
+ <item quantity="other">Rasta %1$d kanalų</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Puiku! Nuskaitant kanalus rastas %1$d kanalas. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą.</item>
+ <item quantity="few">Puiku! Nuskaitant kanalus rasti %1$d kanalai. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą.</item>
+ <item quantity="many">Puiku! Nuskaitant kanalus rasta %1$d kanalo. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą.</item>
+ <item quantity="other">Puiku! Nuskaitant kanalus rasta %1$d kanalų. Jei tai neatrodo tinkamas rezultatas, pabandykite pakoreguoti antenos padėtį ir nuskaityti dar kartą.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Atlikta"</item>
<item msgid="496688122303154468">"Nuskaityti dar kartą"</item>
diff --git a/usbtuner/res/values-lv/strings.xml b/usbtuner/res/values-lv/strings.xml
index 606a558b..38d806ac 100644
--- a/usbtuner/res/values-lv/strings.xml
+++ b/usbtuner/res/values-lv/strings.xml
@@ -50,19 +50,22 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB kanālu meklētāja iestatīšana"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Tas var ilgt vairākas minūtes."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Tika atrasts %1$d kanāls."</item>
- <item quantity="other" msgid="7340557317633613">"Tika atrasti %1$d kanāli."</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="zero">Tika atrasti %1$d kanāli.</item>
+ <item quantity="one">Tika atrasts %1$d kanāls.</item>
+ <item quantity="other">Tika atrasti %1$d kanāli.</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"APTURĒT KANĀLU MEKLĒŠANU"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Atrasts %1$d kanāls"</item>
- <item quantity="other" msgid="4331542666115153576">"Atrasti %1$d kanāli"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Lieliski! Tika atrasts %1$d kanāls. Ja jums šķiet, ka kaut kas nav pareizi, noregulējiet antenu un mēģiniet vēlreiz."</item>
- <item quantity="other" msgid="8098777464551209564">"Lieliski! Tika atrasti %1$d kanāli. Ja jums šķiet, ka kaut kas nav pareizi, noregulējiet antenu un mēģiniet vēlreiz."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="zero">Atrasti %1$d kanāli</item>
+ <item quantity="one">Atrasts %1$d kanāls</item>
+ <item quantity="other">Atrasti %1$d kanāli</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="zero">Lieliski! Tika atrasti %1$d kanāli. Ja jums šķiet, ka kaut kas nav pareizi, noregulējiet antenu un meklējiet kanālus vēlreiz.</item>
+ <item quantity="one">Lieliski! Tika atrasts %1$d kanāls. Ja jums šķiet, ka kaut kas nav pareizi, noregulējiet antenu un meklējiet kanālus vēlreiz.</item>
+ <item quantity="other">Lieliski! Tika atrasti %1$d kanāli. Ja jums šķiet, ka kaut kas nav pareizi, noregulējiet antenu un meklējiet kanālus vēlreiz.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Gatavs"</item>
<item msgid="496688122303154468">"Meklēt vēlreiz"</item>
diff --git a/usbtuner/res/values-mk-rMK/strings.xml b/usbtuner/res/values-mk-rMK/strings.xml
index 98da5004..5c4b0f1f 100644
--- a/usbtuner/res/values-mk-rMK/strings.xml
+++ b/usbtuner/res/values-mk-rMK/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Поставување на УСБ-приемникот за канали"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Ова може да трае неколку минути"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Пронајден е %1$d канал"</item>
- <item quantity="other" msgid="7340557317633613">"Пронајдени се %1$d канали"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Пронајден е %1$d канал</item>
+ <item quantity="other">Пронајдени се %1$d канали</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"СОПРИ ГО СКЕНИРАЊЕТО КАНАЛИ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Пронајден е %1$d канал"</item>
- <item quantity="other" msgid="4331542666115153576">"Пронајдени се %1$d канали"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Одлично! Се пронајде %1$d канал во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на антената и скенирајте повторно."</item>
- <item quantity="other" msgid="8098777464551209564">"Одлично! Се пронајдоа %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на антената и скенирајте повторно."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Пронајден е %1$d канал</item>
+ <item quantity="other">Пронајдени се %1$d канали</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Фино! Пронајден е %1$d канал во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
+ <item quantity="other">Фино! Пронајдени се %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Готово"</item>
<item msgid="496688122303154468">"Скенирај пак"</item>
diff --git a/usbtuner/res/values-ml-rIN/strings.xml b/usbtuner/res/values-ml-rIN/strings.xml
index e9f07b8d..5fa3e638 100644
--- a/usbtuner/res/values-ml-rIN/strings.xml
+++ b/usbtuner/res/values-ml-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"ഇതിന് കുറച്ച് സമയം എടുത്തേക്കാം"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ചാനൽ കണ്ടെത്തി"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ചാനലുകൾ കണ്ടെത്തി"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
+ <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ചാനൽ സ്കാൻ ചെയ്യുന്നത് നിർത്തുക"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ചാനൽ കണ്ടെത്തി"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ചാനലുകൾ കണ്ടെത്തി"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"തകർപ്പൻ! ചാനൽ സ്കാൻ ചെയ്തപ്പോൾ %1$d ചാനൽ കണ്ടെത്തി. ഇതിലെന്തെങ്കിലും പൊരുത്തക്കേട് തോന്നുന്നുവെങ്കിൽ, ആന്റിന പൊസിഷൻ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക."</item>
- <item quantity="other" msgid="8098777464551209564">"തകർപ്പൻ! ചാനൽ സ്കാൻ ചെയ്തപ്പോൾ %1$d ചാനലുകൾ കണ്ടെത്തി. ഇതിലെന്തെങ്കിലും പൊരുത്തക്കേട് തോന്നുന്നുവെങ്കിൽ, ആന്റിന പൊസിഷൻ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
+ <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനലുകൾ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
+ <item quantity="one">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനൽ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"പൂർത്തിയായി"</item>
<item msgid="496688122303154468">"വീണ്ടും സ്കാൻ ചെയ്യുക"</item>
diff --git a/usbtuner/res/values-mn-rMN/strings.xml b/usbtuner/res/values-mn-rMN/strings.xml
index b3912917..0940b9d4 100644
--- a/usbtuner/res/values-mn-rMN/strings.xml
+++ b/usbtuner/res/values-mn-rMN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB суваг тохируулагчийн тохиргоо"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Хэдэн минут болж магадгүй"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d суваг олдсон"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d суваг олдсон"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d суваг олдлоо</item>
+ <item quantity="one">%1$d суваг олдлоо</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"СУВАГ ХАЙХЫГ ЗОГСООХ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d суваг олдсон"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d суваг олдсон"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Гайхалтай! Суваг хайх явцад %1$d суваг олдлоо. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу."</item>
- <item quantity="other" msgid="8098777464551209564">"Гайхалтай! Суваг хайх явцад %1$d суваг олдлоо. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d суваг олдлоо</item>
+ <item quantity="one">%1$d суваг олдлоо</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other"> Сайн байна! Суваг хайх явцад %1$d суваг олдлоо. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
+ <item quantity="one">Сайн байна! Суваг хайх явцад %1$d суваг олдсон байна. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Дууссан"</item>
<item msgid="496688122303154468">"Дахин хайх"</item>
diff --git a/usbtuner/res/values-mr-rIN/strings.xml b/usbtuner/res/values-mr-rIN/strings.xml
index 6a1cd81d..ea1ffadb 100644
--- a/usbtuner/res/values-mr-rIN/strings.xml
+++ b/usbtuner/res/values-mr-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB चॅनेल ट्यूनर सेटअप"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"यास अनेक मिनिटे लागू शकतात"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d चॅनेल आढळले"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d चॅनेल आढळले"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d चॅनेल आढळले</item>
+ <item quantity="other">%1$d चॅनेल आढळले</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"चॅनेल स्कॅन करणे थांबवा"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d चॅनेल आढळले"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d चॅनेल आढळले"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"छान! चॅनेल स्कॅन करताना %1$d चॅनेल आढळले. हे योग्य नसल्‍याचे वाटत असल्‍यास, अॅंटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा."</item>
- <item quantity="other" msgid="8098777464551209564">"छान! चॅनेल स्कॅन करताना %1$d चॅनेल आढळले. हे योग्य नसल्‍याचे वाटल्‍यास, अॅंटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d चॅनेल आढळले</item>
+ <item quantity="other">%1$d चॅनेल आढळले</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">छान! चॅनेल स्कॅन करताना %1$d चॅनेल आढळले. हे योग्य वाटत नसल्यास, अॅंटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
+ <item quantity="other">छान! चॅनेल स्कॅन करताना %1$d चॅनेल आढळले. हे योग्य वाटत नसल्यास, अॅंटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"पूर्ण झाले"</item>
<item msgid="496688122303154468">"पुन्हा स्कॅन करा"</item>
diff --git a/usbtuner/res/values-ms-rMY/strings.xml b/usbtuner/res/values-ms-rMY/strings.xml
index 00cec77f..c124bfac 100644
--- a/usbtuner/res/values-ms-rMY/strings.xml
+++ b/usbtuner/res/values-ms-rMY/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Persediaan penala saluran USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Proses ini mungkin mengambil masa beberapa minit"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d saluran ditemui"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d saluran ditemui"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d saluran ditemui</item>
+ <item quantity="one">%1$d saluran ditemui</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"HENTIKAN PENGIMBASAN SALURAN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d saluran ditemui"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d saluran ditemui"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi."</item>
- <item quantity="other" msgid="8098777464551209564">"Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Selesai"</item>
<item msgid="496688122303154468">"Imbas lagi"</item>
diff --git a/usbtuner/res/values-my-rMM/strings.xml b/usbtuner/res/values-my-rMM/strings.xml
index 0036cf2b..0cdd574f 100644
--- a/usbtuner/res/values-my-rMM/strings.xml
+++ b/usbtuner/res/values-my-rMM/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB ချန်နယ် တျူနား စဖွင့်သတ်မှတ်ပါ"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"မိနစ် အနည်းငယ်ကြာနိုင်ပါသည်"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"ချန်နယ် %1$d ခု တွေ့ခဲ့သည်"</item>
- <item quantity="other" msgid="7340557317633613">"ချန်နယ် %1$d ခု တွေ့ခဲ့သည်"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">ချန်နယ် %1$d ခုတွေ့သည်</item>
+ <item quantity="one">ချန်နယ် %1$d ခုတွေ့သည်</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ချန်နယ် ရှာဖွေမှုကို ရပ်စဲပါ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"ချန်နယ် %1$d ခု တွေ့ခဲ့သည်"</item>
- <item quantity="other" msgid="4331542666115153576">"ချန်နယ် %1$d ခု တွေ့ခဲ့သည်"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"ကောင်းသည်။ ချန်နယ်များကို စကင် လုပ်စဉ် ချန်နယ် %1$d ကို တွေ့ခဲ့ပါသည်။ မမှန်ဘူးထင်လျှင်၊ ဧရီယာ အနေအထားကို ချိန်ညှိလျက် ထပ်စမ်းကြည့်ပါ။"</item>
- <item quantity="other" msgid="8098777464551209564">"ကောင်းသည်။ ချန်နယ်များကို စကင် လုပ်စဉ် ချန်နယ် %1$d ကို တွေ့ခဲ့ပါသည်။ မမှန်ဘူးထင်လျှင်၊ ဧရီယာ အနေအထားကို ချိန်ညှိလျက် ထပ်စမ်းကြည့်ပါ။"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">ချန်နယ် %1$d ခုတွေ့သည်</item>
+ <item quantity="one">ချန်နယ် %1$d ခုတွေ့သည်</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">ကောင်းသည်။ ချန်နယ်ရှာဖွေချိန်တွင် ချန်နယ် %1$d ခုတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင်၊ အင်တန်နာတည်နေရာကို ချိန်ညှိကာ ထပ်ရှာပါ။</item>
+ <item quantity="one">ကောင်းသည်။ ချန်နယ်ရှာဖွေချိန်တွင် ချန်နယ် %1$d ခုတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင်၊ အင်တန်နာတည်နေရာကို ချိန်ညှိကာ ထပ်ရှာပါ။</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"လုပ်ပြီး"</item>
<item msgid="496688122303154468">"ထပ်ပြီး စကင်လုပ်ပါ"</item>
diff --git a/usbtuner/res/values-nb/strings.xml b/usbtuner/res/values-nb/strings.xml
index 7297a8c9..20856f51 100644
--- a/usbtuner/res/values-nb/strings.xml
+++ b/usbtuner/res/values-nb/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Konfigurasjon av kanaler via USB-mottakeren"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Dette kan ta flere minutter"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanal ble funnet"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanaler ble funnet"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanaler er funnet</item>
+ <item quantity="one">%1$d kanal er funnet</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOPP KANALSKANNINGEN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanal ble funnet"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanaler ble funnet"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Flott! %1$d kanal ble funnet under kanalskanningen. Hvis dette virker feil, kan du prøve å justere antenneposisjonen og skanne på nytt."</item>
- <item quantity="other" msgid="8098777464551209564">"Flott! %1$d kanaler ble funnet under kanalskanningen. Hvis dette virker feil, kan du prøve å justere antenneposisjonen og skanne på nytt."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanaler er funnet</item>
+ <item quantity="one">%1$d kanal er funnet</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Flott! %1$d kanaler er funnet under kanalskanningen. Hvis dette virker feil, kan du prøve å justere antenneposisjonen og skanne på nytt.</item>
+ <item quantity="one">Flott! %1$d kanal er funnet under kanalskanningen. Hvis dette virker feil, kan du prøve å justere antenneposisjonen og skanne på nytt.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Ferdig"</item>
<item msgid="496688122303154468">"Skann på nytt"</item>
diff --git a/usbtuner/res/values-ne-rNP/strings.xml b/usbtuner/res/values-ne-rNP/strings.xml
index 62559729..f1588e4c 100644
--- a/usbtuner/res/values-ne-rNP/strings.xml
+++ b/usbtuner/res/values-ne-rNP/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB च्यानल ट्युनर सेटअप"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"यसले धेरै मिनेट लिन सक्छ"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d च्यानल फेला पर्‍यो"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d च्यानलहरू फेला परे"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d च्यानलहरू फेला पर्यो</item>
+ <item quantity="one">%1$d च्यानल फेला पर्यो</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"च्यानल स्क्यान गर्न रोक्नुहोस्"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d च्यानल फेला पर्‍यो"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d च्यानलहरू फेला परे"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"राम्रो! च्यानल स्क्यानको बेलामा %1$d च्यानल फेला परे। यदि यो सही लाग्दैन भने, एन्टेना अवस्था समायोजन गर्ने प्रयास गर्नुहोस् र फेरि स्क्यान गर्नुहोस्।"</item>
- <item quantity="other" msgid="8098777464551209564">"राम्रो! च्यानल स्क्यानको बेलामा %1$d च्यानलहरू फेला परे। यदि यो सही लाग्दैन भने, एन्टेना अवस्था समायोजन गर्ने प्रयास गर्नुहोस् र फेरि स्क्यान गर्नुहोस्।"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d च्यानलहरू फेला पर्यो</item>
+ <item quantity="one">%1$d च्यानल फेला पर्यो</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">राम्रो! च्यानल स्क्यान गर्दा %1$d च्यानलहरू फेला पर्यो। यदि त्यो सही जस्तो देखिन्न भने, एन्टेनाको स्थान समायोजन गर्ने प्रयास गर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
+ <item quantity="one">राम्रो! च्यानल स्क्यान गर्दा %1$d च्यानल फेला पर्यो। यदि त्यो सही जस्तो देखिन्न भने, एन्टेनाको स्थान समायोजन गर्ने प्रयास गर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"सम्पन्न भयो"</item>
<item msgid="496688122303154468">"फेरि स्क्यान गर्नुहोस्"</item>
diff --git a/usbtuner/res/values-nl/strings.xml b/usbtuner/res/values-nl/strings.xml
index faf3e4be..1e7cbe13 100644
--- a/usbtuner/res/values-nl/strings.xml
+++ b/usbtuner/res/values-nl/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Zenderconfiguratie van USB-tuner"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Dit kan enkele minuten duren"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanaal gevonden"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanalen gevonden"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanalen gevonden</item>
+ <item quantity="one">%1$d kanaal gevonden</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"KANAALSCAN STOPPEN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanaal gevonden"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanalen gevonden"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Er is %1$d kanaal gevonden tijdens de kanaalscan. Als je denkt dat dit niet klopt, pas je de antennepositie aan en voer je de scan opnieuw uit."</item>
- <item quantity="other" msgid="8098777464551209564">"Er zijn %1$d kanalen gevonden tijdens de kanaalscan. Als je denkt dat dit niet klopt, pas je de antennepositie aan en voer je de scan opnieuw uit."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanalen gevonden</item>
+ <item quantity="one">%1$d kanaal gevonden</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Er zijn %1$d kanalen gevonden tijdens de kanaalscan. Als je denkt dat dit niet klopt, pas je de antennepositie aan en voer je de scan opnieuw uit.</item>
+ <item quantity="one">Er is %1$d kanaal gevonden tijdens de kanaalscan. Als je denkt dat dit niet klopt, pas je de antennepositie aan en voer je de scan opnieuw uit.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Gereed"</item>
<item msgid="496688122303154468">"Opnieuw scannen"</item>
diff --git a/usbtuner/res/values-pl/strings.xml b/usbtuner/res/values-pl/strings.xml
index 7715d324..43f1bdc7 100644
--- a/usbtuner/res/values-pl/strings.xml
+++ b/usbtuner/res/values-pl/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Konfiguracja kanałów w tunerze USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Może to potrwać kilka minut"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Znaleziono %1$d kanał"</item>
- <item quantity="other" msgid="7340557317633613">"Znalezione kanały: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="few">Znaleziono %1$d kanały</item>
+ <item quantity="many">Znaleziono %1$d kanałów</item>
+ <item quantity="other">Znaleziono %1$d kanału</item>
+ <item quantity="one">Znaleziono %1$d kanał</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ZATRZYMAJ SKANOWANIE W POSZUKIWANIU KANAŁÓW"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Znaleziono %1$d kanał"</item>
- <item quantity="other" msgid="4331542666115153576">"Znalezione kanały: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Świetnie! Podczas skanowania znaleziono %1$d kanał. Jeśli coś jest nie tak, wyreguluj położenie anteny i ponownie wykonaj skanowanie."</item>
- <item quantity="other" msgid="8098777464551209564">"Świetnie! Podczas skanowania znaleziono kanały: %1$d. Jeśli coś jest nie tak, spróbuj wyregulować położenie anteny i ponownie wykonaj skanowanie."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="few">Znaleziono %1$d kanały</item>
+ <item quantity="many">Znaleziono %1$d kanałów</item>
+ <item quantity="other">Znaleziono %1$d kanału</item>
+ <item quantity="one">Znaleziono %1$d kanał</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="few">Super! Podczas skanowania znaleziono %1$d kanały. Jeśli coś jest nie tak, wyreguluj położenie anteny i ponownie wykonaj skanowanie</item>
+ <item quantity="many"> Super! Podczas skanowania znaleziono %1$d kanałów. Jeśli coś jest nie tak, wyreguluj położenie anteny i ponownie wykonaj skanowanie</item>
+ <item quantity="other"> Super! Podczas skanowania znaleziono %1$d kanału. Jeśli coś jest nie tak, wyreguluj położenie anteny i ponownie wykonaj skanowanie</item>
+ <item quantity="one">Super! Podczas skanowania znaleziono %1$d kanał. Jeśli coś jest nie tak, wyreguluj położenie anteny i ponownie wykonaj skanowanie</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Gotowe"</item>
<item msgid="496688122303154468">"Skanuj ponownie"</item>
diff --git a/usbtuner/res/values-pt-rPT/strings.xml b/usbtuner/res/values-pt-rPT/strings.xml
index dc5ec6c1..ec51b909 100644
--- a/usbtuner/res/values-pt-rPT/strings.xml
+++ b/usbtuner/res/values-pt-rPT/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuração do sintonizador de canais USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Esta operação pode demorar vários minutos"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d canais encontrados"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d canais encontrados</item>
+ <item quantity="one">%1$d canal encontrado</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"INTERROMPER A PROCURA DE CANAIS"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d canais encontrados"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Boa! Foi encontrado %1$d canal durante a procura de canais. Se não lhe parecer correto, experimente ajustar a posição da antena e procurar novamente."</item>
- <item quantity="other" msgid="8098777464551209564">"Boa! Foram encontrados %1$d canais durante a procura de canais. Se não lhe parecer correto, experimente ajustar a posição da antena e pesquisar novamente."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d canais encontrados</item>
+ <item quantity="one">%1$d canal encontrado</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Boa! Foram encontrados %1$d canais 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="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>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Concluído"</item>
<item msgid="496688122303154468">"Procurar novamente"</item>
diff --git a/usbtuner/res/values-pt/strings.xml b/usbtuner/res/values-pt/strings.xml
index 19ec852a..6d51c770 100644
--- a/usbtuner/res/values-pt/strings.xml
+++ b/usbtuner/res/values-pt/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configuração do sintonizador de canais USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Isso pode demorar alguns minutos"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d canais encontrados"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d canais encontrados</item>
+ <item quantity="other">%1$d canais encontrados</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"INTERROMPER PROCURA DE CANAIS"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d canal encontrado"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d canais encontrados"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Legal! %1$d canal foi encontrado durante a procura de canais. Se você achar que esse número não está certo, tente ajustar a posição da antena e procure novamente."</item>
- <item quantity="other" msgid="8098777464551209564">"Legal! %1$d canais foram encontrados durante a procura de canais. Se você achar que esse número não está certo, tente ajustar a posição da antena e procure novamente."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d canais encontrados</item>
+ <item quantity="other">%1$d canais encontrados</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Legal! %1$d canais foram encontrados durante a procura de canais. Se você acha que esse número não está correto, tente ajustar a posição da antena e procure novamente.</item>
+ <item quantity="other">Legal! %1$d canais foram encontrados durante a procura de canais. Se você acha que esse número não está correto, tente ajustar a posição da antena e procure novamente.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Concluído"</item>
<item msgid="496688122303154468">"Procurar novamente"</item>
diff --git a/usbtuner/res/values-ro/strings.xml b/usbtuner/res/values-ro/strings.xml
index 3085ed30..2773348d 100644
--- a/usbtuner/res/values-ro/strings.xml
+++ b/usbtuner/res/values-ro/strings.xml
@@ -50,19 +50,22 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Configurarea tunerului de canale USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Poate dura mai multe minute"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d canal găsit"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d (de) canale găsite"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="few">%1$d canale găsite</item>
+ <item quantity="other">%1$d de canale găsite</item>
+ <item quantity="one">%1$d canal găsit</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"OPRIȚI SCANAREA CANALELOR"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d canal găsit"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d (de) canale găsite"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Excelent! La scanarea canalelor s-a găsit %1$d canal. Dacă vi se pare că ceva nu este în regulă, încercați să ajustați poziția antenei și repetați scanarea."</item>
- <item quantity="other" msgid="8098777464551209564">"Excelent! La scanarea canalelor s-au găsit %1$d (de) canale. Dacă vi se pare că ceva nu este în regulă, încercați să ajustați poziția antenei și repetați scanarea."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="few">%1$d canale găsite</item>
+ <item quantity="other">%1$d de canale găsite</item>
+ <item quantity="one">%1$d canal găsit</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="few">Excelent! La scanarea canalelor s-au găsit %1$d canale. Dacă vi se pare că ceva nu este în regulă, încercați să ajustați poziția antenei și repetați scanarea.</item>
+ <item quantity="other">Excelent! La scanarea canalelor s-au găsit %1$d de canale. Dacă vi se pare că ceva nu este în regulă, încercați să ajustați poziția antenei și repetați scanarea.</item>
+ <item quantity="one">Excelent! La scanarea canalelor s-a găsit %1$d canal. Dacă vi se pare că ceva nu este în regulă, încercați să ajustați poziția antenei și repetați scanarea.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Terminat"</item>
<item msgid="496688122303154468">"Scanați din nou"</item>
diff --git a/usbtuner/res/values-ru/strings.xml b/usbtuner/res/values-ru/strings.xml
index adb51e7c..2f3aab50 100644
--- a/usbtuner/res/values-ru/strings.xml
+++ b/usbtuner/res/values-ru/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Настройка USB-тюнера"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Это может занять несколько минут."</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Найдено каналов: %1$d"</item>
- <item quantity="other" msgid="7340557317633613">"Найдено каналов: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Найден %1$d канал</item>
+ <item quantity="few">Найдено %1$d канала</item>
+ <item quantity="many">Найдено %1$d каналов</item>
+ <item quantity="other">Найдено %1$d канала</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"НЕ СКАНИРОВАТЬ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Найдено каналов: %1$d"</item>
- <item quantity="other" msgid="4331542666115153576">"Найдено каналов: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Найден %1$d канал. Если такой результат вас не устраивает, перенесите антенну и повторите сканирование."</item>
- <item quantity="other" msgid="8098777464551209564">"Найдены каналы (%1$d). Если такой результат вас не устраивает, перенесите антенну и повторите сканирование."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Найден %1$d канал</item>
+ <item quantity="few">Найдено %1$d канала</item>
+ <item quantity="many">Найдено %1$d каналов</item>
+ <item quantity="other">Найдено %1$d канала</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Отлично! Найден %1$d канал. Если такой результат вас не устраивает, переместите антенну и повторите сканирование.</item>
+ <item quantity="few">Отлично! Найдено %1$d канала. Если такой результат вас не устраивает, переместите антенну и повторите сканирование.</item>
+ <item quantity="many">Отлично! Найдено %1$d каналов. Если такой результат вас не устраивает, переместите антенну и повторите сканирование.</item>
+ <item quantity="other">Отлично! Найдено %1$d канала. Если такой результат вас не устраивает, переместите антенну и повторите сканирование.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Готово"</item>
<item msgid="496688122303154468">"Сканировать повторно"</item>
diff --git a/usbtuner/res/values-si-rLK/strings.xml b/usbtuner/res/values-si-rLK/strings.xml
index e279a4f5..b8968e6e 100644
--- a/usbtuner/res/values-si-rLK/strings.xml
+++ b/usbtuner/res/values-si-rLK/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB නාලිකා සුසරක පිහිටුවීම"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"මෙය මිනිත්තු කිහිපයක් ගත හැකිය"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"නාලිකා %1$dක් සොයා ගන්නා ලදී"</item>
- <item quantity="other" msgid="7340557317633613">"නාලිකා %1$dක් සොයා ගන්නා ලදී"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"නාලිකා ස්කෑන් කිරීම නවත්වන්න"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"නාලිකා %1$dක් සොයා ගන්නා ලදී"</item>
- <item quantity="other" msgid="4331542666115153576">"නාලිකා %1$dක් සොයා ගන්නා ලදී"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න."</item>
- <item quantity="other" msgid="8098777464551209564">"කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
+ <item quantity="other">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"නිමයි"</item>
<item msgid="496688122303154468">"නැවත ස්කෑන් කරන්න"</item>
diff --git a/usbtuner/res/values-sk/strings.xml b/usbtuner/res/values-sk/strings.xml
index f8e4c385..b2673ac9 100644
--- a/usbtuner/res/values-sk/strings.xml
+++ b/usbtuner/res/values-sk/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Nastavenie kanálov tunera USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Môže to trvať niekoľko minút"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Našiel sa %1$d kanál"</item>
- <item quantity="other" msgid="7340557317633613">"Nájdené kanály: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="few">Našli sa %1$d kanály</item>
+ <item quantity="many">Našlo sa %1$d kanála</item>
+ <item quantity="other">Našlo sa %1$d kanálov</item>
+ <item quantity="one">Našiel sa %1$d kanál</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ZASTAVIŤ HĽADANIE KANÁLOV"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Našiel sa %1$d kanál"</item>
- <item quantity="other" msgid="4331542666115153576">"Nájdené kanály: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Skvelé! Pri hľadaní kanálov sa našiel %1$d kanál. Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova."</item>
- <item quantity="other" msgid="8098777464551209564">"Skvelé! Pri hľadaní kanálov sa našlo niekoľko kanálov (počet: %1$d). Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="few">Našli sa %1$d kanály</item>
+ <item quantity="many">Našlo sa %1$d kanála</item>
+ <item quantity="other">Našlo sa %1$d kanálov</item>
+ <item quantity="one">Našiel sa %1$d kanál</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="few">Skvelé! Pri hľadaní kanálov sa našli %1$d kanály. Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova.</item>
+ <item quantity="many">Skvelé! Pri hľadaní kanálov sa našlo %1$d kanála. Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova.</item>
+ <item quantity="other">Skvelé! Pri hľadaní kanálov sa našlo %1$d kanálov. Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova.</item>
+ <item quantity="one">Skvelé! Pri hľadaní kanálov sa našiel %1$d kanál. Ak sa vám to nezdá, skúste upraviť pozíciu antény a spustite hľadanie znova.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Hotovo"</item>
<item msgid="496688122303154468">"Hľadať znova"</item>
diff --git a/usbtuner/res/values-sl/strings.xml b/usbtuner/res/values-sl/strings.xml
index 352250ad..9fc197a3 100644
--- a/usbtuner/res/values-sl/strings.xml
+++ b/usbtuner/res/values-sl/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Nastavitev sprejemnika kanalov USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"To lahko traja nekaj minut"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Najden je bil %1$d kanal"</item>
- <item quantity="other" msgid="7340557317633613">"Najdenih je bilo toliko kanalov: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Najden je bil %1$d kanal</item>
+ <item quantity="two">Najdena sta bila %1$d kanala</item>
+ <item quantity="few">Najdeni so bili %1$d kanali</item>
+ <item quantity="other">Najdenih je bilo %1$d kanalov</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"USTAVI ISKANJE KANALOV"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Najden je bil %1$d kanal"</item>
- <item quantity="other" msgid="4331542666115153576">"Najdenih je bilo toliko kanalov: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Lepo! Med iskanjem kanalov je bil najden %1$d kanal. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova."</item>
- <item quantity="other" msgid="8098777464551209564">"Lepo! Med iskanjem kanalov je bilo najdenih toliko kanalov: %1$d. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Najden je bil %1$d kanal</item>
+ <item quantity="two">Najdena sta bila %1$d kanala</item>
+ <item quantity="few">Najdeni so bili %1$d kanali</item>
+ <item quantity="other">Najdenih je bilo %1$d kanalov</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Super. Med iskanjem kanalov je bil najden %1$d kanal. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova.</item>
+ <item quantity="two">Super. Med iskanjem kanalov sta bila najdena %1$d kanala. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova.</item>
+ <item quantity="few">Super. Med iskanjem kanalov so bili najdeni %1$d kanali. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova.</item>
+ <item quantity="other">Super. Med iskanjem kanalov je bilo najdenih %1$d kanalov. Če menite, da to ni pravilno, poskusite prilagoditi položaj antene in iščite znova.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Končano"</item>
<item msgid="496688122303154468">"Znova išči"</item>
diff --git a/usbtuner/res/values-sr/strings.xml b/usbtuner/res/values-sr/strings.xml
index 48ae4bb5..ade9584e 100644
--- a/usbtuner/res/values-sr/strings.xml
+++ b/usbtuner/res/values-sr/strings.xml
@@ -50,19 +50,22 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Подешавање USB тјунера за канале"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Ово може да потраје неколико минута"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Пронашли смо %1$d канал"</item>
- <item quantity="other" msgid="7340557317633613">"Пронашли смо %1$d канала"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Пронашли смо %1$d канал</item>
+ <item quantity="few">Пронашли смо %1$d канала</item>
+ <item quantity="other">Пронашли смо %1$d канала</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ЗАУСТАВИ СКЕНИРАЊЕ КАНАЛА"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Пронашли смо %1$d канал"</item>
- <item quantity="other" msgid="4331542666115153576">"Пронашли смо %1$d канала"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Одлично! Пронашли смо %1$d канал током скенирања канала. Ако сматрате да ово није у реду, покушајте да подесите положај антене и да поново обавите скенирање."</item>
- <item quantity="other" msgid="8098777464551209564">"Одлично! Пронашли смо %1$d канала током скенирања канала. Ако сматрате да ово није у реду, покушајте да подесите положај антене и да поново обавите скенирање."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Пронашли смо %1$d канал</item>
+ <item quantity="few">Пронашли смо %1$d канала</item>
+ <item quantity="other">Пронашли смо %1$d канала</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Одлично! Пронашли смо %1$d канал током скенирања канала. Ако сматрате да ово није у реду, покушајте да подесите положај антене и да поново обавите скенирање.</item>
+ <item quantity="few">Одлично! Пронашли смо %1$d канала током скенирања канала. Ако сматрате да ово није у реду, покушајте да подесите положај антене и да поново обавите скенирање.</item>
+ <item quantity="other">Одлично! Пронашли смо %1$d канала током скенирања канала. Ако сматрате да ово није у реду, покушајте да подесите положај антене и да поново обавите скенирање.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Готово"</item>
<item msgid="496688122303154468">"Скенирај поново"</item>
diff --git a/usbtuner/res/values-sv/strings.xml b/usbtuner/res/values-sv/strings.xml
index 0ab32300..501725eb 100644
--- a/usbtuner/res/values-sv/strings.xml
+++ b/usbtuner/res/values-sv/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Kanalinställning för USB-mottagare"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Det här kan ta flera minuter"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanal hittades"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanaler hittades"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanaler hittades</item>
+ <item quantity="one">%1$d kanal hittades</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"STOPPA KANALSÖKNINGEN"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanal hittades"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanaler hittades"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Härligt! %1$d kanal hittades vid kanalsökningen. Om det här inte verkar stämma kan du testa att justera antennens läge och söka igen."</item>
- <item quantity="other" msgid="8098777464551209564">"Härligt! %1$d kanaler hittades vid kanalsökningen. Om det här inte verkar stämma kan du testa att justera antennens läge och söka igen."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanaler hittades</item>
+ <item quantity="one">%1$d kanal hittades</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Härligt! %1$d kanaler hittades vid kanalsökningen. Om det här inte verkar stämma kan du testa att justera antennens läge och söka igen.</item>
+ <item quantity="one">Härligt! %1$d kanal hittades vid kanalsökningen. Om det här inte verkar stämma kan du testa att justera antennens läge och söka igen.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Klar"</item>
<item msgid="496688122303154468">"Sök igen"</item>
diff --git a/usbtuner/res/values-sw/strings.xml b/usbtuner/res/values-sw/strings.xml
index d790ac09..4a6e0f24 100644
--- a/usbtuner/res/values-sw/strings.xml
+++ b/usbtuner/res/values-sw/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Kuweka mipangilio ya kitafuta vituo cha USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Hii inaweza kuchukua dakika kadhaa"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Imepata kituo %1$d"</item>
- <item quantity="other" msgid="7340557317633613">"Imepata vituo %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Vituo %1$d vimepatikana</item>
+ <item quantity="one">Kituo %1$d kimepatikana</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"SIMAMISHA UTAFUTAJI WA VITUO"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Imepata kituo %1$d"</item>
- <item quantity="other" msgid="4331542666115153576">"Imepata vituo %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Marahaba! Imetafuta na kupata kituo %1$d. Kama hujaridhika, jaribu kurekebisha mkao wa antena na utafute tena."</item>
- <item quantity="other" msgid="8098777464551209564">"Marahaba! Imetafuta na kupata vituo %1$d. Kama hujaridhika, jaribu kurekebisha mkao wa antena na utafute tena."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">Vituo %1$d vimepatikana</item>
+ <item quantity="one">Kituo %1$d kimepatikana</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Sadakta! Vituo %1$d vimepatikana baada ya kutafuta vituo. Kama hujaridhika, jaribu kurekebisha mkao wa antena na utafute tena.</item>
+ <item quantity="one">Sadakta! Kituo %1$d kimepatikana baada ya kutafuta vituo. Kama hujaridhika, jaribu kurekebisha mkao wa antena kisha utafute tena.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Imemaliza"</item>
<item msgid="496688122303154468">"Tafuta tena"</item>
diff --git a/usbtuner/res/values-ta-rIN/strings.xml b/usbtuner/res/values-ta-rIN/strings.xml
index 69338e23..6db07d72 100644
--- a/usbtuner/res/values-ta-rIN/strings.xml
+++ b/usbtuner/res/values-ta-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB சேனல் டியூனர் அமைவு"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"இதற்குச் சில நிமிடங்கள் ஆகலாம்"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d சேனல் உள்ளது"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d சேனல்கள் உள்ளன"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
+ <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"சேனலை ஸ்கேன் செய்வதை நிறுத்து"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d சேனல் உள்ளது"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d சேனல்கள் உள்ளன"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல் கண்டறியப்பட்டது. இது சரியாகத் தெரியவில்லை என்றால், ஆன்டெனா நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்."</item>
- <item quantity="other" msgid="8098777464551209564">"அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல்கள் கண்டறியப்பட்டன. இவை சரியாகத் தெரியவில்லை எனில், ஆன்டெனா நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
+ <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல்கள் கண்டறியப்பட்டன. இவை சரியாகத் தெரியவில்லை என்றால், ஆன்டெனா நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
+ <item quantity="one">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல் கண்டறியப்பட்டது. இது சரியாகத் தெரியவில்லை என்றால், ஆன்டெனா நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"முடிந்தது"</item>
<item msgid="496688122303154468">"மீண்டும் ஸ்கேன் செய்"</item>
diff --git a/usbtuner/res/values-te-rIN/strings.xml b/usbtuner/res/values-te-rIN/strings.xml
index 2c2099e6..c80ea655 100644
--- a/usbtuner/res/values-te-rIN/strings.xml
+++ b/usbtuner/res/values-te-rIN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB ఛానెల్ ట్యూనర్ సెటప్"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"దీనికి కొన్ని నిమిషాలు పట్టవచ్చు"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ఛానెల్ కనుగొనబడింది"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ఛానెల్‌లు కనుగొనబడ్డాయి"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
+ <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ఛానెల్ స్కాన్‌ను ఆపివేయి"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ఛానెల్ కనుగొనబడింది"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ఛానెల్‌లు కనుగొనబడ్డాయి"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"బాగుంది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్ కనుగొనబడింది. ఇది సరైనదిగా కనిపించకపోతే, యాంటెన్నా స్థానాన్ని సర్దుబాటు చేయడాన్ని ప్రయత్నించి, ఆపై మళ్లీ స్కాన్ చేయండి."</item>
- <item quantity="other" msgid="8098777464551209564">"బాగుంది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్‌లు కనుగొనబడ్డాయి. ఇది సరైనదిగా కనిపించకపోతే, యాంటెన్నా స్థానాన్ని సర్దుబాటు చేయడాన్ని ప్రయత్నించి, ఆపై మళ్లీ స్కాన్ చేయండి."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
+ <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్‌లు కనుగొనబడ్డాయి. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
+ <item quantity="one">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్ కనుగొనబడింది. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"పూర్తయింది"</item>
<item msgid="496688122303154468">"మళ్లీ స్కాన్ చేయి"</item>
diff --git a/usbtuner/res/values-th/strings.xml b/usbtuner/res/values-th/strings.xml
index 66ddca9b..a937c6ec 100644
--- a/usbtuner/res/values-th/strings.xml
+++ b/usbtuner/res/values-th/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"ตั้งค่าตัวรับสัญญาณช่องแบบ USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"อาจใช้เวลาหลายนาที"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"พบ %1$d ช่อง"</item>
- <item quantity="other" msgid="7340557317633613">"พบ %1$d ช่อง"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">พบ %1$d ช่อง</item>
+ <item quantity="one">พบ %1$d ช่อง</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"หยุดการสแกนช่อง"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"พบ %1$d ช่อง"</item>
- <item quantity="other" msgid="4331542666115153576">"พบ %1$d ช่อง"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"เยี่ยมมาก! พบ %1$d ช่องระหว่างการสแกน หากคุณคิดว่าไม่ถูกต้อง ให้ลองปรับตำแหน่งเสาอากาศและสแกนอีกครั้ง"</item>
- <item quantity="other" msgid="8098777464551209564">"เยี่ยมมาก! พบ %1$d ช่องระหว่างการสแกน หากคุณคิดว่าไม่ถูกต้อง ให้ลองปรับตำแหน่งเสาอากาศและสแกนอีกครั้ง"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">พบ %1$d ช่อง</item>
+ <item quantity="one">พบ %1$d ช่อง</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">เยี่ยมมาก! พบ %1$d ช่องระหว่างการสแกนช่อง หากคุณคิดว่าไม่ถูกต้อง ให้ลองปรับตำแหน่งเสาอากาศและสแกนอีกครั้ง</item>
+ <item quantity="one">เยี่ยมมาก! พบ %1$d ช่องระหว่างการสแกนช่อง หากคุณคิดว่าไม่ถูกต้อง ให้ลองปรับตำแหน่งเสาอากาศและสแกนอีกครั้ง</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"เสร็จ"</item>
<item msgid="496688122303154468">"สแกนอีกครั้ง"</item>
diff --git a/usbtuner/res/values-tl/strings.xml b/usbtuner/res/values-tl/strings.xml
index 11818c9d..aad2e1cc 100644
--- a/usbtuner/res/values-tl/strings.xml
+++ b/usbtuner/res/values-tl/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Pag-setup ng USB tuner ng channel"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Maaaring abutin ito ng ilang minuto"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Nakakita ng %1$d channel"</item>
- <item quantity="other" msgid="7340557317633613">"Nakakita ng %1$d (na) channel"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Nakahanap ng %1$d channel</item>
+ <item quantity="other">Nakahanap ng %1$d na channel</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"IHINTO ANG PAG-SCAN NG CHANNEL"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Nakakita ng %1$d channel"</item>
- <item quantity="other" msgid="4331542666115153576">"Nakakita ng %1$d (na) channel"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Ayos! Nakakita ng %1$d channel noong nag-ii-scan ng channel. Kung sa palagay mo ay kulang pa ito, subukang ayusin ang posisyon ng antenna at muling mag-scan."</item>
- <item quantity="other" msgid="8098777464551209564">"Ayos! Nakakita ng %1$d (na) channel noong nag-ii-scan ng channel. Kung sa palagay mo ay kulang pa ito, subukang ayusin ang posisyon ng antenna at muling mag-scan."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Nakahanap ng %1$d channel</item>
+ <item quantity="other">Nakahanap ng %1$d na channel</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Ayos! Nakahanap ng %1$d channel noong nag-ii-scan ng channel. Kung sa palagay mo ay kulang pa ito, subukang ayusin ang posisyon ng antenna at muling mag-scan.</item>
+ <item quantity="other">Ayos! Nakahanap ng %1$d na channel noong nag-ii-scan ng channel. Kung sa palagay mo ay kulang pa ito, subukang ayusin ang posisyon ng antenna at muling mag-scan.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Tapos Na"</item>
<item msgid="496688122303154468">"Muling mag-scan"</item>
diff --git a/usbtuner/res/values-tr/strings.xml b/usbtuner/res/values-tr/strings.xml
index 5e9e1072..167b220e 100644
--- a/usbtuner/res/values-tr/strings.xml
+++ b/usbtuner/res/values-tr/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB kanal ayarlayıcı kurulumu"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Bu işlem birkaç dakika sürebilir"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d kanal bulundu"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d kanal bulundu"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">%1$d kanal bulundu</item>
+ <item quantity="one">%1$d kanal bulundu</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"KANAL TARAMAYI DURDUR"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d kanal bulundu"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d kanal bulundu"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Harika! Kanal tarama sırasında %1$d kanal bulundu. Bu sonuç doğru görünmüyorsa antenin konumunu ayarlayıp tekrar taramayı deneyin."</item>
- <item quantity="other" msgid="8098777464551209564">"Harika! Kanal tarama sırasında %1$d kanal bulundu. Bu sonuç doğru görünmüyorsa antenin konumunu ayarlayıp tekrar taramayı deneyin."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">%1$d kanal bulundu</item>
+ <item quantity="one">%1$d kanal bulundu</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Harika! Kanal tarama sırasında %1$d kanal bulundu. Bu sonuç doğru görünmüyorsa antenin konumunu ayarlayıp tekrar taramayı deneyin.</item>
+ <item quantity="one">Harika! Kanal tarama sırasında %1$d kanal bulundu. Bu sonuç doğru görünmüyorsa antenin konumunu ayarlayıp tekrar taramayı deneyin.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Bitti"</item>
<item msgid="496688122303154468">"Yeniden tara"</item>
diff --git a/usbtuner/res/values-uk/strings.xml b/usbtuner/res/values-uk/strings.xml
index e9ec8905..f84badba 100644
--- a/usbtuner/res/values-uk/strings.xml
+++ b/usbtuner/res/values-uk/strings.xml
@@ -50,19 +50,25 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Налаштування USB-тюнера"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Це може зайняти декілька хвилин"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Знайдено %1$d канал"</item>
- <item quantity="other" msgid="7340557317633613">"Знайдено каналів: %1$d"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">Знайдено %1$d канал</item>
+ <item quantity="few">Знайдено %1$d канали</item>
+ <item quantity="many">Знайдено %1$d каналів</item>
+ <item quantity="other">Знайдено %1$d каналу</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"ПРИПИНИТИ ПОШУК КАНАЛІВ"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Знайдено %1$d канал"</item>
- <item quantity="other" msgid="4331542666115153576">"Знайдено каналів: %1$d"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Знайдено %1$d канал. Якщо має бути більше каналів, змініть положення антени та повторіть спробу."</item>
- <item quantity="other" msgid="8098777464551209564">"Знайдено стільки каналів: %1$d. Якщо має бути більше каналів, змініть положення антени та повторіть спробу."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">Знайдено %1$d канал</item>
+ <item quantity="few">Знайдено %1$d канали</item>
+ <item quantity="many">Знайдено %1$d каналів</item>
+ <item quantity="other">Знайдено %1$d каналу</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one"> Під час сканування знайдено %1$d канал. Якщо має бути більше каналів, змініть положення антени та проскануйте знову.</item>
+ <item quantity="few"> Під час сканування знайдено %1$d канали. Якщо має бути більше каналів, змініть положення антени та проскануйте знову.</item>
+ <item quantity="many"> Під час сканування знайдено %1$d каналів. Якщо має бути більше каналів, змініть положення антени та проскануйте знову.</item>
+ <item quantity="other"> Під час сканування знайдено %1$d каналу. Якщо має бути більше каналів, змініть положення антени та проскануйте знову.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Готово"</item>
<item msgid="496688122303154468">"Шукати знову"</item>
diff --git a/usbtuner/res/values-ur-rPK/strings.xml b/usbtuner/res/values-ur-rPK/strings.xml
index e696fd6a..38b8d601 100644
--- a/usbtuner/res/values-ur-rPK/strings.xml
+++ b/usbtuner/res/values-ur-rPK/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"‏USB چینل ٹیونر سیٹ اپ"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"اس میں کئی منٹ لگ سکتے ہیں"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"‏%1$d چینل ملا"</item>
- <item quantity="other" msgid="7340557317633613">"‏%1$d چینلز ملے"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">‏%1$d چینل ملے</item>
+ <item quantity="one">‏%1$d چینل ملا</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"چینل اسکین روکیں"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"‏%1$d چینل ملا"</item>
- <item quantity="other" msgid="4331542666115153576">"‏%1$d چینلز ملے"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"‏خوب! چینل اسکین کے دوران ‎%1$d چینل ملا۔ اگر یہ ٹھیک نہ لگے تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔"</item>
- <item quantity="other" msgid="8098777464551209564">"‏خوب! چینل اسکین کے دوران ‎%1$d چینلز ملے۔ اگر یہ ٹھیک نہ لگے تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">‏%1$d چینل ملے</item>
+ <item quantity="one">‏%1$d چینل ملا</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">‏خوب! چینل اسکین کے دوران ‎%1$d چینل ملے۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
+ <item quantity="one">‏خوب! چینل اسکین کے دوران ‎%1$d چینل ملا۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"ہو گیا"</item>
<item msgid="496688122303154468">"دوبارہ اسکین کریں"</item>
diff --git a/usbtuner/res/values-uz-rUZ/strings.xml b/usbtuner/res/values-uz-rUZ/strings.xml
index fb31f815..06c953fb 100644
--- a/usbtuner/res/values-uz-rUZ/strings.xml
+++ b/usbtuner/res/values-uz-rUZ/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB kanal tyunerini sozlash"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Bu bir necha daqiqa vaqt olishi mumkin"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d ta kanal topildi"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d ta kanal topildi"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <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="8358794117343664624">"KANAL QIDIRUVINI TO‘XTATISH"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d ta kanal topildi"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d ta kanal topildi"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"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="other" msgid="8098777464551209564">"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>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <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="1946474144459881182">
+ <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="979481834388007277">"Tayyor"</item>
<item msgid="496688122303154468">"Yana qidirish"</item>
diff --git a/usbtuner/res/values-vi/strings.xml b/usbtuner/res/values-vi/strings.xml
index 660d7821..966b139b 100644
--- a/usbtuner/res/values-vi/strings.xml
+++ b/usbtuner/res/values-vi/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Thiết lập bộ dò kênh USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Quá trình này có thể mất vài phút"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"Đã tìm thấy %1$d kênh"</item>
- <item quantity="other" msgid="7340557317633613">"Đã tìm thấy %1$d kênh"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">Đã tìm thấy %1$d kênh</item>
+ <item quantity="one">Đã tìm thấy %1$d kênh</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"NGỪNG QUÉT KÊNH"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"Đã tìm thấy %1$d kênh"</item>
- <item quantity="other" msgid="4331542666115153576">"Đã tìm thấy %1$d kênh"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Thật tuyệt! Đã tìm thấy %1$d kênh trong quá trình quét kênh. Nếu kết quả này có vẻ chưa chính xác, hãy thử điều chỉnh vị trí của ăng-ten và quét lại."</item>
- <item quantity="other" msgid="8098777464551209564">"Thật tuyệt! Đã tìm thấy %1$d kênh trong quá trình quét kênh. Nếu kết quả này có vẻ chưa chính xác, hãy thử điều chỉnh vị trí của ăng-ten và quét lại."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">Đã tìm thấy %1$d kênh</item>
+ <item quantity="one">Đã tìm thấy %1$d kênh</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">Tuyệt! Đã tìm thấy %1$d kênh trong quá trình quét kênh. Nếu điều này có vẻ không ổn, hãy thử điều chỉnh vị trí ăng-ten và quét lại.</item>
+ <item quantity="one">Tuyệt! Đã tìm thấy %1$d kênh trong quá trình quét kênh. Nếu điều này có vẻ không ổn, hãy thử điều chỉnh vị trí ăng-ten và quét lại.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Xong"</item>
<item msgid="496688122303154468">"Quét lại"</item>
diff --git a/usbtuner/res/values-zh-rCN/strings.xml b/usbtuner/res/values-zh-rCN/strings.xml
index 9f5ffb5c..5f8d366f 100644
--- a/usbtuner/res/values-zh-rCN/strings.xml
+++ b/usbtuner/res/values-zh-rCN/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB 频道调谐器设置"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"此过程可能需要几分钟时间"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"找到 %1$d 个频道"</item>
- <item quantity="other" msgid="7340557317633613">"找到 %1$d 个频道"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">找到 %1$d 个频道</item>
+ <item quantity="one">找到 %1$d 个频道</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"停止频道扫描"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"找到 %1$d 个频道"</item>
- <item quantity="other" msgid="4331542666115153576">"找到 %1$d 个频道"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"很好!系统在频道扫描过程中找到 %1$d 个频道。如果您觉得数量有误,请尝试调整天线的位置,然后再扫描一次。"</item>
- <item quantity="other" msgid="8098777464551209564">"很好!系统在频道扫描过程中找到 %1$d 个频道。如果您觉得数量有误,请尝试调整天线的位置,然后再扫描一次。"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">找到 %1$d 个频道</item>
+ <item quantity="one">找到 %1$d 个频道</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">很好!系统在频道扫描过程中找到 %1$d 个频道。如果您觉得数量有误,请尝试调整天线的位置,然后再扫描一次。</item>
+ <item quantity="one">很好!系统在频道扫描过程中找到 %1$d 个频道。如果您觉得数量有误,请尝试调整天线的位置,然后再扫描一次。</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"完成"</item>
<item msgid="496688122303154468">"重新扫描"</item>
diff --git a/usbtuner/res/values-zh-rHK/strings.xml b/usbtuner/res/values-zh-rHK/strings.xml
index d0ac38a2..67ee0a15 100644
--- a/usbtuner/res/values-zh-rHK/strings.xml
+++ b/usbtuner/res/values-zh-rHK/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB 頻道調諧器設定"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"可能需時數分鐘"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"已找到 %1$d 個頻道"</item>
- <item quantity="other" msgid="7340557317633613">"已找到 %1$d 個頻道"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">已找到 %1$d 個頻道</item>
+ <item quantity="one">已找到 %1$d 個頻道</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"停止頻道掃瞄"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"已找到 %1$d 個頻道"</item>
- <item quantity="other" msgid="4331542666115153576">"已找到 %1$d 個頻道"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"太好了!掃瞄頻道時找到 %1$d 個頻道。如果掃瞄結果看來不正確,請嘗試調整天線位置並重新掃瞄。"</item>
- <item quantity="other" msgid="8098777464551209564">"太好了!掃瞄頻道時找到 %1$d 個頻道。如果掃瞄結果看來不正確,請嘗試調整天線位置並重新掃瞄。"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">已找到 %1$d 個頻道</item>
+ <item quantity="one">已找到 %1$d 個頻道</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">太好了!掃瞄頻道時找到 %1$d 個頻道。如果掃瞄結果看來不正確,請嘗試調整天線位置並重新掃瞄。</item>
+ <item quantity="one">太好了!掃瞄頻道時找到 %1$d 個頻道。如果掃瞄結果看來不正確,請嘗試調整天線位置並重新掃瞄。</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"完成"</item>
<item msgid="496688122303154468">"重新掃瞄"</item>
diff --git a/usbtuner/res/values-zh-rTW/strings.xml b/usbtuner/res/values-zh-rTW/strings.xml
index 3c9d1762..b6c83e5d 100644
--- a/usbtuner/res/values-zh-rTW/strings.xml
+++ b/usbtuner/res/values-zh-rTW/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"USB 頻道調諧器設定"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"這可能需要幾分鐘的時間"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"找到 %1$d 個頻道"</item>
- <item quantity="other" msgid="7340557317633613">"找到 %1$d 個頻道"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="other">找到 %1$d 個頻道</item>
+ <item quantity="one">找到 %1$d 個頻道</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"停止頻道掃描"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"找到 %1$d 個頻道"</item>
- <item quantity="other" msgid="4331542666115153576">"找到 %1$d 個頻道"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"太好了!頻道掃描作業結束後找到 %1$d 個頻道。如果數量不太正確,請嘗試調整天線的位置,然後再掃描一次。"</item>
- <item quantity="other" msgid="8098777464551209564">"太好了!頻道掃描作業結束後找到 %1$d 個頻道。如果數量不太正確,請嘗試調整天線的位置,然後再掃描一次。"</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="other">找到 %1$d 個頻道</item>
+ <item quantity="one">找到 %1$d 個頻道</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="other">太好了!頻道掃描作業結束後找到 %1$d 個頻道。如果數量不太正確,請嘗試調整天線的位置,然後再掃描一次。</item>
+ <item quantity="one">太好了!頻道掃描作業結束後找到 %1$d 個頻道。如果數量不太正確,請嘗試調整天線的位置,然後再掃描一次。</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"完成"</item>
<item msgid="496688122303154468">"重新掃描"</item>
diff --git a/usbtuner/res/values-zu/strings.xml b/usbtuner/res/values-zu/strings.xml
index 2d29211a..6373234a 100644
--- a/usbtuner/res/values-zu/strings.xml
+++ b/usbtuner/res/values-zu/strings.xml
@@ -50,19 +50,19 @@
</string-array>
<string name="ut_channel_scan" msgid="5275436876483779315">"Ukusetha kweshuna yesiteshi se-USB"</string>
<string name="ut_channel_scan_time" msgid="5108578893396614867">"Lokhu kungathatha amaminithi athile"</string>
- <plurals name="ut_channel_scan_message">
- <item quantity="one" msgid="4648415957579494291">"%1$d isiteshi esitholakele"</item>
- <item quantity="other" msgid="7340557317633613">"%1$d iziteshi ezitholakele"</item>
- </plurals>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="8883404542863956040">
+ <item quantity="one">%1$d iziteshi ezitholakele</item>
+ <item quantity="other">%1$d iziteshi ezitholakele</item>
+ </plurals>
<string name="ut_stop_channel_scan" msgid="8358794117343664624">"MISA UKUSKENA KWESITESHI"</string>
- <plurals name="ut_result_found_title">
- <item quantity="one" msgid="5609704543525317852">"%1$d isiteshi esitholakele"</item>
- <item quantity="other" msgid="4331542666115153576">"%1$d iziteshi ezitholakele"</item>
- </plurals>
- <plurals name="ut_result_found_description">
- <item quantity="one" msgid="3464139901043217695">"Kuhle! Isiteshi se-%1$d sitholwe ngesikhathi sokuskenwa kwesiteshi. Uma lokhu kungabonakali kulungile,"</item>
- <item quantity="other" msgid="8098777464551209564">"Kuhle! Iziteshi ezingu-%1$d zitholakele ngesikhathi sokuskena isiteshi. Uma lokhu kungabukeki kulungile, zama ukulungisa ukuma kwe-antenna uphinde uskene futhi."</item>
- </plurals>
+ <plurals name="ut_result_found_title" formatted="false" msgid="4621251784881527371">
+ <item quantity="one">%1$d iziteshi ezitholakele</item>
+ <item quantity="other">%1$d iziteshi ezitholakele</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="1946474144459881182">
+ <item quantity="one">Kuhle! %1$d iziteshi ezitholakele ngesikhathi sokuskena kwesiteshi. Uma lokhu kungabonakali kulungile, zama ukulungisa ukuma kwe-antenna uphinde uskene futhi.</item>
+ <item quantity="other">Kuhle! %1$d iziteshi ezitholakele ngesikhathi sokuskena kwesiteshi. Uma lokhu kungabonakali kulungile, zama ukulungisa ukuma kwe-antenna uphinde uskene futhi.</item>
+ </plurals>
<string-array name="ut_result_found_choices">
<item msgid="979481834388007277">"Kwenziwe"</item>
<item msgid="496688122303154468">"Skena futhi"</item>
diff --git a/usbtuner/res/values/dimens.xml b/usbtuner/res/values/dimens.xml
index 100ff570..0a09b062 100644
--- a/usbtuner/res/values/dimens.xml
+++ b/usbtuner/res/values/dimens.xml
@@ -52,7 +52,6 @@
<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_icon_margin_right_for_button">21dp</dimen>
<dimen name="ut_scan_title_text_size">34sp</dimen>
<dimen name="ut_scan_title_margin_top">178dp</dimen>
diff --git a/usbtuner/res/xml/ut_tvinputservice.xml b/usbtuner/res/xml/ut_tvinputservice.xml
index 9029da5b..039d848f 100644
--- a/usbtuner/res/xml/ut_tvinputservice.xml
+++ b/usbtuner/res/xml/ut_tvinputservice.xml
@@ -34,4 +34,4 @@
-->
<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
- android:setupActivity="com.android.usbtuner.TunerSetupActivity" />
+ android:setupActivity="com.android.usbtuner.setup.TunerSetupActivity" />
diff --git a/usbtuner/src/com/android/usbtuner/ChannelScanFileParser.java b/usbtuner/src/com/android/usbtuner/ChannelScanFileParser.java
index 989bdaf0..ef9d8425 100644
--- a/usbtuner/src/com/android/usbtuner/ChannelScanFileParser.java
+++ b/usbtuner/src/com/android/usbtuner/ChannelScanFileParser.java
@@ -66,7 +66,7 @@ public class ChannelScanFileParser {
public static List<ScanChannel> parseScanFile(InputStream is) {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
- List<ScanChannel> scanChannelList = new ArrayList<ScanChannel>();
+ List<ScanChannel> scanChannelList = new ArrayList<>();
try {
while ((line = in.readLine()) != null) {
if (line.isEmpty()) {
diff --git a/usbtuner/src/com/android/usbtuner/DvbDeviceAccessor.java b/usbtuner/src/com/android/usbtuner/DvbDeviceAccessor.java
index 024fab37..61185f59 100644
--- a/usbtuner/src/com/android/usbtuner/DvbDeviceAccessor.java
+++ b/usbtuner/src/com/android/usbtuner/DvbDeviceAccessor.java
@@ -23,6 +23,8 @@ import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.util.Log;
+import com.android.tv.common.recording.RecordingCapability;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
@@ -111,10 +113,28 @@ public class DvbDeviceAccessor {
return null;
}
+ /**
+ * Returns the current recording capability for USB tuner.
+ * @param inputId the input id to use.
+ */
+ public RecordingCapability getRecordingCapability(String inputId) {
+ List<DvbDeviceInfoWrapper> deviceList = getDvbDeviceList();
+ // TODO(DVR) implement accurate capabilities and updating values when needed.
+ return RecordingCapability.builder()
+ .setInputId(inputId)
+ .setMaxConcurrentPlayingSessions(1)
+ .setMaxConcurrentTunedSessions(deviceList.size())
+ .setMaxConcurrentSessionsOfAllTypes(deviceList.size() + 1)
+ .build();
+ }
+
public static class DvbDeviceInfoWrapper implements Comparable<DvbDeviceInfoWrapper> {
private static Method sGetAdapterIdMethod;
private static Method sGetDeviceIdMethod;
private final Object mDvbDeviceInfo;
+ private final int mAdapterId;
+ private final int mDeviceId;
+ private final long mId;
static {
try {
@@ -132,13 +152,20 @@ public class DvbDeviceAccessor {
public DvbDeviceInfoWrapper(Object dvbDeviceInfo) {
mDvbDeviceInfo = dvbDeviceInfo;
+ mAdapterId = initAdapterId();
+ mDeviceId = initDeviceId();
+ mId = (((long) getAdapterId()) << 32) | (getDeviceId() & 0xffffffffL);
}
public long getId() {
- return (((long) getAdapterId()) << 32) | (getDeviceId() & 0xffffffffL);
+ return mId;
}
public int getAdapterId() {
+ return mAdapterId;
+ }
+
+ private int initAdapterId() {
try {
return (int) sGetAdapterIdMethod.invoke(mDvbDeviceInfo);
} catch (InvocationTargetException e) {
@@ -150,6 +177,10 @@ public class DvbDeviceAccessor {
}
public int getDeviceId() {
+ return mDeviceId;
+ }
+
+ private int initDeviceId() {
try {
return (int) sGetDeviceIdMethod.invoke(mDvbDeviceInfo);
} catch (InvocationTargetException e) {
diff --git a/usbtuner/src/com/android/usbtuner/FileDataSource.java b/usbtuner/src/com/android/usbtuner/FileDataSource.java
index 0fdaa2bf..163d1048 100644
--- a/usbtuner/src/com/android/usbtuner/FileDataSource.java
+++ b/usbtuner/src/com/android/usbtuner/FileDataSource.java
@@ -304,9 +304,6 @@ public class FileDataSource extends MediaDataSource implements InputStreamSource
public void close() {}
@Override
- public void release() {}
-
- @Override
public int getType() {
return Channel.TYPE_FILE;
}
diff --git a/usbtuner/src/com/android/usbtuner/InputStreamSource.java b/usbtuner/src/com/android/usbtuner/InputStreamSource.java
index 5f14f590..12587d9a 100644
--- a/usbtuner/src/com/android/usbtuner/InputStreamSource.java
+++ b/usbtuner/src/com/android/usbtuner/InputStreamSource.java
@@ -23,7 +23,7 @@ import com.android.usbtuner.data.TunerChannel;
* Interface definition for stream source. Source based on physical tuner or files should implement
* this interface.
*/
-public interface InputStreamSource {
+public interface InputStreamSource extends AutoCloseable {
/**
* @return a type of the source. Either {@code TYPE_TUNER} or {@code TYPE_FILE}.
*/
@@ -70,9 +70,4 @@ public interface InputStreamSource {
* @return the position of a input source
*/
long getPosition();
-
- /**
- * Release all the resources related to stream source.
- */
- void release();
}
diff --git a/usbtuner/src/com/android/usbtuner/InternalTunerHal.java b/usbtuner/src/com/android/usbtuner/InternalTunerHal.java
new file mode 100644
index 00000000..50832aae
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/InternalTunerHal.java
@@ -0,0 +1,57 @@
+/*
+ * 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.usbtuner;
+
+import android.content.Context;
+
+/**
+ * A class to handle one internal tuner device.
+ */
+public class InternalTunerHal extends TunerHal {
+
+ private boolean isDeviceOpen;
+
+ protected InternalTunerHal(Context context) {
+ super(context);
+ isDeviceOpen = false;
+ }
+
+ @Override
+ protected boolean openFirstAvailable() {
+ isDeviceOpen = true;
+ return true;
+ }
+
+ @Override
+ public void close() {
+ if (isStreaming()) {
+ stopTune();
+ }
+ nativeFinalize(getDeviceId());
+ isDeviceOpen = false;
+ }
+
+ @Override
+ protected boolean isDeviceOpen() {
+ return (isDeviceOpen);
+ }
+
+ @Override
+ protected long getDeviceId() {
+ return 0L;
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/SetupGuidedStepFragment.java b/usbtuner/src/com/android/usbtuner/SetupGuidedStepFragment.java
deleted file mode 100644
index b8f26d42..00000000
--- a/usbtuner/src/com/android/usbtuner/SetupGuidedStepFragment.java
+++ /dev/null
@@ -1,543 +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.usbtuner;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-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.GuidedActionsStylist;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A customized GuidedStepFragment for setup UI.
- */
-public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
-
- // Used from {@link GuidedStepFragment#getCurrentGuidedStepFragment}.
- // String from {@link GuidedStepFragment}
- private static final String FRAGMENT_TAG = "leanBackGuidedStepFragment";
-
- public static void addSetupFragment(FragmentManager fm, SetupGuidedStepFragment f,
- boolean isTop) {
- int id = android.R.id.content;
-
- FragmentTransaction ft = fm.beginTransaction();
- if (!isTop) {
- ft.addToBackStack(null);
- }
- ft.replace(id, f, FRAGMENT_TAG).commit();
- }
-
- // Create Animator without target View.
- private static class UntargetableAnimatorSet extends Animator {
-
- private final AnimatorSet mAnimatorSet;
-
- UntargetableAnimatorSet(AnimatorSet animatorSet) {
- mAnimatorSet = animatorSet;
- }
-
- @Override
- public void addListener(Animator.AnimatorListener listener) {
- mAnimatorSet.addListener(listener);
- }
-
- @Override
- public void cancel() {
- mAnimatorSet.cancel();
- }
-
- @Override
- public Animator clone() {
- return mAnimatorSet.clone();
- }
-
- @Override
- public void end() {
- mAnimatorSet.end();
- }
-
- @Override
- public long getDuration() {
- return mAnimatorSet.getDuration();
- }
-
- @Override
- public ArrayList<Animator.AnimatorListener> getListeners() {
- return mAnimatorSet.getListeners();
- }
-
- @Override
- public long getStartDelay() {
- return mAnimatorSet.getStartDelay();
- }
-
- @Override
- public boolean isRunning() {
- return mAnimatorSet.isRunning();
- }
-
- @Override
- public boolean isStarted() {
- return mAnimatorSet.isStarted();
- }
-
- @Override
- public void removeAllListeners() {
- mAnimatorSet.removeAllListeners();
- }
-
- @Override
- public void removeListener(Animator.AnimatorListener listener) {
- mAnimatorSet.removeListener(listener);
- }
-
- @Override
- public Animator setDuration(long duration) {
- return mAnimatorSet.setDuration(duration);
- }
-
- @Override
- public void setInterpolator(TimeInterpolator value) {
- mAnimatorSet.setInterpolator(value);
- }
-
- @Override
- public void setStartDelay(long startDelay) {
- mAnimatorSet.setStartDelay(startDelay);
- }
-
- @Override
- public void setTarget(Object target) {
- // ignore
- }
-
- @Override
- public void setupEndValues() {
- mAnimatorSet.setupEndValues();
- }
-
- @Override
- public void setupStartValues() {
- mAnimatorSet.setupStartValues();
- }
-
- @Override
- public void start() {
- mAnimatorSet.start();
- }
- }
-
- private static Animator createDummyAnimator(List<Animator> animators) {
- final AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(animators);
- return new UntargetableAnimatorSet(animatorSet);
- }
-
- private static Animator createActionAnimator(final View v, List<Animator> animators) {
- final AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playSequentially(animators);
- animatorSet.setTarget(v);
- return animatorSet;
- }
-
- private static Animator createAnimator(View v, int resId) {
- Animator animator = AnimatorInflater.loadAnimator(v.getContext(), resId);
- animator.setTarget(v);
- return animator;
- }
-
- private static void addActionsAnimator(VerticalGridView view, int beforeId, int resId,
- int delay, @NonNull List<Animator> animators) {
- if (view != null) {
- int count = 0;
- int childCount = view.getAdapter().getItemCount();
- Context ctx = view.getContext();
-
- // Enumerate visible actions item and construct animations for them.
- for (int i = 0; i < childCount; ++i) {
- RecyclerView.ViewHolder viewHolder = view.findViewHolderForPosition(i);
- if( viewHolder!= null) {
- ArrayList<Animator> childAnimators = new ArrayList<>();
-
- View childView = viewHolder.itemView;
- Animator animator;
- animator = AnimatorInflater.loadAnimator(ctx, beforeId);
- animator.setDuration(count * delay);
- childAnimators.add(animator);
-
- animator = AnimatorInflater.loadAnimator(ctx, resId);
- childAnimators.add(animator);
-
- Animator lastAnimator = createActionAnimator(childView, childAnimators);
- animators.add(lastAnimator);
-
- count++;
- }
- }
- }
- }
-
- private static class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
- private final int mVerticalSpaceHeight;
-
- public VerticalSpaceItemDecoration(int mVerticalSpaceHeight) {
- this.mVerticalSpaceHeight = mVerticalSpaceHeight;
- }
-
- @Override
- public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
- RecyclerView.State state) {
- if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
- outRect.bottom = mVerticalSpaceHeight;
- }
- }
- }
-
- private class SetupGuidedActionsStylist extends GuidedActionsStylist {
-
- @Override
- public View onCreateView(LayoutInflater inflater, final ViewGroup container) {
- View view = super.onCreateView(inflater, container);
-
- // Change default scroll behaviour of the actions view.
- mActionsGridView.addItemDecoration(new VerticalSpaceItemDecoration(view.getContext()
- .getResources().getInteger(R.integer.ut_guidedactions_vertical_spcae)));
- mActionsGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
- mActionsGridView.setWindowAlignmentOffsetPercent(
- VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
- mActionsGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
- return view;
- }
-
- @Override
- public int onProvideLayoutId() {
- return R.layout.ut_guidedactions;
- }
-
- public void onSetupFragmentEnter(@NonNull List<Animator> animators) {
- addActionsAnimator(mActionsGridView, R.animator.setup_before_entry,
- R.animator.setup_entry, 50, animators);
- }
-
- public void onSetupFragmentExit(@NonNull List<Animator> animators) {
- addActionsAnimator(mActionsGridView, R.animator.setup_before_exit,
- R.animator.setup_exit, 50, animators);
- }
- }
-
- private class SetupGuidanceStylist extends GuidanceStylist {
- @Override
- public int onProvideLayoutId() {
- return R.layout.ut_guidance;
- }
-
- public void onSetupFragmentEnter(@NonNull List<Animator> animators) {
- animators.add(createAnimator(getTitleView(), R.animator.setup_entry));
- animators.add(createAnimator(getDescriptionView(), R.animator.setup_entry));
- animators.add(createAnimator(getBreadcrumbView(), R.animator.setup_entry));
- }
-
- public void onSetupFragmentExit(@NonNull List<Animator> animators) {
- animators.add(createAnimator(getTitleView(), R.animator.setup_exit));
- animators.add(createAnimator(getDescriptionView(), R.animator.setup_exit));
- animators.add(createAnimator(getBreadcrumbView(), R.animator.setup_exit));
- }
- }
-
- public void addDefaultAction(List<GuidedAction> actions, long id, String title) {
- GuidedAction.Builder builder = new GuidedAction.Builder()
- .id(id)
- .title(title);
- actions.add(builder.build());
- }
-
- public void addIntentAction(List<GuidedAction> actions, long id, Class cls, String title) {
- GuidedAction.Builder builder = new GuidedAction.Builder()
- .id(id)
- .intent(new Intent(getActivity(), cls))
- .title(title);
- actions.add(builder.build());
- }
-
- public void addBooleanSetupAction(List<GuidedAction> actions, long id, boolean value,
- int titleRes) {
- GuidedAction.Builder builder = new GuidedAction.Builder()
- .id(id)
- .title(getString(titleRes))
- .description(getString(value ? R.string.ut_setup_on : R.string.ut_setup_off));
- actions.add(builder.build());
- }
-
- public void addCheckedAction(List<GuidedAction> actions, long id, Class cls, String title,
- boolean checked) {
- actions.add(new GuidedAction.Builder()
- .id(id)
- .intent(new Intent(getActivity(), cls))
- .title(title)
- .checkSetId(GuidedAction.DEFAULT_CHECK_SET_ID)
- .checked(checked)
- .build());
- }
-
- public void updateGuidanceTitle(String title) {
- GuidanceStylist stylist = getGuidanceStylist();
- if (stylist != null) {
- TextView view = stylist.getTitleView();
- if (view != null) {
- view.setText(title);
- }
- }
- }
-
- public void updateGuidanceDescription(String description) {
- GuidanceStylist stylist = getGuidanceStylist();
- if (stylist != null) {
- TextView view = stylist.getDescriptionView();
- if (view != null) {
- view.setText(description);
- }
- }
- }
-
- public void updateGuidanceBreadcrumb(String breadcrumb) {
- GuidanceStylist stylist = getGuidanceStylist();
- if (stylist != null) {
- TextView view = stylist.getBreadcrumbView();
- if (view != null) {
- view.setText(breadcrumb);
- }
- }
- }
-
- @Override
- protected void onProvideFragmentTransitions() {
- // Disable fragment transition animations.
- }
-
- @Override
- public View onCreateView (LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Override {@link RelativeLayout#LayoutParams} for {@link GuidedStepFragment}
- View view = super.onCreateView(inflater, container, savedInstanceState);
- View frameView = view.findViewById(R.id.content_frame);
- if (frameView instanceof ViewGroup) {
- ((ViewGroup) frameView).setClipChildren(false);
- ((ViewGroup) frameView).setClipToPadding(false);
- frameView.setBackgroundColor(
- view.getContext().getResources().getColor(R.color.ut_guidedstep_background));
- }
- View contentView = view.findViewById(R.id.content_fragment);
- if (contentView instanceof ViewGroup) {
- ((ViewGroup) contentView).setClipChildren(false);
- ((ViewGroup) contentView).setClipToPadding(false);
- RelativeLayout.LayoutParams layoutParams =
- (RelativeLayout.LayoutParams) contentView.getLayoutParams();
- layoutParams.width = view.getContext().getResources()
- .getDimensionPixelSize(R.dimen.ut_guidance_section_width);
- layoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT;
- contentView.setLayoutParams(layoutParams);
- contentView.setPadding(0, 0, 0, 0);
- }
- View actionView = view.findViewById(R.id.action_fragment);
- if (actionView instanceof ViewGroup) {
- ((ViewGroup) actionView).setClipChildren(false);
- ((ViewGroup) actionView).setClipToPadding(false);
- RelativeLayout.LayoutParams layoutParams =
- (RelativeLayout.LayoutParams) actionView.getLayoutParams();
- layoutParams.width = RelativeLayout.LayoutParams.MATCH_PARENT;
- layoutParams.height = RelativeLayout.LayoutParams.MATCH_PARENT;
- actionView.setLayoutParams(layoutParams);
- actionView.setPadding(0, 0, 0, 0);
- }
- return view;
- }
-
- protected void doStartAnimation(View mainView, GuidanceStylist guidanceStylist,
- GuidedActionsStylist actionsStylist) {
- ArrayList<Animator> animators = new ArrayList<>();
- if (guidanceStylist instanceof SetupGuidanceStylist) {
- ((SetupGuidanceStylist)guidanceStylist).onSetupFragmentEnter(animators);
- }
- if (actionsStylist instanceof SetupGuidedActionsStylist) {
- ((SetupGuidedActionsStylist)actionsStylist).onSetupFragmentEnter(animators);
- }
- if (animators.size() > 0) {
- Animator anim = createDummyAnimator(animators);
- anim.setTarget(mainView);
- setHWLayerAnimListenerIfAlpha(mainView, anim);
-
- anim.start();
- }
- }
-
- protected void setStartAnimation() {
- final GuidedActionsStylist actionsStylist = getGuidedActionsStylist();
- final GuidanceStylist guidanceStylist = getGuidanceStylist();
- final VerticalGridView actionsView = actionsStylist.getActionsGridView();
- final View mainView = getView();
- if (actionsView != null) {
- actionsView.getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- actionsView.getViewTreeObserver()
- .removeOnGlobalLayoutListener(this);
- doStartAnimation(mainView, guidanceStylist, actionsStylist);
- }
- });
- }
- }
-
- protected void doExitAnimation(final Runnable onAnimationEnded) {
- ArrayList<Animator> animators = new ArrayList<>();
- final View mainView = getView();
- GuidanceStylist guidanceStylist = getGuidanceStylist();
- GuidedActionsStylist actionsStylist = getGuidedActionsStylist();
- if (guidanceStylist instanceof SetupGuidanceStylist) {
- ((SetupGuidanceStylist)guidanceStylist).onSetupFragmentExit(animators);
- }
- if (actionsStylist instanceof SetupGuidedActionsStylist) {
- ((SetupGuidedActionsStylist)actionsStylist).onSetupFragmentExit(animators);
- }
- if (animators.size() > 0) {
- Animator anim = createDummyAnimator(animators);
- anim.setTarget(mainView);
- setHWLayerAnimListenerIfAlpha(mainView, anim);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- onAnimationEnded.run();
- }
- });
- anim.start();
- }
- }
-
- @Override
- public GuidanceStylist onCreateGuidanceStylist() {
- return (GuidanceStylist)new SetupGuidanceStylist();
- }
-
- @Override
- public GuidedActionsStylist onCreateActionsStylist() {
- return (GuidedActionsStylist) new SetupGuidedActionsStylist();
- }
-
- // Code from {@link FragmentManager#FragmentManagerImpl}
- private static class AnimateOnHWLayerIfNeededListener implements Animator.AnimatorListener {
- private boolean mShouldRunOnHWLayer = false;
- private View mView;
- public AnimateOnHWLayerIfNeededListener(final View v) {
- if (v == null) {
- return;
- }
- mView = v;
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- mShouldRunOnHWLayer = shouldRunOnHWLayer(mView, animation);
- if (mShouldRunOnHWLayer) {
- mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mShouldRunOnHWLayer) {
- mView.setLayerType(View.LAYER_TYPE_NONE, null);
- }
- mView = null;
- animation.removeListener(this);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
-
- }
- }
-
- private static boolean modifiesAlpha(Animator anim) {
- if (anim == null) {
- return false;
- }
- if (anim instanceof ValueAnimator) {
- ValueAnimator valueAnim = (ValueAnimator) anim;
- PropertyValuesHolder[] values = valueAnim.getValues();
- for (PropertyValuesHolder value : values) {
- if (("alpha").equals(value.getPropertyName())) {
- return true;
- }
- }
- } else if (anim instanceof AnimatorSet) {
- List<Animator> animList = ((AnimatorSet) anim).getChildAnimations();
- for (Animator animator : animList) {
- if (modifiesAlpha(animator)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private static boolean shouldRunOnHWLayer(View v, Animator anim) {
- if (v == null || anim == null) {
- return false;
- }
- return v.getLayerType() == View.LAYER_TYPE_NONE
- && v.hasOverlappingRendering()
- && modifiesAlpha(anim);
- }
-
- private void setHWLayerAnimListenerIfAlpha(final View v, Animator anim) {
- if (v == null || anim == null) {
- return;
- }
- if (shouldRunOnHWLayer(v, anim)) {
- anim.addListener(new AnimateOnHWLayerIfNeededListener(v));
- }
- }
-}
diff --git a/usbtuner/src/com/android/usbtuner/TunerHal.java b/usbtuner/src/com/android/usbtuner/TunerHal.java
new file mode 100644
index 00000000..102b60fd
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/TunerHal.java
@@ -0,0 +1,231 @@
+/*
+ * 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.usbtuner;
+
+import android.content.Context;
+import android.support.annotation.IntDef;
+import android.support.annotation.StringDef;
+import android.util.Log;
+
+import com.android.usbtuner.util.TisConfiguration;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A base class to handle a hardware tuner device.
+ */
+public abstract class TunerHal implements AutoCloseable {
+ protected static final String TAG = "TunerHal";
+ protected static final boolean DEBUG = false;
+
+ @IntDef({ FILTER_TYPE_OTHER, FILTER_TYPE_AUDIO, FILTER_TYPE_VIDEO, FILTER_TYPE_PCR })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FilterType {}
+ public static final int FILTER_TYPE_OTHER = 0;
+ public static final int FILTER_TYPE_AUDIO = 1;
+ public static final int FILTER_TYPE_VIDEO = 2;
+ public static final int FILTER_TYPE_PCR = 3;
+
+ @StringDef({ MODULATION_8VSB, MODULATION_QAM256 })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ModulationType {}
+ public static final String MODULATION_8VSB = "8VSB";
+ public static final String MODULATION_QAM256 = "QAM256";
+
+ protected static final int PID_PAT = 0;
+ protected static final int PID_ATSC_SI_BASE = 0x1ffb;
+ 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.
+ private boolean mIsStreaming;
+ private int mFrequency;
+ private String mModulation;
+
+ static {
+ System.loadLibrary("tunertvinput_jni");
+ }
+
+ public static TunerHal getInstance(Context context) {
+ TunerHal tunerHal;
+ if (TisConfiguration.isPackagedWithLiveChannels(context)) {
+ tunerHal = new UsbTunerHal(context);
+ } else {
+ tunerHal = new InternalTunerHal(context);
+ } if (tunerHal.openFirstAvailable()) {
+ return tunerHal;
+ }
+ return null;
+ }
+
+ protected TunerHal(Context context) {
+ mIsStreaming = false;
+ mFrequency = -1;
+ mModulation = null;
+ }
+
+ protected boolean isStreaming() {
+ return mIsStreaming;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ close();
+ }
+
+ protected native void nativeFinalize(long deviceId);
+
+ /**
+ * Acquires the first available tuner device. If there is a tuner device that is available, the
+ * tuner device will be locked to the current instance.
+ *
+ * @return {@code true} if the operation was successful, {@code false} otherwise
+ */
+ protected abstract boolean openFirstAvailable();
+
+ protected abstract boolean isDeviceOpen();
+
+ protected abstract long getDeviceId();
+
+ /**
+ * Sets the tuner channel. This should be called after acquiring a tuner device.
+ *
+ * @param frequency a frequency of the channel to tune to
+ * @param modulation a modulation method of the channel to tune to
+ * @return {@code true} if the operation was successful, {@code false} otherwise
+ */
+ public boolean tune(int frequency, @ModulationType String modulation) {
+ if (!isDeviceOpen()) {
+ Log.e(TAG, "There's no available device");
+ return false;
+ }
+ if (mIsStreaming) {
+ nativeCloseAllPidFilters(getDeviceId());
+ mIsStreaming = false;
+ }
+
+ // When tuning to a new channel in the same frequency, there's no need to stop current tuner
+ // device completely and the only thing necessary for tuning is reopening pid filters.
+ if (mFrequency == frequency && Objects.equals(mModulation, modulation)) {
+ addPidFilter(PID_PAT, FILTER_TYPE_OTHER);
+ addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
+ mIsStreaming = true;
+ return true;
+ }
+ int timeout_ms = modulation.equals(MODULATION_8VSB) ? DEFAULT_VSB_TUNE_TIMEOUT_MS
+ : DEFAULT_QAM_TUNE_TIMEOUT_MS;
+ if (nativeTune(getDeviceId(), frequency, modulation, timeout_ms)) {
+ addPidFilter(PID_PAT, FILTER_TYPE_OTHER);
+ addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
+ mFrequency = frequency;
+ mModulation = modulation;
+ mIsStreaming = true;
+ return true;
+ }
+ return false;
+ }
+
+ protected native boolean nativeTune(long deviceId, int frequency,
+ @ModulationType String modulation, int timeout_ms);
+
+ /**
+ * Sets a pid filter. This should be set after setting a channel.
+ *
+ * @param pid a pid number to be added to filter list
+ * @param filterType a type of pid. Must be one of (FILTER_TYPE_XXX)
+ * @return {@code true} if the operation was successful, {@code false} otherwise
+ */
+ public boolean addPidFilter(int pid, @FilterType int filterType) {
+ if (!isDeviceOpen()) {
+ Log.e(TAG, "There's no available device");
+ return false;
+ }
+ if (pid >= 0 && pid <= 0x1fff) {
+ nativeAddPidFilter(getDeviceId(), pid, filterType);
+ return true;
+ }
+ return false;
+ }
+
+ protected native void nativeAddPidFilter(long deviceId, int pid, @FilterType int filterType);
+ protected native void nativeCloseAllPidFilters(long deviceId);
+
+ /**
+ * Stops current tuning. The tuner device and pid filters will be reset by this call and make
+ * the tuner ready to accept another tune request.
+ */
+ public void stopTune() {
+ if (isDeviceOpen()) {
+ if (mIsStreaming) {
+ nativeCloseAllPidFilters(getDeviceId());
+ }
+ nativeStopTune(getDeviceId());
+ }
+ mIsStreaming = false;
+ mFrequency = -1;
+ mModulation = null;
+ }
+
+ protected native void nativeStopTune(long deviceId);
+
+ /**
+ * This method must be called after {@link TunerHal#tune} and before
+ * {@link TunerHal#stopStreaming}. Writes at most maxSize TS frames in a buffer
+ * provided by the user. The frames employ MPEG encoding.
+ *
+ * @param javaBuffer a buffer to write the video data in
+ * @param javaBufferSize the max amount of bytes to write in this buffer. Usually this number
+ * should be equal to the length of the buffer.
+ * @return the amount of bytes written in the buffer. Note that this value could be 0 if no new
+ * frames have been obtained since the last call.
+ */
+ public int readTsStream(byte[] javaBuffer, int javaBufferSize) {
+ if (isDeviceOpen()) {
+ return nativeWriteInBuffer(getDeviceId(), javaBuffer, javaBufferSize);
+ } else {
+ return 0;
+ }
+ }
+
+ protected native int nativeWriteInBuffer(long deviceId, byte[] javaBuffer, int javaBufferSize);
+
+ /**
+ * Opens Linux DVB frontend device. This method is called from native JNI and used only for
+ * UsbTunerHal.
+ */
+ protected int openDvbFrontEndFd() {
+ return -1;
+ }
+
+ /**
+ * Opens Linux DVB demux device. This method is called from native JNI and used only for
+ * UsbTunerHal.
+ */
+ protected int openDvbDemuxFd() {
+ return -1;
+ }
+
+ /**
+ * Opens Linux DVB dvr device. This method is called from native JNI and used only for
+ * UsbTunerHal.
+ */
+ protected int openDvbDvrFd() {
+ return -1;
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/TunerSetupActivity.java b/usbtuner/src/com/android/usbtuner/TunerSetupActivity.java
deleted file mode 100644
index 81e6d6dd..00000000
--- a/usbtuner/src/com/android/usbtuner/TunerSetupActivity.java
+++ /dev/null
@@ -1,400 +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.usbtuner;
-
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.tv.TvContract;
-import android.media.tv.TvInputInfo;
-import android.os.Bundle;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v4.app.NotificationCompat;
-
-import com.android.tv.common.TvCommonConstants;
-import com.android.tv.common.TvCommonUtils;
-import com.android.usbtuner.tvinput.UsbTunerTvInputService;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.TimeZone;
-
-/**
- * An activity that serves USB tuner setup process.
- */
-public class TunerSetupActivity extends Activity {
- public static final String EXTRA_FOR_CHANNEL_SCAN_FILE = "scan_file_choice";
- public static final String EXTRA_FOR_SCANNED_RESULT = "scanned_count";
-
- // For the recommendation card
- private static final String TV_ACTIVITY_CLASS_NAME = "com.android.tv.TvActivity";
- private static final String NOTIFY_TAG = "UsbTunerSetup";
- 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 ID_SCAN = 1;
-
- // an arbitrary large number in order not to duplicate another action id
- private static final int ID_FINISH_ACTION = 1000;
-
- 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};
- private static final int SETUP_BREADCRUMB = R.string.ut_setup_breadcrumb;
- private static final int[] SETUP_TITLE =
- {R.string.ut_setup_new_title, R.string.ut_setup_again_title};
- private static final int[] SETUP_DESCRIPTION =
- {R.string.ut_setup_new_description, R.string.ut_setup_again_description};
- private static final int[] SETUP_CHOICES =
- {R.array.ut_setup_new_choices, R.array.ut_setup_again_choices};
- private static final int SETUP_FINISH_POSITION = 1;
- private static final int CONNECTION_TITLE = R.string.ut_connection_title;
- private static final int CONNECTION_DESCRIPTION = R.string.ut_connection_description;
- private static final int CONNECTION_CHOICES = R.array.ut_connection_choices;
- private static final int[] SCAN_RESULT_TITLE =
- {R.plurals.ut_result_found_title, R.string.ut_result_not_found_title};
- private static final int[] SCAN_RESULT_DESCRIPTION =
- {R.plurals.ut_result_found_description, R.string.ut_result_not_found_description};
- private static final int[] SCAN_RESULT_CHOICES =
- {R.array.ut_result_found_choices, R.array.ut_result_not_found_choices};
- private static final int[] SCAN_RESULT_RESCAN_POSITION = {1, 0};
-
-
- private int mChannelCountOnPreference;
- private int mChannelScanned;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mChannelCountOnPreference = UsbTunerPreferences
- .getScannedChannelCount(getApplicationContext());
- SetupGuidedStepFragment
- .addSetupFragment(getFragmentManager(), new SetupStepFragment(), true);
- }
-
- /**
- * Finishes the setup activity.
- * <p>
- * If scanning is done, it starts TV app after finishing.
- *
- * @param isScanningDone tells whether scanning is done
- */
- public final void finishSetupStep(boolean isScanningDone) {
- UsbTunerPreferences
- .setScannedChannelCount(getApplicationContext(), mChannelScanned);
- if (!isScanningDone) {
- setResult(Activity.RESULT_CANCELED);
- }
- finish();
- }
-
- private int getSetupIndex() {
- return (mChannelCountOnPreference == 0 && mChannelScanned == 0) ? 0 : 1;
- }
-
- private class SetupStepFragment extends SetupGuidedStepFragment {
- private int mIndex;
-
- public SetupStepFragment() {
- }
-
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- mIndex = getSetupIndex();
- String title = getString(SETUP_TITLE[mIndex]);
- String description = getString(SETUP_DESCRIPTION[mIndex]);
- return new Guidance(title, description, null, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- updateActions(actions);
- }
-
- private void updateActions(List<GuidedAction> actions) {
- updateGuidanceTitle(getString(SETUP_TITLE[mIndex]));
- updateGuidanceDescription(getString(SETUP_DESCRIPTION[mIndex]));
- String[] choices = getResources().getStringArray(SETUP_CHOICES[mIndex]);
- for (int i = 0; i < choices.length; ++i) {
- if (i == SETUP_FINISH_POSITION) {
- addDefaultAction(actions, ID_FINISH_ACTION, choices[i]);
- } else {
- addDefaultAction(actions, i, choices[i]);
- }
- }
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- final int actionId = (int) action.getId();
-
- doExitAnimation(new Runnable() {
- @Override
- public void run() {
- switch (actionId) {
- case ID_FINISH_ACTION:
- // Finishing without scanning
- finishSetupStep(false);
- break;
- default:
- SetupGuidedStepFragment.addSetupFragment(getFragmentManager(),
- new ScanStepFragment(), false);
- break;
- }
- }
- });
- }
-
- @Override
- public void onStart() {
- super.onStart();
- int index = getSetupIndex();
- if (index != mIndex) {
- mIndex = index;
- List<GuidedAction> actions = new ArrayList<>();
- updateActions(actions);
- setActions(actions);
- }
- getGuidedActionsStylist().getActionsGridView().setSelectedPosition(0);
- setStartAnimation();
- }
- }
-
- private class ScanStepFragment extends SetupGuidedStepFragment {
- private final static int INDEX_RESULT_HAS_CHANNELS = 0;
- private final static int INDEX_RESULT_NO_CHANNELS = 1;
- private int mScanChoice = -1;
-
- public ScanStepFragment() {
- }
-
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getString(CONNECTION_TITLE);
- String breadcrumb = getString(SETUP_BREADCRUMB);
- String description = getString(CONNECTION_DESCRIPTION);
- return new Guidance(title, description, breadcrumb, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- updateActions(actions);
- }
-
- private int getResultIndex() {
- return mChannelScanned != 0 ? INDEX_RESULT_HAS_CHANNELS : INDEX_RESULT_NO_CHANNELS;
- }
-
- private String getResultTitle(int index, int result) {
- if (index == INDEX_RESULT_HAS_CHANNELS) {
- // handle plurality.
- return getResources().getQuantityString(SCAN_RESULT_TITLE[index], result, result);
- }
- return getString(SCAN_RESULT_TITLE[index]);
- }
-
- private String getResultDescription(int index, int result) {
- if (index == INDEX_RESULT_HAS_CHANNELS) {
- // handle plurality.
- return getResources()
- .getQuantityString(SCAN_RESULT_DESCRIPTION[index], result, result);
- }
- return getString(SCAN_RESULT_DESCRIPTION[index]);
- }
-
- private void updateActions(List<GuidedAction> actions) {
- if (mScanChoice < 0) {
- String[] choices = getResources().getStringArray(CONNECTION_CHOICES);
- int length = choices.length - 1;
- int startOffset = 0;
- for (int i = 0; i < length; ++i) {
- addIntentAction(actions, startOffset + i, ScanActivity.class, choices[i]);
- }
- } else {
- // Render channel scan result UI.
- int index = getResultIndex();
- updateGuidanceTitle(getResultTitle(index, mChannelScanned));
- updateGuidanceDescription(getResultDescription(index, mChannelScanned));
-
- String[] choices = getResources().getStringArray(SCAN_RESULT_CHOICES[index]);
- for (int i = 0; i < choices.length; ++i) {
- if (SCAN_RESULT_RESCAN_POSITION[index] == i) {
- addIntentAction(actions, mScanChoice, ScanActivity.class, choices[i]);
- } else {
- addDefaultAction(actions, ID_FINISH_ACTION, choices[i]);
- }
- }
- setSelectedActionPosition(0);
- }
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- final int choice = (int) action.getId();
- final Intent intent = action.getIntent();
-
- doExitAnimation(new Runnable() {
- @Override
- public void run() {
- if (mScanChoice >= 0 && choice == ID_FINISH_ACTION) {
- // Finishing after scanning
- finishSetupStep(true);
- } else {
- intent.putExtra(TvInputInfo.EXTRA_INPUT_ID,
- getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID));
- intent.putExtra(EXTRA_FOR_CHANNEL_SCAN_FILE, CHANNEL_MAP_SCAN_FILE[choice]);
- mScanChoice = choice;
- startActivityForResult(intent, (int) ID_SCAN);
- }
- }
- });
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == ID_SCAN) {
- Activity activity = getActivity();
- activity.setResult(resultCode);
- mChannelScanned = data.getIntExtra(EXTRA_FOR_SCANNED_RESULT, 0);
-
- // Cancel a previously shown recommendation card.
- cancelRecommendationCard(getApplicationContext());
-
- // Mark scan as done
- UsbTunerPreferences.setScanDone(getApplicationContext());
-
- // finishing will be done manually.
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- List<GuidedAction> actions = new ArrayList<>();
- updateActions(actions);
- setActions(actions);
- setStartAnimation();
- }
- }
-
- /**
- * A callback to be invoked when the TvInputService is enabled or disabled.
- *
- * @param context a {@link Context} instance
- * @param enabled {@code true} for the {@link UsbTunerTvInputService} to be enabled;
- * otherwise {@code false}
- */
- public static void onTvInputEnabled(Context context, boolean enabled) {
- // Send a recommendation card for USB channel tuner setup
- // if there's no channels and the USB tuner TV input setup has been not done.
- boolean channelScanDoneOnPreference = UsbTunerPreferences.isScanDone(context);
- int channelCountOnPreference = UsbTunerPreferences.getScannedChannelCount(context);
- if (enabled && !channelScanDoneOnPreference && channelCountOnPreference == 0) {
- UsbTunerPreferences.setShouldShowSetupActivity(context, true);
- sendRecommendationCard(context);
- } else {
- UsbTunerPreferences.setShouldShowSetupActivity(context, false);
- cancelRecommendationCard(context);
- }
- }
-
- /**
- * Returns a {@link Intent} to launch the USB tuner TV input service.
- *
- * @param context a {@link Context} instance
- */
- public static Intent createSetupActivity(Context context) {
- String inputId = TvContract.buildInputId(new ComponentName(context.getPackageName(),
- UsbTunerTvInputService.class.getName()));
-
- // Make an intent to launch the setup activity of USB tuner TV input.
- Intent intent = TvCommonUtils.createSetupIntent(
- new Intent(context, TunerSetupActivity.class), inputId);
- intent.putExtra(TvCommonConstants.EXTRA_INPUT_ID, inputId);
- Intent tvActivityIntent = new Intent();
- tvActivityIntent.setComponent(new ComponentName(context, TV_ACTIVITY_CLASS_NAME));
- intent.putExtra(TvCommonConstants.EXTRA_ACTIVITY_AFTER_COMPLETION, tvActivityIntent);
- return intent;
- }
-
- /**
- * Returns a {@link PendingIntent} to launch the USB tuner TV input service.
- *
- * @param context a {@link Context} instance
- */
- private static PendingIntent createPendingIntentForSetupActivity(Context context) {
- return PendingIntent.getActivity(context, 0, createSetupActivity(context),
- PendingIntent.FLAG_UPDATE_CURRENT);
- }
-
- /**
- * Sends the recommendation card to start the USB 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 = resources.getString(R.string.ut_setup_recommendation_card_title);
- Bitmap largeIcon = BitmapFactory.decodeResource(resources,
- R.drawable.recommendation_antenna);
-
- // Build and send the notification.
- Notification notification = new NotificationCompat.BigPictureStyle(
- new NotificationCompat.Builder(context)
- .setAutoCancel(false)
- .setContentTitle(focusedTitle)
- .setContentText(title)
- .setContentInfo(title)
- .setCategory(Notification.CATEGORY_RECOMMENDATION)
- .setLargeIcon(largeIcon)
- .setSmallIcon(resources.getIdentifier(
- TAG_ICON, TAG_DRAWABLE, context.getPackageName()))
- .setContentIntent(createPendingIntentForSetupActivity(context)))
- .build();
- NotificationManager notificationManager = (NotificationManager) context
- .getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.notify(NOTIFY_TAG, NOTIFY_ID, notification);
- }
-
- /**
- * Cancels the previously shown recommendation card.
- *
- * @param context a {@link Context} instance
- */
- private static void cancelRecommendationCard(Context context) {
- NotificationManager notificationManager = (NotificationManager) context
- .getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.cancel(NOTIFY_TAG, NOTIFY_ID);
- }
-}
diff --git a/usbtuner/src/com/android/usbtuner/UsbTunerDataSource.java b/usbtuner/src/com/android/usbtuner/UsbTunerDataSource.java
index 195134be..34558b99 100644
--- a/usbtuner/src/com/android/usbtuner/UsbTunerDataSource.java
+++ b/usbtuner/src/com/android/usbtuner/UsbTunerDataSource.java
@@ -56,14 +56,14 @@ public class UsbTunerDataSource extends MediaDataSource implements InputStreamSo
private boolean mEndOfStreamSent;
private boolean mStreaming;
- private final UsbTunerInterface mUsbTunerInterface;
+ private final TunerHal mTunerHal;
private Thread mStreamingThread;
private boolean mDeviceConfigured;
private EventDetector mEventDetector;
- public UsbTunerDataSource(UsbTunerInterface usbTunerInterface, EventListener eventListener) {
- mUsbTunerInterface = usbTunerInterface;
- mEventDetector = new EventDetector(mUsbTunerInterface, eventListener);
+ public UsbTunerDataSource(TunerHal tunerHal, EventListener eventListener) {
+ mTunerHal = tunerHal;
+ mEventDetector = new EventDetector(mTunerHal, eventListener);
}
/**
@@ -102,17 +102,17 @@ public class UsbTunerDataSource extends MediaDataSource implements InputStreamSo
*/
@Override
public boolean tuneToChannel(TunerChannel channel) {
- if (mUsbTunerInterface.tuneAtsc(channel.getFrequency(), channel.getModulation())) {
+ if (mTunerHal.tune(channel.getFrequency(), channel.getModulation())) {
if (channel.hasVideo()) {
- mUsbTunerInterface.addTunerPidFilter(channel.getVideoPid(),
- UsbTunerInterface.FILTER_TYPE_VIDEO);
+ mTunerHal.addPidFilter(channel.getVideoPid(),
+ TunerHal.FILTER_TYPE_VIDEO);
}
if (channel.hasAudio()) {
- mUsbTunerInterface.addTunerPidFilter(channel.getAudioPid(),
- UsbTunerInterface.FILTER_TYPE_AUDIO);
+ mTunerHal.addPidFilter(channel.getAudioPid(),
+ TunerHal.FILTER_TYPE_AUDIO);
}
- mUsbTunerInterface.addTunerPidFilter(channel.getPcrPid(),
- UsbTunerInterface.FILTER_TYPE_PCR);
+ mTunerHal.addPidFilter(channel.getPcrPid(),
+ TunerHal.FILTER_TYPE_PCR);
if (mEventDetector != null) {
mEventDetector.startDetecting(channel.getFrequency(), channel.getModulation());
}
@@ -167,7 +167,7 @@ public class UsbTunerDataSource extends MediaDataSource implements InputStreamSo
}
}
- int bytesWritten = mUsbTunerInterface.readTsStream(dataBuffer, dataBuffer.length);
+ int bytesWritten = mTunerHal.readTsStream(dataBuffer, dataBuffer.length);
if (bytesWritten <= 0) {
continue;
}
@@ -193,9 +193,6 @@ public class UsbTunerDataSource extends MediaDataSource implements InputStreamSo
}
Log.i(TAG, "Streaming stopped");
-
- // Once the stream stops we perform cleanup with the DVB API.
- mUsbTunerInterface.stopStreaming();
}
}
@@ -262,11 +259,8 @@ public class UsbTunerDataSource extends MediaDataSource implements InputStreamSo
}
@Override
- public void close() {}
-
- @Override
- public void release() {
- mUsbTunerInterface.stopTune();
+ public void close() {
+ mTunerHal.stopTune();
}
@Override
diff --git a/usbtuner/src/com/android/usbtuner/UsbTunerHal.java b/usbtuner/src/com/android/usbtuner/UsbTunerHal.java
new file mode 100644
index 00000000..28ab4ef5
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/UsbTunerHal.java
@@ -0,0 +1,168 @@
+/*
+ * 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.usbtuner;
+
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.support.annotation.IntDef;
+import android.util.Log;
+import com.android.usbtuner.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;
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/UsbTunerInterface.java b/usbtuner/src/com/android/usbtuner/UsbTunerInterface.java
deleted file mode 100644
index cbfed1df..00000000
--- a/usbtuner/src/com/android/usbtuner/UsbTunerInterface.java
+++ /dev/null
@@ -1,312 +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.usbtuner;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.support.annotation.IntDef;
-import android.util.Log;
-
-import com.android.usbtuner.DvbDeviceAccessor.DvbDeviceInfoWrapper;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * An interface to handle a hardware USB tuner device.
- */
-public class UsbTunerInterface {
- private static final String TAG = "UsbTunerInterface";
- private static final boolean DEBUG = false;
-
- @IntDef({FILTER_TYPE_OTHER, FILTER_TYPE_AUDIO, FILTER_TYPE_VIDEO, FILTER_TYPE_PCR})
- @Retention(RetentionPolicy.SOURCE)
- public @interface FilterType {}
- public static final int FILTER_TYPE_OTHER = 0;
- public static final int FILTER_TYPE_AUDIO = 1;
- public static final int FILTER_TYPE_VIDEO = 2;
- public static final int FILTER_TYPE_PCR = 3;
-
- private static final int PID_PAT = 0;
- private static final int PID_ATSC_SI_BASE = 0x1ffb;
- private static final int DEFAULT_VSB_TUNE_TIMEOUT_MS = 2000;
- private static final int DEFAULT_QAM_TUNE_TIMEOUT_MS = 4000; // Some device takes time for
- // QAM256 tuning.
-
- private static final Set<DvbDeviceInfoWrapper> sUsedDvbDevices = new TreeSet<>();
- private static final Object sLock = new Object();
-
- private final DvbDeviceAccessor mDvbDeviceAccessor;
- private boolean mIsStreaming;
- private int mFrequency;
- private String mModulation;
- private DvbDeviceInfoWrapper mDvbDeviceInfo;
-
- static {
- System.loadLibrary("usbtuner_jni");
- }
-
- public UsbTunerInterface(Context context) {
- mDvbDeviceAccessor = new DvbDeviceAccessor(context);
- mIsStreaming = false;
- mFrequency = -1;
- mModulation = null;
- mDvbDeviceInfo = null;
- }
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- close();
- }
-
- private native void nativeFinalize(long deviceId);
-
- /**
- * Acquires the first available tuner device. If there is a tuner device that is available, the
- * tuner device will be locked to the current instance.
- *
- * @return {@code true} if the operation was successful, {@code false} otherwise
- */
- public 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
- */
- public 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;
- }
-
- /**
- * Releases the already acquired tuner device. This should be called after closing the tuner
- * device if it's opened for tuning.
- */
- public void close() {
- if (mDvbDeviceInfo != null) {
- if (mIsStreaming) {
- stopTune();
- }
- nativeFinalize(mDvbDeviceInfo.getId());
- }
- synchronized (sLock) {
- if (mDvbDeviceInfo != null) {
- sUsedDvbDevices.remove(mDvbDeviceInfo);
- }
- }
- mDvbDeviceInfo = null;
- }
-
- /**
- * Sets the tuner channel. This should be called after acquiring a tuner device.
- *
- * @param frequency a frequency of the channel to tune to
- * @param modulation a modulation method of the channel to tune to
- * @return {@code true} if the operation was successful, {@code false} otherwise
- */
- public boolean tuneAtsc(int frequency, String modulation) {
- if (mDvbDeviceInfo == null) {
- Log.e(TAG, "There's no available device");
- return false;
- }
- if (mIsStreaming) {
- nativeCloseAllPidFilters(mDvbDeviceInfo.getId());
- mIsStreaming = false;
- }
-
- // When tuning to a new channel in the same frequency, there's no need to stop current tuner
- // device completely and the only thing necessary for tuning is reopening pid filters.
- if (mFrequency == frequency && Objects.equals(mModulation, modulation)) {
- addTunerPidFilter(PID_PAT, FILTER_TYPE_OTHER);
- addTunerPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
- mIsStreaming = true;
- return true;
- }
- int timeout_ms = modulation.equals("8VSB") ? DEFAULT_VSB_TUNE_TIMEOUT_MS
- : DEFAULT_QAM_TUNE_TIMEOUT_MS;
- if (nativeTuneAtsc(mDvbDeviceInfo.getId(), frequency, modulation, timeout_ms)) {
- addTunerPidFilter(PID_PAT, FILTER_TYPE_OTHER);
- addTunerPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
- mFrequency = frequency;
- mModulation = modulation;
- mIsStreaming = true;
- return true;
- }
- return false;
- }
-
- private native boolean nativeTuneAtsc(long deviceId, int frequency, String modulation,
- int timeout_ms);
-
- /**
- * Sets a pid filter. This should be set after setting a channel.
- *
- * @param pid a pid number to be added to filter list
- * @param filterType a type of pid. Must be one of (FILTER_TYPE_XXX)
- * @return {@code true} if the operation was successful, {@code false} otherwise
- */
- public boolean addTunerPidFilter(int pid, @FilterType int filterType) {
- if (mDvbDeviceInfo == null) {
- Log.e(TAG, "There's no available device");
- return false;
- }
- if (pid >= 0 && pid <= 0x1fff) {
- nativeAddPidFilter(mDvbDeviceInfo.getId(), pid, filterType);
- return true;
- }
- return false;
- }
-
- private native void nativeAddPidFilter(long deviceId, int pid, @FilterType int filterType);
- private native void nativeCloseAllPidFilters(long deviceId);
-
- /**
- * Stops the tuner stream.
- */
- public void stopStreaming() {
- if (mDvbDeviceInfo != null && mIsStreaming) {
- nativeCloseAllPidFilters(mDvbDeviceInfo.getId());
- }
- mIsStreaming = false;
- }
-
- private native void nativeStopTune(long deviceId);
-
- /**
- * This method must be called after {@link UsbTunerInterface#tuneAtsc} and before
- * {@link UsbTunerInterface#stopStreaming}. Writes at most maxSize TS frames in a buffer
- * provided by the user. The frames employ MPEG encoding.
- *
- * @param javaBuffer a buffer to write the video data in
- * @param javaBufferSize the max amount of bytes to write in this buffer. Usually this number
- * should be equal to the length of the buffer.
- * @return the amount of bytes written in the buffer. Note that this value could be 0 if no new
- * frames have been obtained since the last call.
- */
- public int readTsStream(byte[] javaBuffer, int javaBufferSize) {
- if (mDvbDeviceInfo != null) {
- return nativeWriteInBuffer(mDvbDeviceInfo.getId(), javaBuffer, javaBufferSize);
- } else {
- return 0;
- }
- }
-
- private native int nativeWriteInBuffer(long deviceId, byte[] javaBuffer, int javaBufferSize);
-
- // Call from native
- private int openDvbFrontEndFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_FRONTEND);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- private int openDvbDemuxFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DEMUX);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- private int openDvbDvrFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DVR);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- /**
- * Closes the opened tuner device. This method should be called after tuning successfully.
- */
- public void stopTune() {
- if (mDvbDeviceInfo != null) {
- nativeStopTune(mDvbDeviceInfo.getId());
- }
- mIsStreaming = false;
- mFrequency = -1;
- mModulation = null;
- }
-}
diff --git a/usbtuner/src/com/android/usbtuner/UsbTunerPreferences.java b/usbtuner/src/com/android/usbtuner/UsbTunerPreferences.java
index 1434eb24..2f4a4764 100644
--- a/usbtuner/src/com/android/usbtuner/UsbTunerPreferences.java
+++ b/usbtuner/src/com/android/usbtuner/UsbTunerPreferences.java
@@ -19,9 +19,11 @@ package com.android.usbtuner;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.content.SharedPreferences;
import android.database.Cursor;
import com.android.usbtuner.UsbTunerPreferenceProvider.Preferences;
+import com.android.usbtuner.util.TisConfiguration;
/**
* A helper class for the USB tuner preferences.
@@ -32,36 +34,91 @@ public class UsbTunerPreferences {
private static final String PREFS_KEY_SCAN_DONE = "scan_done";
private static final String PREFS_KEY_LAUNCH_SETUP = "launch_setup";
+ private static final String SHARED_PREFS_NAME = "com.android.usbtuner.preferences";
+
+ private static boolean useContentProvider(Context context) {
+ // If TIS is a part of LC, it should use ContentProvider to resolve multiple process access.
+ return TisConfiguration.isPackagedWithLiveChannels(context);
+ }
+
public static int getChannelDataVersion(Context context) {
- return getPreferenceInt(context, PREFS_KEY_CHANNEL_DATA_VERSION);
+ if (useContentProvider(context)) {
+ return getPreferenceInt(context, PREFS_KEY_CHANNEL_DATA_VERSION);
+ } else {
+ return getSharedPreferences(context)
+ .getInt(UsbTunerPreferences.PREFS_KEY_CHANNEL_DATA_VERSION, 0);
+ }
}
public static void setChannelDataVersion(Context context, int version) {
- setPreference(context, PREFS_KEY_CHANNEL_DATA_VERSION, version);
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_CHANNEL_DATA_VERSION, version);
+ } else {
+ getSharedPreferences(context).edit()
+ .putInt(UsbTunerPreferences.PREFS_KEY_CHANNEL_DATA_VERSION, version)
+ .apply();
+ }
}
public static int getScannedChannelCount(Context context) {
- return getPreferenceInt(context, PREFS_KEY_SCANNED_CHANNEL_COUNT);
+ if (useContentProvider(context)) {
+ return getPreferenceInt(context, PREFS_KEY_SCANNED_CHANNEL_COUNT);
+ } else {
+ return getSharedPreferences(context)
+ .getInt(UsbTunerPreferences.PREFS_KEY_SCANNED_CHANNEL_COUNT, 0);
+ }
}
public static void setScannedChannelCount(Context context, int channelCount) {
- setPreference(context, PREFS_KEY_SCANNED_CHANNEL_COUNT, channelCount);
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_SCANNED_CHANNEL_COUNT, channelCount);
+ } else {
+ getSharedPreferences(context).edit()
+ .putInt(UsbTunerPreferences.PREFS_KEY_SCANNED_CHANNEL_COUNT, channelCount)
+ .apply();
+ }
}
public static boolean isScanDone(Context context) {
- return getPreferenceBoolean(context, PREFS_KEY_SCAN_DONE);
+ if (useContentProvider(context)) {
+ return getPreferenceBoolean(context, PREFS_KEY_SCAN_DONE);
+ } else {
+ return getSharedPreferences(context)
+ .getBoolean(UsbTunerPreferences.PREFS_KEY_SCAN_DONE, false);
+ }
}
public static void setScanDone(Context context) {
- setPreference(context, PREFS_KEY_SCAN_DONE, true);
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_SCAN_DONE, true);
+ } else {
+ getSharedPreferences(context).edit()
+ .putBoolean(UsbTunerPreferences.PREFS_KEY_SCAN_DONE, true)
+ .apply();
+ }
}
public static boolean shouldShowSetupActivity(Context context) {
- return getPreferenceBoolean(context, PREFS_KEY_LAUNCH_SETUP);
+ if (useContentProvider(context)) {
+ return getPreferenceBoolean(context, PREFS_KEY_LAUNCH_SETUP);
+ } else {
+ return getSharedPreferences(context)
+ .getBoolean(UsbTunerPreferences.PREFS_KEY_LAUNCH_SETUP, false);
+ }
}
public static void setShouldShowSetupActivity(Context context, boolean need) {
- setPreference(context, PREFS_KEY_LAUNCH_SETUP, need);
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_LAUNCH_SETUP, need);
+ } else {
+ getSharedPreferences(context).edit()
+ .putBoolean(UsbTunerPreferences.PREFS_KEY_LAUNCH_SETUP, need)
+ .apply();
+ }
+ }
+
+ private static SharedPreferences getSharedPreferences(Context context) {
+ return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
}
// Content provider helpers
@@ -72,7 +129,7 @@ public class UsbTunerPreferences {
String[] selectionArgs = new String[] { key };
try (Cursor cursor = resolver.query(UsbTunerPreferenceProvider.buildPreferenceUri(key),
projection, selection, selectionArgs, null)) {
- if (cursor.moveToFirst()) {
+ if (cursor != null && cursor.moveToFirst()) {
return cursor.getString(0);
}
}
diff --git a/usbtuner/src/com/android/usbtuner/UsbTunerTsScannerSource.java b/usbtuner/src/com/android/usbtuner/UsbTunerTsScannerSource.java
index e5788f77..afb1ee31 100644
--- a/usbtuner/src/com/android/usbtuner/UsbTunerTsScannerSource.java
+++ b/usbtuner/src/com/android/usbtuner/UsbTunerTsScannerSource.java
@@ -19,6 +19,7 @@ package com.android.usbtuner;
import android.content.Context;
import android.util.Log;
+import com.android.tv.common.AutoCloseableUtils;
import com.android.usbtuner.ChannelScanFileParser.ScanChannel;
import com.android.usbtuner.data.Channel;
import com.android.usbtuner.data.TunerChannel;
@@ -41,18 +42,18 @@ public class UsbTunerTsScannerSource implements InputStreamSource {
private boolean mStreaming;
- private final UsbTunerInterface mUsbTunerInterface;
+ private final TunerHal mTunerHal;
private Thread mStreamingThread;
private boolean mDeviceConfigured;
private final EventDetector mEventDetector;
private final AtomicLong mBytesFetched = new AtomicLong();
public UsbTunerTsScannerSource(Context context, EventListener eventListener) {
- mUsbTunerInterface = new UsbTunerInterface(context);
- if (!mUsbTunerInterface.openFirstAvailable()) {
+ mTunerHal = TunerHal.getInstance(context);
+ if (mTunerHal == null) {
throw new RuntimeException("Failed to open a DVB device");
}
- mEventDetector = new EventDetector(mUsbTunerInterface, eventListener);
+ mEventDetector = new EventDetector(mTunerHal, eventListener);
}
/**
@@ -74,7 +75,7 @@ public class UsbTunerTsScannerSource implements InputStreamSource {
@Override
public boolean setScanChannel(ScanChannel channel) {
- if (mUsbTunerInterface.tuneAtsc(channel.frequency, channel.modulation)) {
+ if (mTunerHal.tune(channel.frequency, channel.modulation)) {
mEventDetector.startDetecting(channel.frequency, channel.modulation);
mDeviceConfigured = true;
return true;
@@ -119,8 +120,8 @@ public class UsbTunerTsScannerSource implements InputStreamSource {
}
@Override
- public void release() {
- mUsbTunerInterface.close();
+ public void close() {
+ AutoCloseableUtils.closeQuietly(mTunerHal);
}
private class StreamingThread extends Thread {
@@ -135,7 +136,7 @@ public class UsbTunerTsScannerSource implements InputStreamSource {
break;
}
int bytesWritten;
- bytesWritten = mUsbTunerInterface.readTsStream(dataBuffer, dataBuffer.length);
+ bytesWritten = mTunerHal.readTsStream(dataBuffer, dataBuffer.length);
if (bytesWritten <= 0) {
continue;
}
@@ -145,9 +146,6 @@ public class UsbTunerTsScannerSource implements InputStreamSource {
}
Log.i(TAG, "Streaming stopped");
-
- // Once the stream stops we perform cleanup with the DVB API.
- mUsbTunerInterface.stopStreaming();
}
}
diff --git a/usbtuner/src/com/android/usbtuner/data/TunerChannel.java b/usbtuner/src/com/android/usbtuner/data/TunerChannel.java
index 98a8f500..688faf7a 100644
--- a/usbtuner/src/com/android/usbtuner/data/TunerChannel.java
+++ b/usbtuner/src/com/android/usbtuner/data/TunerChannel.java
@@ -33,6 +33,7 @@ import com.google.protobuf.nano.MessageNano;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -95,8 +96,8 @@ public class TunerChannel implements Comparable<TunerChannel>, TvTracksInterface
mProto.frequency = INVALID_FREQUENCY;
mProto.videoPid = INVALID_PID;
mProto.videoStreamType = INVALID_STREAMTYPE;
- List<Integer> audioPids = new ArrayList<Integer>();
- List<Integer> audioStreamTypes = new ArrayList<Integer>();
+ List<Integer> audioPids = new ArrayList<>();
+ List<Integer> audioStreamTypes = new ArrayList<>();
for (PsiData.PmtItem pmt : pmtItems) {
switch (pmt.getStreamType()) {
// MPEG ES stream video types
@@ -299,7 +300,7 @@ public class TunerChannel implements Comparable<TunerChannel>, TvTracksInterface
@Override
public List<AtscAudioTrack> getAudioTracks() {
- return Arrays.asList(mProto.audioTracks);
+ return Collections.unmodifiableList(Arrays.asList(mProto.audioTracks));
}
public void setAudioTracks(List<AtscAudioTrack> audioTracks) {
@@ -308,7 +309,7 @@ public class TunerChannel implements Comparable<TunerChannel>, TvTracksInterface
@Override
public List<AtscCaptionTrack> getCaptionTracks() {
- return Arrays.asList(mProto.captionTracks);
+ return Collections.unmodifiableList(Arrays.asList(mProto.captionTracks));
}
public void setCaptionTracks(List<AtscCaptionTrack> captionTracks) {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/BaseSampleSourceExtractor.java b/usbtuner/src/com/android/usbtuner/exoplayer/BaseSampleSourceExtractor.java
index 9c651cc7..69e44f21 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/BaseSampleSourceExtractor.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/BaseSampleSourceExtractor.java
@@ -33,7 +33,7 @@ import java.io.IOException;
* Base class for feeding samples from a given media extractor using a extractor thread.
*/
public abstract class BaseSampleSourceExtractor implements SampleExtractor {
- private static final String TAG = "BaseSampleSourceExtractor";
+ private static final String TAG = "BaseSampleSourceExt";
// Maximum bandwidth of 1080p channel is about 2.2MB/s. 2MB for a sample will suffice.
private static final int SAMPLE_BUFFER_SIZE = 1024 * 1024 * 2;
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/CacheManager.java b/usbtuner/src/com/android/usbtuner/exoplayer/CacheManager.java
index d686afda..c52a0a44 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/CacheManager.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/CacheManager.java
@@ -353,7 +353,6 @@ public class CacheManager {
*/
public ArrayList<Pair<String, MediaFormat>> readTrackInfoFiles() throws IOException {
ArrayList<Pair<String, MediaFormat>> trackInfos = new ArrayList<>();
- mStorageManager.readTrackInfoFile(false);
try {
trackInfos.add(mStorageManager.readTrackInfoFile(false));
} catch (FileNotFoundException e) {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/CachedSampleSourceExtractor.java b/usbtuner/src/com/android/usbtuner/exoplayer/CachedSampleSourceExtractor.java
index 00df131d..654a9f92 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/CachedSampleSourceExtractor.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/CachedSampleSourceExtractor.java
@@ -18,7 +18,6 @@ package com.android.usbtuner.exoplayer;
import android.media.MediaCodec;
import android.media.MediaDataSource;
-import android.media.MediaExtractor;
import android.os.ConditionVariable;
import android.os.SystemClock;
import android.util.Log;
@@ -41,7 +40,7 @@ import java.util.concurrent.TimeUnit;
*/
public class CachedSampleSourceExtractor extends BaseSampleSourceExtractor implements
CacheManager.EvictListener {
- private static final String TAG = "CachedSampleSourceExtractor";
+ private static final String TAG = "CachedSampleSourceExt";
private static final boolean DEBUG = false;
public static final long CHUNK_DURATION_US = TimeUnit.MILLISECONDS.toMicros(500);
@@ -79,7 +78,7 @@ public class CachedSampleSourceExtractor extends BaseSampleSourceExtractor imple
}
public boolean maybeReadSample() {
- if (!isEmpty() && getEndPositionUs() - getStartPositionUs() > CHUNK_DURATION_US) {
+ if (isDurationGreaterThan(CHUNK_DURATION_US)) {
return false;
}
SampleHolder sample = mCache.maybeReadSample();
@@ -255,8 +254,8 @@ public class CachedSampleSourceExtractor extends BaseSampleSourceExtractor imple
private boolean isLiveLocked(long positionUs) {
Long livePositionUs = null;
for (SampleCache cache : mSampleCaches) {
- if (livePositionUs == null || livePositionUs < cache.getLastWrittenPositionUs()) {
- livePositionUs = cache.getLastWrittenPositionUs();
+ if (livePositionUs == null || livePositionUs < cache.getEndPositionUs()) {
+ livePositionUs = cache.getEndPositionUs();
}
}
return (livePositionUs == null
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/DvrStorageManager.java b/usbtuner/src/com/android/usbtuner/exoplayer/DvrStorageManager.java
index 4afaba55..4ef86e29 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/DvrStorageManager.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/DvrStorageManager.java
@@ -43,7 +43,7 @@ public class DvrStorageManager implements CacheManager.StorageManager {
// Size of minimum reserved storage buffer which will be used to save meta files
// and index files after actual recording finished.
- private static final long MIN_BUFFER_BYTES = 256l * 1024 * 1024;
+ private static final long MIN_BUFFER_BYTES = 256L * 1024 * 1024;
private static final int NO_VALUE = -1;
private static final long NO_VALUE_LONG = -1L;
@@ -84,11 +84,7 @@ public class DvrStorageManager implements CacheManager.StorageManager {
@Override
public boolean hasEnoughBuffer(long pendingDelete) {
- if (mIsRecording) {
- return mCacheDir.getUsableSpace() >= MIN_BUFFER_BYTES;
- } else {
- return true;
- }
+ return !mIsRecording || mCacheDir.getUsableSpace() >= MIN_BUFFER_BYTES;
}
private void readFormatInt(DataInputStream in, MediaFormat format, String key)
@@ -172,7 +168,7 @@ public class DvrStorageManager implements CacheManager.StorageManager {
readFormatByteBuffer(in, format, "csd-" + i);
}
readFormatLong(in, format, MediaFormat.KEY_DURATION);
- return new Pair<String, MediaFormat>(name, format);
+ return new Pair<>(name, format);
}
}
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/MediaCodecVideoTrackRenderer.java b/usbtuner/src/com/android/usbtuner/exoplayer/MediaCodecVideoTrackRenderer.java
index fa66dd86..19a8ff49 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/MediaCodecVideoTrackRenderer.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/MediaCodecVideoTrackRenderer.java
@@ -43,7 +43,7 @@ import java.nio.ByteBuffer;
*/
@TargetApi(16)
public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
- private static final String TAG = "MediaCodecVideoTrackRenderer";
+ private static final String TAG = "MediaCodecVideoTrackRen";
private static final boolean DEBUG = false;
/**
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPassthroughAc3RendererBuilder.java b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPassthroughAc3RendererBuilder.java
index c407b671..971be491 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPassthroughAc3RendererBuilder.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPassthroughAc3RendererBuilder.java
@@ -47,8 +47,10 @@ public class MpegTsPassthroughAc3RendererBuilder implements RendererBuilder {
public void buildRenderers(MpegTsPlayer mpegTsPlayer, MediaDataSource dataSource,
RendererBuilderCallback callback) {
// Build the video and audio renderers.
- SampleSource sampleSource = new DefaultSampleSource(
- new MpegTsSampleSourceExtractor(dataSource, mCacheManager, mCacheListener),
+ SampleExtractor extractor = dataSource == null ?
+ new MpegTsSampleSourceExtractor(mCacheManager, mCacheListener) :
+ new MpegTsSampleSourceExtractor(dataSource, mCacheManager, mCacheListener);
+ SampleSource sampleSource = new DefaultSampleSource(extractor,
mpegTsPlayer.isAc3Playable() ? NUM_TRACKS : NUM_TRACKS - 1);
MediaCodecVideoTrackRenderer videoRenderer =
new MediaCodecVideoTrackRenderer(sampleSource, null, true,
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPlayer.java b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPlayer.java
index af3c3ea6..db47fb90 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPlayer.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsPlayer.java
@@ -133,7 +133,6 @@ public class MpegTsPlayer implements ExoPlayer.Listener,
@PlaybackState private int mLastReportedPlaybackState;
private boolean mLastReportedPlayWhenReady;
- private MediaDataSource mDataSource;
private Surface mSurface;
private InternalRendererBuilderCallback mBuilderCallback;
private TrackRenderer mVideoRenderer;
@@ -161,10 +160,6 @@ public class MpegTsPlayer implements ExoPlayer.Listener,
mCcListener = new MpegTsCcListener();
}
- public void setDataSource(MediaDataSource dataSource) {
- mDataSource = dataSource;
- }
-
public void addListener(Listener listener) {
mListener = listener;
}
@@ -215,7 +210,7 @@ public class MpegTsPlayer implements ExoPlayer.Listener,
pushTrackSelection(type, true);
}
- public void prepare() {
+ public void prepare(MediaDataSource source) {
if (mRendererBuildingState == RENDERER_BUILDING_STATE_BUILT) {
mPlayer.stop();
}
@@ -225,7 +220,7 @@ public class MpegTsPlayer implements ExoPlayer.Listener,
mRendererBuildingState = RENDERER_BUILDING_STATE_BUILDING;
maybeReportPlayerState();
mBuilderCallback = new InternalRendererBuilderCallback();
- mRendererBuilder.buildRenderers(this, mDataSource, mBuilderCallback);
+ mRendererBuilder.buildRenderers(this, source, mBuilderCallback);
}
/* package */ void onRenderers(String[][] trackNames,
@@ -334,10 +329,8 @@ public class MpegTsPlayer implements ExoPlayer.Listener,
}
public boolean isAc3Playable() {
- if (mAudioCapabilities != null) {
- return mAudioCapabilities.supportsEncoding(AudioFormat.ENCODING_AC3);
- }
- return false;
+ return mAudioCapabilities != null
+ && mAudioCapabilities.supportsEncoding(AudioFormat.ENCODING_AC3);
}
public void onAudioUnplayable() {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsSampleSourceExtractor.java b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsSampleSourceExtractor.java
index 74eafbcd..7a6cbf10 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsSampleSourceExtractor.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/MpegTsSampleSourceExtractor.java
@@ -35,6 +35,8 @@ import java.nio.ByteBuffer;
public final class MpegTsSampleSourceExtractor implements SampleExtractor {
public static final String MIMETYPE_TEXT_CEA_708 = "text/cea-708";
+ private static final int CC_BUFFER_SIZE_IN_BYTES = 9600 / 8;
+
private final SampleExtractor mSampleExtractor;
private TrackInfo[] mTrackInfos;
private boolean[] mGotEos;
@@ -46,18 +48,28 @@ public final class MpegTsSampleSourceExtractor implements SampleExtractor {
private long mCea708PresentationTimeUs;
private CcParser mCcParser;
- public MpegTsSampleSourceExtractor(MediaDataSource source, CacheManager cacheManager,
- PlaybackCacheListener cacheListener) {
+ private void init() {
+ mVideoTrackIndex = -1;
+ mCea708TextTrackIndex = -1;
+ mCea708CcBuffer = ByteBuffer.allocate(CC_BUFFER_SIZE_IN_BYTES);
+ mCea708PresentationTimeUs = -1;
+ mCea708TextTrackSelected = false;
+ }
+
+ public MpegTsSampleSourceExtractor(MediaDataSource source,
+ CacheManager cacheManager, PlaybackCacheListener cacheListener) {
if (cacheManager == null || cacheManager.isDisabled()) {
mSampleExtractor = new SimpleSampleSourceExtractor(source, cacheListener);
} else {
mSampleExtractor = new CachedSampleSourceExtractor(source, cacheManager, cacheListener);
}
- mVideoTrackIndex = -1;
- mCea708TextTrackIndex = -1;
- mCea708CcBuffer = ByteBuffer.allocate(9600 / 8);
- mCea708PresentationTimeUs = -1;
- mCea708TextTrackSelected = false;
+ init();
+ }
+
+ public MpegTsSampleSourceExtractor(CacheManager cacheManager,
+ PlaybackCacheListener cacheListener) {
+ mSampleExtractor = new ReplaySampleSourceExtractor(cacheManager, cacheListener);
+ init();
}
@Override
@@ -83,11 +95,10 @@ public final class MpegTsSampleSourceExtractor implements SampleExtractor {
mCea708TextTrackIndex = trackCount;
}
mTrackInfos = new TrackInfo[mCea708TextTrackIndex < 0 ? trackCount : trackCount + 1];
- for (int i = 0; i < trackCount; ++i) {
- mTrackInfos[i] = trackInfos[i];
- }
+ System.arraycopy(trackInfos, 0, mTrackInfos, 0, trackCount);
if (mCea708TextTrackIndex >= 0) {
- mTrackInfos[trackCount] = new TrackInfo(MIMETYPE_TEXT_CEA_708, C.UNKNOWN_TIME_US);
+ mTrackInfos[trackCount] = new TrackInfo(MIMETYPE_TEXT_CEA_708,
+ trackCount > 0 ? mTrackInfos[0].durationUs : C.UNKNOWN_TIME_US);
}
return true;
}
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/RecordSampleSourceExtractor.java b/usbtuner/src/com/android/usbtuner/exoplayer/RecordSampleSourceExtractor.java
index 1cc718cf..fa416c25 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/RecordSampleSourceExtractor.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/RecordSampleSourceExtractor.java
@@ -47,7 +47,7 @@ import java.util.concurrent.TimeUnit;
public class RecordSampleSourceExtractor implements SampleExtractor, CacheManager.EvictListener {
// TODO: Decouple from {@link SampleExtractor}. Handle recording errors properly.
- private static final String TAG = "RecordSampleSourceExtractor";
+ private static final String TAG = "RecordSampleSourceExt";
// Maximum bandwidth of 1080p channel is about 2.2MB/s. 2MB for a sample will suffice.
private static final int SAMPLE_BUFFER_SIZE = 1024 * 1024 * 2;
@@ -71,6 +71,7 @@ public class RecordSampleSourceExtractor implements SampleExtractor, CacheManage
private final PlaybackCacheListener mCacheListener;
private long[] mCacheEndPositionsUs;
+ private volatile long mCacheDurationUs = 0;
private SampleCache[] mSampleCaches;
private final SamplePool mSamplePool;
@@ -123,6 +124,9 @@ public class RecordSampleSourceExtractor implements SampleExtractor, CacheManage
}
sample.data.position(sample.size);
sample.timeUs = mMediaExtractor.getSampleTime();
+ if (sample.timeUs > mCacheDurationUs) {
+ mCacheDurationUs = sample.timeUs;
+ }
sample.flags = mMediaExtractor.getSampleFlags();
mMediaExtractor.advance();
@@ -266,6 +270,7 @@ public class RecordSampleSourceExtractor implements SampleExtractor, CacheManage
Pair<String, android.media.MediaFormat> audio = null, video = null;
for (int i = 0; i < mTrackCount; ++i) {
String mime = mTrackInfos[i].mimeType;
+ mMediaFormat[i].setLong(android.media.MediaFormat.KEY_DURATION, mCacheDurationUs);
if (MimeTypes.isAudio(mime)) {
audio = new Pair<>(getTrackId(i), mMediaFormat[i]);
}
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/ReplaySampleSourceExtractor.java b/usbtuner/src/com/android/usbtuner/exoplayer/ReplaySampleSourceExtractor.java
new file mode 100644
index 00000000..603f1e68
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/ReplaySampleSourceExtractor.java
@@ -0,0 +1,311 @@
+/*
+ * 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.usbtuner.exoplayer;
+
+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.TrackInfo;
+import com.android.usbtuner.tvinput.PlaybackCacheListener;
+
+import junit.framework.Assert;
+
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A class that plays a recorded stream without using {@link MediaExtractor},
+ * since all samples are extracted and stored to the permanent storage already.
+ */
+public class ReplaySampleSourceExtractor implements SampleExtractor, CacheManager.EvictListener {
+ private static final String TAG = "ReplaySampleSourceExt";
+ private static final boolean DEBUG = false;
+
+ public static final long CHUNK_DURATION_US = TimeUnit.MILLISECONDS.toMicros(500);
+
+ private android.media.MediaFormat[] mMediaFormats;
+ private TrackInfo[] mTrackInfos;
+ private String[] mIds;
+
+ private boolean mEos;
+ private boolean mReleased;
+
+
+ private final CacheManager mCacheManager;
+
+ private final PlaybackCacheListener mCacheListener;
+ private CachedSampleQueue[] mPlayingSampleQueues;
+ private final SamplePool mSamplePool = new SamplePool();
+ private long mLastBufferedPositionUs = C.UNKNOWN_TIME_US;
+ private long mCurrentPlaybackPositionUs = 0;
+
+ private class CachedSampleQueue extends SampleQueue {
+ private SampleCache mCache = null;
+
+ public CachedSampleQueue(SamplePool samplePool) {
+ super(samplePool);
+ }
+
+ public void setSource(SampleCache newCache) {
+ for (SampleCache cache = mCache; cache != null; cache = cache.getNext()) {
+ cache.clear();
+ cache.close();
+ }
+ mCache = newCache;
+ for (SampleCache cache = mCache; cache != null; cache = cache.getNext()) {
+ cache.resetRead();
+ }
+ }
+
+ public boolean maybeReadSample() {
+ if (isDurationGreaterThan(CHUNK_DURATION_US)) {
+ return false;
+ }
+ SampleHolder sample = mCache.maybeReadSample();
+ if (sample == null) {
+ if (!mCache.canReadMore()) {
+ if (mCache.getNext() == null) {
+ // reached the end of the recording
+ setEos();
+ return false;
+ } else {
+ mCache.clear();
+ mCache.close();
+ mCache = mCache.getNext();
+ mCache.resetRead();
+ return maybeReadSample();
+ }
+ }
+ return false;
+ } else {
+ queueSample(sample);
+ return true;
+ }
+ }
+
+ public int dequeueSample(SampleHolder sample) {
+ maybeReadSample();
+ return super.dequeueSample(sample);
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ for (SampleCache cache = mCache; cache != null; cache = cache.getNext()) {
+ cache.clear();
+ cache.close();
+ }
+ mCache = null;
+ }
+
+ public long getSourceStartPositionUs() {
+ return mCache == null ? -1 : mCache.getStartPositionUs();
+ }
+ }
+
+ public ReplaySampleSourceExtractor(
+ CacheManager cacheManager, PlaybackCacheListener cacheListener) {
+ mCacheManager = cacheManager;
+ mCacheListener = cacheListener;
+ cacheListener.onCacheStateChanged(true); // Enable trickplay
+ }
+
+ @Override
+ public boolean prepare() throws IOException {
+ ArrayList<Pair<String, android.media.MediaFormat>> trackInfos =
+ mCacheManager.readTrackInfoFiles();
+ if (trackInfos == null || trackInfos.size() <= 0) {
+ return false;
+ }
+ int trackCount = trackInfos.size();
+ mIds = new String[trackCount];
+ mMediaFormats = new android.media.MediaFormat[trackCount];
+ mTrackInfos = new TrackInfo[trackCount];
+ for (int i = 0; i < trackCount; ++i) {
+ Pair<String, android.media.MediaFormat> pair = trackInfos.get(i);
+ mIds[i] = pair.first;
+ mMediaFormats[i] = pair.second;
+
+ // TODO: save this according to recording length
+ long durationUs = mMediaFormats[i].containsKey(android.media.MediaFormat.KEY_DURATION)
+ ? mMediaFormats[i].getLong(android.media.MediaFormat.KEY_DURATION)
+ : C.UNKNOWN_TIME_US;
+ String mime = mMediaFormats[i].getString(android.media.MediaFormat.KEY_MIME);
+ mTrackInfos[i] = new TrackInfo(mime, durationUs);
+ }
+ initOnLoad(trackCount);
+ return true;
+ }
+
+ @Override
+ public TrackInfo[] getTrackInfos() {
+ return mTrackInfos;
+ }
+
+ private void setEos() {
+ mEos = true;
+ }
+
+ public boolean getEos() {
+ return mEos;
+ }
+
+ @Override
+ public void getTrackMediaFormat(int track, MediaFormatHolder mediaFormatHolder) {
+ mediaFormatHolder.format =
+ MediaFormat.createFromFrameworkMediaFormatV16(mMediaFormats[track]);
+ mediaFormatHolder.drmInitData = null;
+ }
+
+ @Override
+ public void release() {
+ if (!mReleased) {
+ cleanUpImpl();
+ }
+ mReleased = true;
+ }
+
+
+ private String getTrackId(int index) {
+ return mIds[index];
+ }
+
+ public void initOnLoad(int trackCount) throws IOException {
+ mPlayingSampleQueues = new CachedSampleQueue[trackCount];
+ for (int i = 0; i < trackCount; i++) {
+ mCacheManager.loadTrackFormStorage(mIds[i], mSamplePool);
+ }
+ }
+
+ @Override
+ public void selectTrack(int index) {
+ if (mPlayingSampleQueues[index] == null) {
+ String trackId = getTrackId(index);
+ mPlayingSampleQueues[index] = new CachedSampleQueue(mSamplePool);
+ mCacheManager.registerEvictListener(trackId, this);
+ seekIndividualTrack(index, mCurrentPlaybackPositionUs);
+ mPlayingSampleQueues[index].maybeReadSample();
+ }
+ }
+
+ @Override
+ public void deselectTrack(int index) {
+ if (mPlayingSampleQueues[index] != null) {
+ mPlayingSampleQueues[index].clear();
+ mPlayingSampleQueues[index] = null;
+ mCacheManager.unregisterEvictListener(getTrackId(index));
+ }
+ }
+
+ @Override
+ public long getBufferedPositionUs() {
+ Long result = null;
+ for (CachedSampleQueue queue : mPlayingSampleQueues) {
+ if (queue == null) {
+ continue;
+ }
+ Long bufferedPositionUs = queue.getEndPositionUs();
+ if (bufferedPositionUs == null) {
+ continue;
+ }
+ if (result == null || result > bufferedPositionUs) {
+ result = bufferedPositionUs;
+ }
+ }
+ if (result == null) {
+ return mLastBufferedPositionUs;
+ } else {
+ return (mLastBufferedPositionUs = result);
+ }
+ }
+
+ @Override
+ public void seekTo(long positionUs) {
+ // Seek video track first
+ for (int i = 0; i < mPlayingSampleQueues.length; ++i) {
+ CachedSampleQueue queue = mPlayingSampleQueues[i];
+ if (queue == null) {
+ continue;
+ }
+ seekIndividualTrack(i, positionUs);
+ if (DEBUG) {
+ Log.d(TAG, "start time = " + queue.getSourceStartPositionUs());
+ }
+ }
+ mLastBufferedPositionUs = positionUs;
+ }
+
+ private void seekIndividualTrack(int index, long positionUs) {
+ CachedSampleQueue queue = mPlayingSampleQueues[index];
+ if (queue == null) {
+ return;
+ }
+ queue.clear();
+ queue.setSource(mCacheManager.getReadFile(getTrackId(index), positionUs));
+ queue.maybeReadSample();
+ }
+
+ @Override
+ public int readSample(int track, SampleHolder sampleHolder) {
+ CachedSampleQueue queue = mPlayingSampleQueues[track];
+ Assert.assertNotNull(queue);
+ queue.maybeReadSample();
+ int result = queue.dequeueSample(sampleHolder);
+ if (result != SampleSource.SAMPLE_READ && getEos()) {
+ return SampleSource.END_OF_STREAM;
+ }
+ return result;
+ }
+
+ public void cleanUpImpl() {
+ mCacheManager.close();
+ for (int i = 0; i < mIds.length; ++i) {
+ mCacheManager.unregisterEvictListener(getTrackId(i));
+ mCacheManager.clearTrack(getTrackId(i));
+ }
+ }
+
+ @Override
+ public boolean continueBuffering(long positionUs) {
+ boolean hasSamples = true;
+ mCurrentPlaybackPositionUs = positionUs;
+ for (CachedSampleQueue queue : mPlayingSampleQueues) {
+ if (queue == null) {
+ continue;
+ }
+ queue.maybeReadSample();
+ if (queue.isEmpty()) {
+ hasSamples = false;
+ }
+ }
+ return hasSamples;
+ }
+
+ // CacheEvictListener
+ // TODO: Remove this. It will not be called.
+ @Override
+ public void onCacheEvicted(String id, long createdTimeMs) {
+ mCacheListener.onCacheStartTimeChanged(
+ createdTimeMs + TimeUnit.MICROSECONDS.toMillis(CHUNK_DURATION_US));
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/SampleCache.java b/usbtuner/src/com/android/usbtuner/exoplayer/SampleCache.java
index 310c8eef..f6c06c12 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/SampleCache.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/SampleCache.java
@@ -41,7 +41,7 @@ public class SampleCache {
private final long mCreatedTimeMs;
private final long mStartPositionUs;
- private long mLastWrittenPositionUs = 0;
+ private long mEndPositionUs = 0;
private SampleCache mNextCache = null;
private final CacheState mCacheState = new CacheState();
private final Handler mIoHandler;
@@ -120,7 +120,6 @@ public class SampleCache {
private final CacheManager.CacheListener mCacheListener;
private final SamplePool mSamplePool;
private final CacheState mCacheState;
- private final long mLastLoadedPosition;
private RandomAccessFile mRaf = null;
private long mWriteOffset = 0;
private long mReadOffset = 0;
@@ -134,35 +133,21 @@ public class SampleCache {
mCacheListener = cacheListener;
mSamplePool = samplePool;
mCacheState = cacheState;
- mLastLoadedPosition = fromFile ? loadFromFile() : -1;
+ if (fromFile) {
+ loadFromFile();
+ }
}
- private long loadFromFile() throws IOException {
+ private void loadFromFile() throws IOException {
// "r" is enough
try (RandomAccessFile raf = new RandomAccessFile(mFile, "r")) {
mWriteFinished = true;
mWriteOffset = raf.length();
mCacheState.setSize(mWriteOffset);
- long offset = 0L, sampleTimeUs;
- int sampleSize, sampleFlags;
-
- // TODO: Save last sampleTimeUs in the indices file to remove this inefficiency.
- do {
- raf.seek(offset);
- sampleSize = raf.readInt();
- sampleFlags = raf.readInt();
- sampleTimeUs = raf.readLong();
- offset += (sampleSize + SAMPLE_HEADER_LENGTH);
- } while (offset < mWriteOffset);
mCacheListener.onWrite(SampleCache.this);
- return sampleTimeUs;
}
}
- public long getLastLoadedPosition() {
- return mLastLoadedPosition;
- }
-
@Override
public boolean handleMessage(Message msg) {
if (mDeleted) {
@@ -330,7 +315,7 @@ public class SampleCache {
protected SampleCache(SamplePool samplePool, File file, long startPositionUs,
long createdTimeMs, CacheManager.CacheListener cacheListener, Looper looper)
throws IOException {
- mLastWrittenPositionUs = mStartPositionUs = startPositionUs;
+ mEndPositionUs = mStartPositionUs = startPositionUs;
mCreatedTimeMs = createdTimeMs;
mIoHandler = new Handler(looper,
new IoHandlerCallback(file, cacheListener, samplePool, mCacheState, false));
@@ -340,10 +325,9 @@ public class SampleCache {
// Constructor of SampleCache which is backed by the given existing file.
protected SampleCache(SamplePool samplePool, File file, long startPositionUs,
CacheManager.CacheListener cacheListener, Looper looper) throws IOException {
- mCreatedTimeMs = mStartPositionUs = startPositionUs;
+ mCreatedTimeMs = mEndPositionUs = mStartPositionUs = startPositionUs;
IoHandlerCallback handlerCallback =
new IoHandlerCallback(file, cacheListener, samplePool, mCacheState, true);
- mLastWrittenPositionUs = handlerCallback.getLastLoadedPosition();
mIoHandler = new Handler(looper, handlerCallback);
}
@@ -375,14 +359,14 @@ public class SampleCache {
throw new IllegalStateException(
"Called writeSample() even though write is already finished");
}
- mLastWrittenPositionUs = sample.timeUs;
+ mEndPositionUs = sample.timeUs;
conditionVariable.close();
mIoHandler.obtainMessage(IoHandlerCallback.MSG_WRITE,
new Object[] { sample, conditionVariable }).sendToTarget();
}
- public long getLastWrittenPositionUs() {
- return mLastWrittenPositionUs;
+ public long getEndPositionUs() {
+ return mEndPositionUs;
}
public long getCreatedTimeMs() {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/SampleQueue.java b/usbtuner/src/com/android/usbtuner/exoplayer/SampleQueue.java
index 44b57c18..47f961bb 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/SampleQueue.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/SampleQueue.java
@@ -57,18 +57,18 @@ public class SampleQueue {
}
}
- public Long getStartPositionUs() {
+ public Long getEndPositionUs() {
if (mQueue.isEmpty()) {
return null;
}
- return mQueue.getFirst().timeUs;
+ return mQueue.getLast().timeUs;
}
- public Long getEndPositionUs() {
+ public boolean isDurationGreaterThan(long durationUs) {
if (mQueue.isEmpty()) {
- return null;
+ return false;
}
- return mQueue.getLast().timeUs;
+ return mQueue.getLast().timeUs - mQueue.getFirst().timeUs > durationUs;
}
public boolean isEmpty() {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/TrickplayStorageManager.java b/usbtuner/src/com/android/usbtuner/exoplayer/TrickplayStorageManager.java
index 6a24ba6e..57af8eba 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/TrickplayStorageManager.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/TrickplayStorageManager.java
@@ -39,7 +39,7 @@ public class TrickplayStorageManager implements CacheManager.StorageManager {
// Copied from android.os.StorageManager
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
- private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500l * 1024 * 1024;
+ private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500L * 1024 * 1024;
private final File mCacheDir;
private final long mMaxCacheSize;
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/Ac3TrackRenderer.java b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/Ac3TrackRenderer.java
index f5e07cb7..0e11b6f2 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/Ac3TrackRenderer.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/Ac3TrackRenderer.java
@@ -87,6 +87,7 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
private final Handler mEventHandler;
private final boolean mIsSoftware;
private final AudioTrackMonitor mMonitor;
+ private final MediaClock mMediaClock;
private MediaFormat mFormat;
private Ac3Decoder mDecoder;
@@ -117,6 +118,7 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
AUDIO_TRACK.restart();
mCodecCounters = new CodecCounters();
mMonitor = new AudioTrackMonitor();
+ mMediaClock = new MediaClock();
}
@Override
@@ -150,17 +152,9 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
@Override
protected void onEnabled(long positionUs, boolean joining) {
- mMonitor.reset(MONITOR_DURATION_MS);
mSource.enable(mTrackIndex, positionUs);
- mSourceStateReady = false;
mDecoder.startDecoder(this);
- mInputStreamEnded = false;
- mOutputStreamEnded = false;
- mPresentationTimeUs = positionUs;
- mPresentationCount = 0;
- mPreviousPositionUs = 0;
- mCurrentPositionUs = Long.MIN_VALUE;
- mInterpolatedTimeUs = Long.MIN_VALUE;
+ seekToInternal(positionUs);
}
@Override
@@ -188,33 +182,40 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
return AUDIO_TRACK.isReady() || (mFormat != null && (mSourceStateReady || mOutputReady));
}
- @Override
- protected void seekTo(long positionUs) {
+ private void seekToInternal(long positionUs) {
mMonitor.reset(MONITOR_DURATION_MS);
- mSource.seekToUs(positionUs);
mSourceStateReady = false;
mInputStreamEnded = false;
mOutputStreamEnded = false;
- AUDIO_TRACK.reset();
- // resetSessionId() will create a new framework AudioTrack instead of reusing old one.
- if (!mIsSoftware) {
- AUDIO_TRACK.resetSessionId();
- }
mPresentationTimeUs = positionUs;
mPresentationCount = 0;
mPreviousPositionUs = 0;
mCurrentPositionUs = Long.MIN_VALUE;
mInterpolatedTimeUs = Long.MIN_VALUE;
+ mMediaClock.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.
+ if (!mIsSoftware) {
+ AUDIO_TRACK.resetSessionId();
+ }
+ seekToInternal(positionUs);
}
@Override
protected void onStarted() {
AUDIO_TRACK.play();
+ mMediaClock.start();
}
@Override
protected void onStopped() {
AUDIO_TRACK.pause();
+ mMediaClock.stop();
}
@Override
@@ -401,7 +402,9 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
@Override
protected long getCurrentPositionUs() {
- if (!AUDIO_TRACK.isEnabled()) {
+ if (!AUDIO_TRACK.isInitialized()) {
+ return mMediaClock.getPositionUs();
+ } if (!AUDIO_TRACK.isEnabled()) {
if (mInterpolatedTimeUs > 0) {
return mInterpolatedTimeUs - ESTIMATED_TRACK_RENDERING_DELAY_US;
}
@@ -409,7 +412,7 @@ public class Ac3TrackRenderer extends TrackRenderer implements Ac3Decoder.Decode
}
long audioTrackCurrentPositionUs = AUDIO_TRACK.getCurrentPositionUs(isEnded());
if (audioTrackCurrentPositionUs == AudioTrack.CURRENT_POSITION_NOT_SET) {
- mPreviousPositionUs = 0l;
+ mPreviousPositionUs = 0L;
if (DEBUG) {
long oldPositionUs = Math.max(mCurrentPositionUs, 0);
long currentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackMonitor.java b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackMonitor.java
index 76363843..fa2250d2 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackMonitor.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackMonitor.java
@@ -105,19 +105,15 @@ public class AudioTrackMonitor {
ptsBuilder.append("PTS received ").append(mSampleCount).append(", ")
.append(totalDuration - sampleDuration).append(' ');
- for (int i = 0; i < mPtsList.size(); ++i) {
- Pair pair = mPtsList.get(i);
- ptsBuilder.append('[').append(pair.first)
- .append(':').append(pair.second).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) {
- StringBuilder sb = new StringBuilder();
- sb.append(mSampleSize);
- sb.append(mCurSampleSize);
- sb.append(mAc3Header);
- Log.d(TAG, "PTS received sample size: " + sb.toString());
+ Log.d(TAG, "PTS received sample size: "
+ + String.valueOf(mSampleSize) + mCurSampleSize + mAc3Header);
}
flush();
}
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackWrapper.java b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackWrapper.java
index 9879ea23..e075dcc0 100644
--- a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackWrapper.java
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/AudioTrackWrapper.java
@@ -70,7 +70,6 @@ public class AudioTrackWrapper {
} else {
mAudioSessionID = mAudioTrack.initialize();
}
- return;
}
public void reset() {
diff --git a/usbtuner/src/com/android/usbtuner/exoplayer/ac3/MediaClock.java b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/MediaClock.java
new file mode 100644
index 00000000..5d28f4ef
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/exoplayer/ac3/MediaClock.java
@@ -0,0 +1,80 @@
+/*
+ * 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.usbtuner.exoplayer.ac3;
+
+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 MediaClock {
+ 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;
+
+ /**
+ * Starts the clock. Does nothing if the clock is already started.
+ */
+ public void start() {
+ if (!mStarted) {
+ mStarted = true;
+ mDeltaUs = elapsedRealtimeMinus(mPositionUs);
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * @return The current position in microseconds.
+ */
+ public long getPositionUs() {
+ return mStarted ? elapsedRealtimeMinus(mDeltaUs) : mPositionUs;
+ }
+
+ private long elapsedRealtimeMinus(long toSubtractUs) {
+ return SystemClock.elapsedRealtime() * 1000 - toSubtractUs;
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/setup/ConnectionTypeFragment.java b/usbtuner/src/com/android/usbtuner/setup/ConnectionTypeFragment.java
new file mode 100644
index 00000000..f5feec2a
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/setup/ConnectionTypeFragment.java
@@ -0,0 +1,82 @@
+/*
+ * 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.usbtuner.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 com.android.tv.common.ui.setup.SetupGuidedStepFragment;
+import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
+import com.android.usbtuner.R;
+
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * A fragment for connection type selection.
+ */
+public class ConnectionTypeFragment extends SetupMultiPaneFragment {
+ public static final String ACTION_CATEGORY =
+ "com.android.usbtuner.setup.ConnectionTypeFragment";
+
+ @Override
+ protected SetupGuidedStepFragment onCreateContentFragment() {
+ return new ContentFragment();
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+
+ @Override
+ protected boolean needsDoneButton() {
+ return false;
+ }
+
+ public static class ContentFragment extends SetupGuidedStepFragment {
+
+ @NonNull
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ return new Guidance(getString(R.string.ut_connection_title),
+ getString(R.string.ut_connection_description),
+ getString(R.string.ut_setup_breadcrumb), null);
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions,
+ Bundle savedInstanceState) {
+ String[] choices = getResources().getStringArray(R.array.ut_connection_choices);
+ int length = choices.length - 1;
+ int startOffset = 0;
+ for (int i = 0; i < length; ++i) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(startOffset + i)
+ .title(choices[i])
+ .build());
+ }
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/ScanActivity.java b/usbtuner/src/com/android/usbtuner/setup/ScanFragment.java
index 2944e5a1..f12738d9 100644
--- a/usbtuner/src/com/android/usbtuner/ScanActivity.java
+++ b/usbtuner/src/com/android/usbtuner/setup/ScanFragment.java
@@ -14,21 +14,20 @@
* limitations under the License.
*/
-package com.android.usbtuner;
+package com.android.usbtuner.setup;
import android.animation.LayoutTransition;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
-import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
@@ -36,12 +35,21 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.tv.common.AutoCloseableUtils;
+import com.android.tv.common.ui.setup.SetupFragment;
+import com.android.usbtuner.ChannelScanFileParser;
import com.android.usbtuner.ChannelScanFileParser.ScanChannel;
+import com.android.usbtuner.FileDataSource;
+import com.android.usbtuner.InputStreamSource;
+import com.android.usbtuner.R;
+import com.android.usbtuner.UsbTunerPreferences;
+import com.android.usbtuner.UsbTunerTsScannerSource;
import com.android.usbtuner.data.Channel;
-import com.android.usbtuner.data.PsipData.EitItem;
+import com.android.usbtuner.data.PsiData;
+import com.android.usbtuner.data.PsipData;
import com.android.usbtuner.data.TunerChannel;
import com.android.usbtuner.tvinput.ChannelDataManager;
-import com.android.usbtuner.tvinput.EventDetector.EventListener;
+import com.android.usbtuner.tvinput.EventDetector;
import junit.framework.Assert;
@@ -49,15 +57,24 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Handles the activity of scanning frequencies in search of available channels and building the
- * lineup.
+ * A fragment for scanning channels.
*/
-public class ScanActivity extends Activity {
- private static final String TAG = "ScanActivity";
+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;
+
+ public static final String ACTION_CATEGORY = "com.android.usbtuner.setup.ScanFragment";
+ public static final int ACTION_CANCEL = 1;
+ public static final int ACTION_FINISH = 2;
+
+ public static final String EXTRA_FOR_CHANNEL_SCAN_FILE = "scan_file_choice";
private static final long CHANNEL_SCAN_SHOW_DELAY_MS = 10000;
private static final long CHANNEL_SCAN_PERIOD_MS = 4000;
+ private static final long SHOW_PROGRESS_DIALOG_DELAY_MS = 300;
// Build channels out of the locally stored TS streams.
private static final boolean SCAN_LOCAL_STREAMS = true;
@@ -67,88 +84,69 @@ public class ScanActivity extends Activity {
private ProgressBar mProgressBar;
private TextView mScanningMessage;
private View mChannelHolder;
- private ListView mChannelList;
private ChannelAdapter mAdapter;
private volatile boolean mChannelListVisible;
private Button mCancelButton;
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mChannelDataManager = new ChannelDataManager(this);
- mChannelDataManager.checkDataVersion(this);
- setContentView(R.layout.ut_channel_scan);
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ mChannelDataManager = new ChannelDataManager(getActivity());
+ mChannelDataManager.checkDataVersion(getActivity());
mAdapter = new ChannelAdapter();
- mProgressBar = (ProgressBar) findViewById(R.id.tune_progress);
- mScanningMessage = (TextView) findViewById(R.id.tune_description);
- mChannelList = (ListView) findViewById(R.id.channel_list);
- mChannelList.setAdapter(mAdapter);
- mChannelList.setOnItemClickListener(null);
- ViewGroup progressHolder = (ViewGroup) findViewById(R.id.progress_holder);
+ mProgressBar = (ProgressBar) view.findViewById(R.id.tune_progress);
+ mScanningMessage = (TextView) view.findViewById(R.id.tune_description);
+ ListView channelList = (ListView) view.findViewById(R.id.channel_list);
+ channelList.setAdapter(mAdapter);
+ channelList.setOnItemClickListener(null);
+ ViewGroup progressHolder = (ViewGroup) view.findViewById(R.id.progress_holder);
LayoutTransition transition = new LayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);
progressHolder.setLayoutTransition(transition);
- mChannelHolder = findViewById(R.id.channel_holder);
- mChannelHolder.setVisibility(View.GONE);
- mCancelButton = (Button) findViewById(R.id.tune_cancel);
- mCancelButton.setOnClickListener(new View.OnClickListener() {
+ mChannelHolder = view.findViewById(R.id.channel_holder);
+ mCancelButton = (Button) view.findViewById(R.id.tune_cancel);
+ mCancelButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- onBackPressed();
+ finishScan(false);
}
});
- startScan(getIntent().getIntExtra(TunerSetupActivity.EXTRA_FOR_CHANNEL_SCAN_FILE, 0));
+ Bundle args = getArguments();
+ startScan(args == null ? 0 : args.getInt(EXTRA_FOR_CHANNEL_SCAN_FILE, 0));
+ return view;
}
@Override
- public void onBackPressed() {
- cancelScan();
+ protected int getLayoutResourceId() {
+ return R.layout.ut_channel_scan;
}
- private void scrollChannelList(boolean down) {
- int start = mChannelList.getFirstVisiblePosition();
- int end = mChannelList.getLastVisiblePosition();
- if (end < 0 || start == end) {
- return;
- }
- int count = mChannelList.getCount();
- int delta = Math.max((end - start) / 2, 1);
- int pos = down ? Math.min(end + delta, count - 1) : Math.max(start - delta, 0);
- mChannelList.smoothScrollToPosition(pos);
+ @Override
+ protected int[] getParentIdsForDelay() {
+ return new int[] {R.id.progress_holder};
}
- @Override
- public boolean dispatchKeyEvent(KeyEvent key) {
- if (key.getAction() == KeyEvent.ACTION_UP && mChannelListVisible) {
- switch(key.getKeyCode()) {
- case KeyEvent.KEYCODE_DPAD_DOWN: {
- scrollChannelList(true);
- return true;
- }
- case KeyEvent.KEYCODE_DPAD_UP: {
- scrollChannelList(false);
- return true;
- }
- }
- }
- return super.dispatchKeyEvent(key);
+ private void startScan(int channelMapId) {
+ mChannelScanTask = new ChannelScanTask(channelMapId);
+ mChannelScanTask.execute();
}
@Override
- public void onDestroy() {
+ public void onDetach() {
// Ensure scan task will stop.
mChannelScanTask.stopScan();
- super.onDestroy();
- }
-
- private void startScan(int channelMapId) {
- mChannelScanTask = new ChannelScanTask(channelMapId);
- mChannelScanTask.execute();
+ super.onDetach();
}
- private void cancelScan() {
+ /**
+ * Finishes the current scan thread. This fragment will be popped after the scan thread ends.
+ *
+ * @param cancel a flag which indicates the scan is canceled or not.
+ */
+ public void finishScan(boolean cancel) {
if (mChannelScanTask != null) {
- mChannelScanTask.stopScan();
+ mChannelScanTask.cancelScan(cancel);
// Notifies a user of waiting to finish the scanning process.
new Handler().postDelayed(new Runnable() {
@@ -156,10 +154,10 @@ public class ScanActivity extends Activity {
public void run() {
mChannelScanTask.showFinishingProgressDialog();
}
- }, 300);
+ }, SHOW_PROGRESS_DIALOG_DELAY_MS);
// Hides the cancel button.
- mCancelButton.setVisibility(View.INVISIBLE);
+ mCancelButton.setEnabled(false);
}
}
@@ -219,29 +217,32 @@ public class ScanActivity extends Activity {
}
}
- private class ChannelScanTask extends AsyncTask<Void, Integer, Void> implements EventListener {
+ private class ChannelScanTask extends AsyncTask<Void, Integer, Void>
+ implements EventDetector.EventListener {
private static final int MAX_PROGRESS = 100;
+ private final Activity mActivity;
private final int mChannelMapId;
- private final UsbTunerTsScannerSource mTunerSource;
- private final FileDataSource mFileSource;
+ private final InputStreamSource mTunerSource;
+ private final InputStreamSource mFileSource;
private final ConditionVariable mConditionStopped;
private List<ScanChannel> mScanChannelList;
+ private boolean mIsCanceled;
private boolean mIsFinished;
private ProgressDialog mFinishingProgressDialog;
public ChannelScanTask(int channelMapId) {
+ mActivity = getActivity();
mChannelMapId = channelMapId;
- mTunerSource = new UsbTunerTsScannerSource(getApplicationContext(), this);
- if (SCAN_LOCAL_STREAMS) {
- mFileSource = new FileDataSource(this);
- }
+ mTunerSource = FAKE_MODE ? new FakeInputStreamSource(this)
+ : new UsbTunerTsScannerSource(mActivity.getApplicationContext(), this);
+ mFileSource = SCAN_LOCAL_STREAMS ? new FileDataSource(this) : null;
mConditionStopped = new ConditionVariable();
}
private void maybeSetChannelListVisible() {
- runOnUiThread(new Runnable() {
+ mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
int channelsFound = mAdapter.getCount();
@@ -257,7 +258,7 @@ public class ScanActivity extends Activity {
}
private void addChannel(final TunerChannel channel) {
- runOnUiThread(new Runnable() {
+ mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.add(channel);
@@ -271,17 +272,25 @@ public class ScanActivity extends Activity {
});
}
- private synchronized void finishScan() {
+ private synchronized void finishStanTask() {
if (!mIsFinished) {
- Intent intent = getIntent();
- intent.putExtra(TunerSetupActivity.EXTRA_FOR_SCANNED_RESULT,
- mChannelDataManager.getScannedChannelCount());
- setResult(Activity.RESULT_OK, intent);
- ScanActivity.this.finish();
mIsFinished = true;
- if (mFinishingProgressDialog != null && mFinishingProgressDialog.isShowing()) {
+ UsbTunerPreferences.setScannedChannelCount(mActivity.getApplicationContext(),
+ mChannelDataManager.getScannedChannelCount());
+ // Cancel a previously shown recommendation card.
+ TunerSetupActivity.cancelRecommendationCard(mActivity.getApplicationContext());
+ // Mark scan as done
+ UsbTunerPreferences.setScanDone(mActivity.getApplicationContext());
+ // finishing will be done manually.
+ if (mFinishingProgressDialog != null) {
mFinishingProgressDialog.dismiss();
}
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ onActionClick(ACTION_CATEGORY, mIsCanceled ? ACTION_CANCEL : ACTION_FINISH);
+ }
+ });
}
}
@@ -293,9 +302,9 @@ public class ScanActivity extends Activity {
FileDataSource.addLocalStreamFiles(mScanChannelList);
}
scanChannels();
- mChannelDataManager.setCurrentVersion(ScanActivity.this);
+ mChannelDataManager.setCurrentVersion(mActivity);
mChannelDataManager.release();
- finishScan();
+ finishStanTask();
return null;
}
@@ -308,6 +317,11 @@ public class ScanActivity extends Activity {
mConditionStopped.open();
}
+ private void cancelScan(boolean cancel) {
+ mIsCanceled = cancel;
+ stopScan();
+ }
+
private void scanChannels() {
if (DEBUG) Log.i(TAG, "Channel scan starting");
mChannelDataManager.notifyScanStarted();
@@ -328,7 +342,7 @@ public class ScanActivity extends Activity {
if (System.currentTimeMillis() > startMs + CHANNEL_SCAN_SHOW_DELAY_MS
&& !mChannelListVisible) {
- maybeSetChannelListVisible();
+ maybeSetChannelListVisible();
}
}
if (mConditionStopped.block(-1)) {
@@ -336,8 +350,8 @@ public class ScanActivity extends Activity {
}
onProgressUpdate(MAX_PROGRESS * i++ / mScanChannelList.size());
}
- mTunerSource.release();
- mFileSource.release();
+ AutoCloseableUtils.closeQuietly(mTunerSource);
+ AutoCloseableUtils.closeQuietly(mFileSource);
mChannelDataManager.notifyScanCompleted();
if (!mConditionStopped.block(-1)) {
publishProgress(MAX_PROGRESS);
@@ -358,7 +372,7 @@ public class ScanActivity extends Activity {
}
@Override
- public void onEventDetected(TunerChannel channel, List<EitItem> items) {
+ public void onEventDetected(TunerChannel channel, List<PsipData.EitItem> items) {
mChannelDataManager.notifyEventDetected(channel, items);
}
@@ -375,10 +389,73 @@ public class ScanActivity extends Activity {
public synchronized void showFinishingProgressDialog() {
// Show a progress dialog to wait for the scanning process if it's not done yet.
- if (!mIsFinished) {
- mFinishingProgressDialog = ProgressDialog.show(ScanActivity.this, "",
- ScanActivity.this.getResources().getString(R.string.ut_setup_cancel), true);
+ if (!mIsFinished && mFinishingProgressDialog == null) {
+ mFinishingProgressDialog = ProgressDialog.show(mActivity, "",
+ getString(R.string.ut_setup_cancel), true, false);
+ }
+ }
+ }
+
+ private static class FakeInputStreamSource implements InputStreamSource {
+ private final EventDetector.EventListener mEventListener;
+ private int mProgramNumber = 0;
+
+ FakeInputStreamSource(EventDetector.EventListener eventListener) {
+ mEventListener = eventListener;
+ }
+
+ @Override
+ public int getType() {
+ return 0;
+ }
+
+ @Override
+ public boolean setScanChannel(ScanChannel channel) {
+ return true;
+ }
+
+ @Override
+ public boolean tuneToChannel(TunerChannel channel) {
+ return false;
+ }
+
+ @Override
+ public void startStream() {
+ if (++mProgramNumber % 2 == 1) {
+ return;
}
+ final String displayNumber = Integer.toString(mProgramNumber);
+ final String name = "Channel-" + mProgramNumber;
+ mEventListener.onChannelDetected(new TunerChannel(mProgramNumber,
+ new ArrayList<PsiData.PmtItem>()) {
+ @Override
+ public String getDisplayNumber() {
+ return displayNumber;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+ }, true);
+ }
+
+ @Override
+ public void stopStream() {
+ }
+
+ @Override
+ public long getLimit() {
+ return 0;
+ }
+
+ @Override
+ public long getPosition() {
+ return 0;
+ }
+
+ @Override
+ public void close() {
}
}
}
diff --git a/usbtuner/src/com/android/usbtuner/setup/ScanResultFragment.java b/usbtuner/src/com/android/usbtuner/setup/ScanResultFragment.java
new file mode 100644
index 00000000..1c32aeb8
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/setup/ScanResultFragment.java
@@ -0,0 +1,123 @@
+/*
+ * 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.usbtuner.setup;
+
+import android.content.res.Resources;
+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.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.usbtuner.R;
+import com.android.usbtuner.UsbTunerPreferences;
+
+import java.util.List;
+
+/**
+ * A fragment for initial screen.
+ */
+public class ScanResultFragment extends SetupMultiPaneFragment {
+ public static final String ACTION_CATEGORY =
+ "com.android.usbtuner.setup.ScanResultFragment";
+
+ /**
+ * An action which moves to previous page when the user presses BACK button.
+ * In some cases, more than one page can be popped out.
+ */
+ public static final int ACTION_BACK_TO_CONNECTION_TYPE = ACTION_DONE - 1;
+
+ @Override
+ protected SetupGuidedStepFragment onCreateContentFragment() {
+ return new ContentFragment();
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+
+ @Override
+ protected boolean needsDoneButton() {
+ return false;
+ }
+
+ public static class ContentFragment extends SetupGuidedStepFragment {
+ private int mChannelCountOnPreference;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mChannelCountOnPreference = UsbTunerPreferences
+ .getScannedChannelCount(getActivity().getApplicationContext());
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @NonNull
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title;
+ String description;
+ String breadcrumb;
+ if (mChannelCountOnPreference > 0) {
+ Resources res = getResources();
+ title = res.getQuantityString(R.plurals.ut_result_found_title,
+ mChannelCountOnPreference, mChannelCountOnPreference);
+ description = res.getQuantityString(R.plurals.ut_result_found_description,
+ mChannelCountOnPreference, mChannelCountOnPreference);
+ breadcrumb = null;
+ } else {
+ title = getString(R.string.ut_result_not_found_title);
+ description = getString(R.string.ut_result_not_found_description);
+ 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[] choices;
+ int doneActionIndex;
+ if (mChannelCountOnPreference > 0) {
+ choices = getResources().getStringArray(R.array.ut_result_found_choices);
+ doneActionIndex = 0;
+ } else {
+ choices = getResources().getStringArray(R.array.ut_result_not_found_choices);
+ doneActionIndex = 1;
+ }
+ for (int i = 0; i < choices.length; ++i) {
+ if (i == doneActionIndex) {
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_DONE)
+ .title(choices[i]).build());
+ } else {
+ actions.add(new GuidedAction.Builder(getActivity()).id(i).title(choices[i])
+ .build());
+ }
+ }
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/setup/TunerSetupActivity.java b/usbtuner/src/com/android/usbtuner/setup/TunerSetupActivity.java
new file mode 100644
index 00000000..a67cc1ea
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/setup/TunerSetupActivity.java
@@ -0,0 +1,242 @@
+/*
+ * 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.usbtuner.setup;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.tv.TvContract;
+import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.view.KeyEvent;
+
+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.usbtuner.R;
+import com.android.usbtuner.UsbTunerPreferences;
+import com.android.usbtuner.tvinput.UsbTunerTvInputService;
+
+/**
+ * An activity that serves USB tuner setup process.
+ */
+public class TunerSetupActivity extends SetupActivity {
+ // For the recommendation card
+ private static final String TV_ACTIVITY_CLASS_NAME = "com.android.tv.TvActivity";
+ private static final String NOTIFY_TAG = "UsbTunerSetup";
+ 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 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};
+
+ private ScanFragment mLastScanFragment;
+
+ @Override
+ protected Fragment onCreateInitialFragment() {
+ SetupFragment fragment = new WelcomeFragment();
+ fragment.setShortDistance(SetupFragment.FRAGMENT_EXIT_TRANSITION
+ | SetupFragment.FRAGMENT_REENTER_TRANSITION);
+ return fragment;
+ }
+
+ @Override
+ protected void executeAction(String category, int actionId) {
+ switch (category) {
+ case WelcomeFragment.ACTION_CATEGORY:
+ switch (actionId) {
+ case SetupMultiPaneFragment.ACTION_DONE:
+ // If the scan was performed, then the result should be OK.
+ 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);
+ break;
+ }
+ }
+ break;
+ case ConnectionTypeFragment.ACTION_CATEGORY:
+ mLastScanFragment = new ScanFragment();
+ Bundle args = new Bundle();
+ args.putInt(ScanFragment.EXTRA_FOR_CHANNEL_SCAN_FILE, CHANNEL_MAP_SCAN_FILE[actionId]);
+ mLastScanFragment.setArguments(args);
+ showFragment(mLastScanFragment, true);
+ break;
+ case ScanFragment.ACTION_CATEGORY:
+ switch (actionId) {
+ case ScanFragment.ACTION_CANCEL:
+ getFragmentManager().popBackStack();
+ break;
+ case ScanFragment.ACTION_FINISH:
+ SetupFragment fragment = new ScanResultFragment();
+ fragment.setShortDistance(SetupFragment.FRAGMENT_EXIT_TRANSITION
+ | SetupFragment.FRAGMENT_REENTER_TRANSITION);
+ showFragment(fragment, true);
+ break;
+ }
+ break;
+ case ScanResultFragment.ACTION_CATEGORY:
+ switch (actionId) {
+ case SetupMultiPaneFragment.ACTION_DONE:
+ setResult(RESULT_OK);
+ finish();
+ break;
+ default:
+ SetupFragment fragment = new ConnectionTypeFragment();
+ fragment.setShortDistance(SetupFragment.FRAGMENT_ENTER_TRANSITION
+ | SetupFragment.FRAGMENT_RETURN_TRANSITION);
+ showFragment(fragment, true);
+ break;
+ }
+ break;
+ }
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ FragmentManager manager = getFragmentManager();
+ int count = manager.getBackStackEntryCount();
+ if (count > 0) {
+ String lastTag = manager.getBackStackEntryAt(count - 1).getName();
+ if (ScanResultFragment.class.getCanonicalName().equals(lastTag) && count >= 2) {
+ // Pops fragment including ScanFragment.
+ manager.popBackStack(manager.getBackStackEntryAt(count - 2).getName(),
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+ return true;
+ } else if (ScanFragment.class.getCanonicalName().equals(lastTag)) {
+ mLastScanFragment.finishScan(true);
+ return true;
+ }
+ }
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ /**
+ * A callback to be invoked when the TvInputService is enabled or disabled.
+ *
+ * @param context a {@link Context} instance
+ * @param enabled {@code true} for the {@link UsbTunerTvInputService} to be enabled;
+ * otherwise {@code false}
+ */
+ public static void onTvInputEnabled(Context context, boolean enabled) {
+ // Send a recommendation card for USB channel tuner setup
+ // if there's no channels and the USB tuner TV input setup has been not done.
+ boolean channelScanDoneOnPreference = UsbTunerPreferences.isScanDone(context);
+ int channelCountOnPreference = UsbTunerPreferences.getScannedChannelCount(context);
+ if (enabled && !channelScanDoneOnPreference && channelCountOnPreference == 0) {
+ UsbTunerPreferences.setShouldShowSetupActivity(context, true);
+ sendRecommendationCard(context);
+ } else {
+ UsbTunerPreferences.setShouldShowSetupActivity(context, false);
+ cancelRecommendationCard(context);
+ }
+ }
+
+ /**
+ * Returns a {@link Intent} to launch the USB tuner TV input service.
+ *
+ * @param context a {@link Context} instance
+ */
+ public static Intent createSetupActivity(Context context) {
+ String inputId = TvContract.buildInputId(new ComponentName(context.getPackageName(),
+ UsbTunerTvInputService.class.getName()));
+
+ // Make an intent to launch the setup activity of USB tuner TV input.
+ Intent intent = TvCommonUtils.createSetupIntent(
+ new Intent(context, TunerSetupActivity.class), inputId);
+ intent.putExtra(TvCommonConstants.EXTRA_INPUT_ID, inputId);
+ Intent tvActivityIntent = new Intent();
+ tvActivityIntent.setComponent(new ComponentName(context, TV_ACTIVITY_CLASS_NAME));
+ intent.putExtra(TvCommonConstants.EXTRA_ACTIVITY_AFTER_COMPLETION, tvActivityIntent);
+ return intent;
+ }
+
+ /**
+ * Returns a {@link PendingIntent} to launch the USB tuner TV input service.
+ *
+ * @param context a {@link Context} instance
+ */
+ private static PendingIntent createPendingIntentForSetupActivity(Context context) {
+ return PendingIntent.getActivity(context, 0, createSetupActivity(context),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ /**
+ * Sends the recommendation card to start the USB 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 = resources.getString(R.string.ut_setup_recommendation_card_title);
+ Bitmap largeIcon = BitmapFactory.decodeResource(resources,
+ R.drawable.recommendation_antenna);
+
+ // Build and send the notification.
+ Notification notification = new NotificationCompat.BigPictureStyle(
+ new NotificationCompat.Builder(context)
+ .setAutoCancel(false)
+ .setContentTitle(focusedTitle)
+ .setContentText(title)
+ .setContentInfo(title)
+ .setCategory(Notification.CATEGORY_RECOMMENDATION)
+ .setLargeIcon(largeIcon)
+ .setSmallIcon(resources.getIdentifier(
+ TAG_ICON, TAG_DRAWABLE, context.getPackageName()))
+ .setContentIntent(createPendingIntentForSetupActivity(context)))
+ .build();
+ NotificationManager notificationManager = (NotificationManager) context
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.notify(NOTIFY_TAG, NOTIFY_ID, notification);
+ }
+
+ /**
+ * Cancels the previously shown recommendation card.
+ *
+ * @param context a {@link Context} instance
+ */
+ public static void cancelRecommendationCard(Context context) {
+ NotificationManager notificationManager = (NotificationManager) context
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.cancel(NOTIFY_TAG, NOTIFY_ID);
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/setup/WelcomeFragment.java b/usbtuner/src/com/android/usbtuner/setup/WelcomeFragment.java
new file mode 100644
index 00000000..c939dd5f
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/setup/WelcomeFragment.java
@@ -0,0 +1,100 @@
+/*
+ * 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.usbtuner.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.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.usbtuner.R;
+import com.android.usbtuner.UsbTunerPreferences;
+
+import java.util.List;
+
+/**
+ * A fragment for initial screen.
+ */
+public class WelcomeFragment extends SetupMultiPaneFragment {
+ public static final String ACTION_CATEGORY =
+ "com.android.usbtuner.setup.WelcomeFragment";
+
+ @Override
+ protected SetupGuidedStepFragment onCreateContentFragment() {
+ return new ContentFragment();
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+
+ @Override
+ protected boolean needsDoneButton() {
+ return false;
+ }
+
+ public static class ContentFragment extends SetupGuidedStepFragment {
+ private int mChannelCountOnPreference;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mChannelCountOnPreference = UsbTunerPreferences
+ .getScannedChannelCount(getActivity().getApplicationContext());
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @NonNull
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title;
+ String description;
+ if (mChannelCountOnPreference == 0) {
+ title = getString(R.string.ut_setup_new_title);
+ description = getString(R.string.ut_setup_new_description);
+ } else {
+ title = getString(R.string.ut_setup_again_title);
+ description = getString(R.string.ut_setup_again_description);
+ }
+ return new Guidance(title, description, null, null);
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions,
+ Bundle savedInstanceState) {
+ String[] choices = getResources().getStringArray(mChannelCountOnPreference == 0
+ ? R.array.ut_setup_new_choices : R.array.ut_setup_again_choices);
+ for (int i = 0; i < choices.length - 1; ++i) {
+ actions.add(new GuidedAction.Builder(getActivity()).id(i).title(choices[i])
+ .build());
+ }
+ actions.add(new GuidedAction.Builder(getActivity()).id(ACTION_DONE)
+ .title(choices[choices.length - 1]).build());
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/ts/TsParser.java b/usbtuner/src/com/android/usbtuner/ts/TsParser.java
index e11bc926..838baad9 100644
--- a/usbtuner/src/com/android/usbtuner/ts/TsParser.java
+++ b/usbtuner/src/com/android/usbtuner/ts/TsParser.java
@@ -17,6 +17,7 @@
package com.android.usbtuner.ts;
import android.util.Log;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.usbtuner.data.PsiData.PatItem;
@@ -49,7 +50,15 @@ public class TsParser {
private static final int TS_PACKET_TEI_MASK = 0x80;
private static final int TS_PACKET_SIZE = 188;
- private final Map<Integer, Stream> mStreamMap = new HashMap<>();
+ /*
+ * Using a SparseArray removes the need to auto box the int key for mStreamMap
+ * in feedTdPacket which is called 100 times a second. This greatly reduces the
+ * number of objects created and the frequency of garbage collection.
+ * Other maps might be suitable for a SparseArray, but the performance
+ * trade offs must be considered carefully.
+ * mStreamMap is the only one called at such a high rate.
+ */
+ private final SparseArray<Stream> mStreamMap = new SparseArray<>();
private final Map<Integer, VctItem> mSourceIdToVctItemMap = new HashMap<>();
private final Map<Integer, String> mSourceIdToVctItemDescriptionMap = new HashMap<>();
private final Map<Integer, VctItem> mProgramNumberToVctItemMap = new HashMap<>();
@@ -187,9 +196,7 @@ public class TsParser {
@Override
public void onVctParsed(List<VctItem> items) {
for (VctItem i : items) {
- if (DEBUG) {
- Log.d(TAG, "onVCTParsed " + i);
- }
+ if (DEBUG) Log.d(TAG, "onVCTParsed " + i);
if (i.getSourceId() != 0) {
mSourceIdToVctItemMap.put(i.getSourceId(), i);
i.setDescription(mSourceIdToVctItemDescriptionMap.get(i.getSourceId()));
@@ -210,9 +217,7 @@ public class TsParser {
@Override
public void onEitParsed(int sourceId, List<EitItem> items) {
- if (DEBUG) {
- Log.d(TAG, "onEITParsed " + sourceId);
- }
+ if (DEBUG) Log.d(TAG, "onEITParsed " + sourceId);
EventSourceEntry entry = new EventSourceEntry(mPid, sourceId);
mEitMap.put(entry, items);
handleEvents(sourceId);
@@ -349,15 +354,15 @@ public class TsParser {
private boolean feedTSPacket(byte[] tsData, int pos) {
if (tsData.length < pos + TS_PACKET_SIZE) {
- Log.d(TAG, "Data should include a single TS packet.");
+ if (DEBUG) Log.d(TAG, "Data should include a single TS packet.");
return false;
}
if (tsData[pos] != TS_PACKET_START_CODE) {
- Log.d(TAG, "Invalid ts packet.");
+ if (DEBUG) Log.d(TAG, "Invalid ts packet.");
return false;
}
if ((tsData[pos + 1] & TS_PACKET_TEI_MASK) != 0) {
- Log.d(TAG, "Erroneous ts packet.");
+ if (DEBUG) Log.d(TAG, "Erroneous ts packet.");
return false;
}
@@ -375,7 +380,7 @@ public class TsParser {
return false;
}
if (payloadPos > pos + TS_PACKET_SIZE) {
- Log.d(TAG, "Payload should be included in a single TS packet.");
+ if (DEBUG) Log.d(TAG, "Payload should be included in a single TS packet.");
return false;
}
stream.feedData(Arrays.copyOfRange(tsData, payloadPos, pos + TS_PACKET_SIZE),
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/BaseTunerTvInputService.java b/usbtuner/src/com/android/usbtuner/tvinput/BaseTunerTvInputService.java
new file mode 100644
index 00000000..cb25cfec
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/tvinput/BaseTunerTvInputService.java
@@ -0,0 +1,113 @@
+/*
+ * 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.usbtuner.tvinput;
+
+import android.os.Handler;
+import android.util.Log;
+import com.google.android.exoplayer.audio.AudioCapabilities;
+import com.google.android.exoplayer.audio.AudioCapabilitiesReceiver;
+import com.android.tv.common.recording.RecordingTvInputService;
+import com.android.tv.common.recording.TvRecording;
+import com.android.usbtuner.exoplayer.CacheManager;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * {@link BaseTunerTvInputService} serves TV channels coming from a usb tuner device.
+ */
+public abstract class BaseTunerTvInputService extends RecordingTvInputService
+ implements AudioCapabilitiesReceiver.Listener {
+ private static final String TAG = "BaseTunerTvInputService";
+ private static final boolean DEBUG = false;
+
+ // WeakContainer for {@link TvInputSessionImpl}
+ private final Set<TvInputSessionImpl> mTvInputSessions = Collections.newSetFromMap(
+ new WeakHashMap<TvInputSessionImpl, Boolean>());
+ private ChannelDataManager mChannelDataManager;
+ private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
+ private AudioCapabilities mAudioCapabilities;
+ protected CacheManager mCacheManager;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (DEBUG) {
+ Log.d(TAG, "onCreate");
+ }
+ mChannelDataManager = new ChannelDataManager(getApplicationContext());
+ mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(getApplicationContext(), this);
+ mAudioCapabilitiesReceiver.register();
+ maybeInitCacheManager();
+ if (mCacheManager == null) {
+ Log.i(TAG, "Trickplay is disabled");
+ } else {
+ Log.i(TAG, "Trickplay is enabled");
+ }
+ }
+
+ protected abstract void maybeInitCacheManager();
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) {
+ Log.d(TAG, "onDestroy");
+ }
+ super.onDestroy();
+ mChannelDataManager.release();
+ mAudioCapabilitiesReceiver.unregister();
+ if (mCacheManager != null) {
+ mCacheManager.close();
+ }
+ }
+
+ @Override
+ public TvRecording.RecordingSession onCreateDvrSession(String inputId) {
+ return new RecordingSessionImpl(this, inputId, mChannelDataManager);
+ }
+
+ @Override
+ public RecordingTvInputService.PlaybackSession onCreatePlaybackSession(String inputId) {
+ if (DEBUG) {
+ Log.d(TAG, "onCreateSession");
+ }
+ final TvInputSessionImpl session = new TvInputSessionImpl(
+ this, mChannelDataManager, mCacheManager);
+ mTvInputSessions.add(session);
+ session.notifyAudioCapabilitiesChanged(mAudioCapabilities);
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ // STOPSHIP(DVR): Session methods cannot be called inside onCreatePlaybackSession.
+ // If DvrSession is added in API. we can call them inside onCreatePlaybackSession.
+ session.setOverlayViewEnabled(true);
+ }
+ });
+ return session;
+ }
+
+ @Override
+ public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) {
+ mAudioCapabilities = audioCapabilities;
+ for (TvInputSessionImpl session : mTvInputSessions) {
+ if (!session.isReleased()) {
+ session.notifyAudioCapabilitiesChanged(audioCapabilities);
+ }
+ }
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/ChannelDataManager.java b/usbtuner/src/com/android/usbtuner/tvinput/ChannelDataManager.java
index 33feacdf..206d8ba4 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/ChannelDataManager.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/ChannelDataManager.java
@@ -36,6 +36,7 @@ import com.android.usbtuner.UsbTunerPreferences;
import com.android.usbtuner.data.PsipData.EitItem;
import com.android.usbtuner.data.TunerChannel;
import com.android.usbtuner.util.ConvertUtils;
+import com.android.usbtuner.util.TisConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
@@ -127,8 +128,14 @@ public class ChannelDataManager implements Handler.Callback {
public ChannelDataManager(Context context) {
mContext = context;
- mInputId = TvContract.buildInputId(new ComponentName(mContext.getPackageName(),
- UsbTunerTvInputService.class.getName()));
+ if (TisConfiguration.isInternalTunerTvInput(context)) {
+ mInputId = TvContract.buildInputId(new ComponentName(mContext.getPackageName(),
+ InternalTunerTvInputService.class.getName())) + "/HW" +
+ TisConfiguration.getTunerHwDeviceId(context);
+ } else {
+ mInputId = TvContract.buildInputId(new ComponentName(mContext.getPackageName(),
+ UsbTunerTvInputService.class.getName()));
+ }
mChannelsUri = TvContract.buildChannelsUriForInput(mInputId);
mTunerChannelMap = new ConcurrentHashMap<>();
mTunerChannelIdMap = new ConcurrentSkipListMap<>();
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImplInternal.java b/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImplInternal.java
index 180706ae..80c5fca6 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImplInternal.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImplInternal.java
@@ -29,8 +29,10 @@ import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
+import com.android.tv.common.recording.RecordingCapability;
+import com.android.usbtuner.DvbDeviceAccessor;
+import com.android.usbtuner.TunerHal;
import com.android.usbtuner.UsbTunerDataSource;
-import com.android.usbtuner.UsbTunerInterface;
import com.android.usbtuner.data.PsipData;
import com.android.usbtuner.data.TunerChannel;
import com.android.usbtuner.exoplayer.CacheManager;
@@ -50,11 +52,19 @@ import java.util.concurrent.CountDownLatch;
public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetector.EventListener,
Handler.Callback {
private static String TAG = "DvrSessionImplInternal";
+ private static final boolean DEBUG = true; // STOPSHIP(DVR)
+
private static final int MSG_START_RECORDING = 1;
private static final int MSG_STOP_RECORDING = 2;
private static final int MSG_DELETE_RECORDING = 3;
private static final int MSG_RELEASE = 4;
+ private final String mInputId;
+ private RecordingCapability mCapabilities;
+
+ public RecordingCapability getCapabilities() {
+ return mCapabilities;
+ }
@IntDef({STATE_IDLE, STATE_RECORDING})
@Retention(RetentionPolicy.SOURCE)
@@ -69,7 +79,7 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
private final Handler mHandler;
private final CountDownLatch mReleaseLatch = new CountDownLatch(1);
- private UsbTunerInterface mUsbTunerInterface;
+ private TunerHal mTunerHal;
private UsbTunerDataSource mTunerSource;
private CacheManager mCacheManager;
private RecordSampleSourceExtractor mRecorder;
@@ -84,13 +94,16 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
void onDeleteFailed(Uri mediaUri, int reason);
}
- public DvrSessionImplInternal(Context context, ChannelDataManager dataManager) {
+ public DvrSessionImplInternal(Context context, String inputId, ChannelDataManager dataManager) {
mContext = context;
+ mInputId = inputId;
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper(), this);
mChannelDataManager = dataManager;
mChannelDataManager.checkDataVersion(context);
+ mCapabilities = new DvbDeviceAccessor(context).getRecordingCapability(mInputId);
+ if (DEBUG) Log.d(TAG, mCapabilities.toString());
}
// PlaybackCacheListener
@@ -197,16 +210,12 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
}
private File getMediaDir(Uri mediaUri) {
- // TODO: Since this is temporary, re-implement this after LiveChannels has APIs.
- String path = mContext.getCacheDir().getAbsolutePath() + "/dvr/";
- String channel = mediaUri.toString().substring(mediaUri.toString().lastIndexOf("/") + 1);
- if (channel.length() == 0) {
- channel = "unknown";
+ String mediaPath = mediaUri.getPath();
+ if (mediaPath == null || mediaPath.length() == 0) {
+ return null;
}
- path += channel;
- path += "/";
-
- return new File(path, String.valueOf(System.currentTimeMillis()));
+ return new File(mContext.getCacheDir().getAbsolutePath() + "/recording" +
+ mediaUri.getPath());
}
private void resetRecorder() {
@@ -222,9 +231,13 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
mTunerSource.stopStream();
mTunerSource = null;
}
- if (mUsbTunerInterface != null) {
- mUsbTunerInterface.close();
- mUsbTunerInterface = null;
+ if (mTunerHal != null) {
+ try {
+ mTunerHal.close();
+ } catch (Exception ex) {
+ Log.e(TAG, "Error on closing tuner HAL.", ex);
+ }
+ mTunerHal = null;
}
}
@@ -237,20 +250,27 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
Log.w(TAG, "Failed to start recording. Couldn't find the channel for " + channelUri);
return false;
}
- mUsbTunerInterface = new UsbTunerInterface(mContext);
- if (!mUsbTunerInterface.openFirstAvailable()) {
+ mTunerHal = TunerHal.getInstance(mContext);
+ if (mTunerHal == null) {
Log.w(TAG, "Failed to start recording. Couldn't open a DVB device");
resetRecorder();
return false;
}
- mTunerSource = new UsbTunerDataSource(mUsbTunerInterface, this);
+ mTunerSource = new UsbTunerDataSource(mTunerHal, this);
if (!mTunerSource.tuneToChannel(channel)) {
Log.w(TAG, "Failed to start recording. Couldn't tune to the channel for " + channel);
resetRecorder();
return false;
}
+ File mediaDir = getMediaDir(mediaUri);
+ if (mediaDir == null) {
+ Log.w(TAG, "Failed to start recording. mediaUri is not provided properly " +
+ mediaUri.toString());
+ resetRecorder();
+ return false;
+ }
mTunerSource.startStream();
- mCacheManager = new CacheManager(new DvrStorageManager(getMediaDir(mediaUri), true));
+ mCacheManager = new CacheManager(new DvrStorageManager(mediaDir, true));
mRecorder = new RecordSampleSourceExtractor((MediaDataSource) mTunerSource,
mCacheManager, this);
try {
@@ -271,12 +291,14 @@ public class DvrSessionImplInternal implements PlaybackCacheListener, EventDetec
}
resetRecorder();
mSessionState = STATE_IDLE;
- return;
}
private void onDeleteRecording(Uri mediaUri) {
// TODO: notify the deletion result to LiveChannels
File mediaDir = getMediaDir(mediaUri);
+ if (mediaDir == null) {
+ return;
+ }
for(File file: mediaDir.listFiles()) {
file.delete();
}
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/EventDetector.java b/usbtuner/src/com/android/usbtuner/tvinput/EventDetector.java
index be8eaccf..9d3c1ab9 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/EventDetector.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/EventDetector.java
@@ -20,7 +20,7 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
-import com.android.usbtuner.UsbTunerInterface;
+import com.android.usbtuner.TunerHal;
import com.android.usbtuner.data.PsiData.PatItem;
import com.android.usbtuner.data.PsiData.PmtItem;
import com.android.usbtuner.data.PsipData.EitItem;
@@ -43,7 +43,7 @@ public class EventDetector {
private static final String TAG = "EventDetector";
private static final boolean DEBUG = false;
- private final UsbTunerInterface mUsbTunerInterface;
+ private final TunerHal mTunerHal;
private TsParser mTsParser;
private final Set<Integer> mPidSet = new HashSet<>();
@@ -61,8 +61,7 @@ public class EventDetector {
@Override
public void onPatDetected(List<PatItem> items) {
for (PatItem i : items) {
- mUsbTunerInterface.addTunerPidFilter(i.getPmtPid(),
- UsbTunerInterface.FILTER_TYPE_OTHER);
+ mTunerHal.addPidFilter(i.getPmtPid(), TunerHal.FILTER_TYPE_OTHER);
}
}
@@ -182,8 +181,8 @@ public class EventDetector {
void onEventDetected(TunerChannel channel, List<EitItem> items);
}
- public EventDetector(UsbTunerInterface usbTunerInteface, EventListener listener) {
- mUsbTunerInterface = usbTunerInteface;
+ public EventDetector(TunerHal usbTunerInteface, EventListener listener) {
+ mTunerHal = usbTunerInteface;
mEventListener = listener;
}
@@ -207,7 +206,7 @@ public class EventDetector {
return;
}
mPidSet.add(pid);
- mUsbTunerInterface.addTunerPidFilter(pid, UsbTunerInterface.FILTER_TYPE_OTHER);
+ mTunerHal.addPidFilter(pid, TunerHal.FILTER_TYPE_OTHER);
}
public void feedTSStream(byte[] data, int startOffset, int length) {
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/InternalTunerTvInputService.java b/usbtuner/src/com/android/usbtuner/tvinput/InternalTunerTvInputService.java
new file mode 100644
index 00000000..adc4f14a
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/tvinput/InternalTunerTvInputService.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.usbtuner.tvinput;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.media.tv.TvInputHardwareInfo;
+import android.media.tv.TvInputInfo;
+import android.os.Environment;
+import android.util.Log;
+
+import com.android.usbtuner.exoplayer.CacheManager;
+import com.android.usbtuner.exoplayer.TrickplayStorageManager;
+import com.android.usbtuner.util.SystemPropertiesProxy;
+import com.android.usbtuner.util.TisConfiguration;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * {@link InternalTunerTvInputService} serves TV channels coming from a internal tuner device.
+ */
+public class InternalTunerTvInputService extends BaseTunerTvInputService {
+ private static final String TAG = "InternalTunerTvInputService";
+ private static final boolean DEBUG = false;
+
+
+ private static final String MAX_CACHE_SIZE_KEY = "usbtuner.cachesize_mbytes";
+ private static final int MAX_CACHE_SIZE_DEF = 2 * 1024; // 2GB
+ private static final int MIN_CACHE_SIZE_DEF = 256; // 256MB
+
+ private ResolveInfo mResolveInfo;
+ private String mTvInputId;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mResolveInfo = getPackageManager().resolveService(
+ new Intent(SERVICE_INTERFACE).setClass(this, getClass()),
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+ }
+
+ @Override
+ protected void maybeInitCacheManager() {
+ int maxCacheSizeMb = SystemPropertiesProxy.getInt(MAX_CACHE_SIZE_KEY, MAX_CACHE_SIZE_DEF);
+ if (maxCacheSizeMb >= MIN_CACHE_SIZE_DEF) {
+ boolean useExternalStorage = Environment.MEDIA_MOUNTED.equals(
+ Environment.getExternalStorageState()) &&
+ Environment.isExternalStorageRemovable();
+ if (DEBUG) Log.d(TAG, "useExternalStorage for trickplay: " + useExternalStorage);
+ boolean allowToUseInternalStorage = true;
+ if (useExternalStorage || allowToUseInternalStorage) {
+ File baseDir = useExternalStorage ? getExternalCacheDir() : getCacheDir();
+ mCacheManager = new CacheManager(
+ new TrickplayStorageManager(getApplicationContext(), baseDir,
+ 1024L * 1024 * maxCacheSizeMb));
+ }
+ }
+ }
+
+ @Override
+ public TvInputInfo onHardwareAdded(TvInputHardwareInfo hardwareInfo) {
+ if (DEBUG) Log.d(TAG, "onHardwareAdded: " + hardwareInfo.toString());
+
+ if (mTvInputId != null) {
+ return null;
+ }
+
+ TvInputInfo info = null;
+ if (hardwareInfo.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_TUNER &&
+ TisConfiguration.getTunerHwDeviceId(this) == hardwareInfo.getDeviceId()) {
+ try {
+ info = TvInputInfo.createTvInputInfo(this, mResolveInfo, hardwareInfo,
+ "Google Tuner", null);
+ mTvInputId = info.getId();
+ } catch (XmlPullParserException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return info;
+ }
+
+ @Override
+ public String onHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
+ if (DEBUG) Log.d(TAG, "onHardwareRemoved: " + hardwareInfo.toString());
+
+ return null;
+ }
+}
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImpl.java b/usbtuner/src/com/android/usbtuner/tvinput/RecordingSessionImpl.java
index 1d231517..0aac1211 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/DvrSessionImpl.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/RecordingSessionImpl.java
@@ -19,19 +19,23 @@ package com.android.usbtuner.tvinput;
import android.content.Context;
import android.net.Uri;
-import com.android.tv.common.dvr.DvrTvInputService;
+import com.android.tv.common.recording.RecordingCapability;
+import com.android.tv.common.recording.TvRecording;
/**
* Processes DVR recordings, and deletes the previously recorded contents.
*/
-public class DvrSessionImpl extends DvrTvInputService.DvrSession implements
+public class RecordingSessionImpl extends TvRecording.RecordingSession implements
DvrSessionImplInternal.DvrEventListener {
// TODO: recording request will be handled here
private final DvrSessionImplInternal mSessionImplInternal;
+ private final String mInputId;
- public DvrSessionImpl(Context context, ChannelDataManager channelDataManager) {
+ public RecordingSessionImpl(Context context, String inputId,
+ ChannelDataManager channelDataManager) {
super(context);
- mSessionImplInternal = new DvrSessionImplInternal(context, channelDataManager);
+ mInputId = inputId;
+ mSessionImplInternal = new DvrSessionImplInternal(context, inputId, channelDataManager);
mSessionImplInternal.setDvrEventListener(this);
}
@@ -52,6 +56,11 @@ public class DvrSessionImpl extends DvrTvInputService.DvrSession implements
}
@Override
+ public RecordingCapability onGetCapability() {
+ return mSessionImplInternal.getCapabilities();
+ }
+
+ @Override
public void onRelease() {
}
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImpl.java b/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImpl.java
index 7a060d2f..94a8607a 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImpl.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImpl.java
@@ -35,7 +35,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.android.tv.common.dvr.DvrTvInputService;
+import com.android.tv.common.recording.RecordingTvInputService;
import com.android.usbtuner.R;
import com.android.usbtuner.cc.CaptionLayout;
import com.android.usbtuner.cc.CaptionTrackRenderer;
@@ -51,7 +51,7 @@ import java.util.ArrayList;
/**
* Provides a USB tuner TV input session.
*/
-public class TvInputSessionImpl extends DvrTvInputService.PlaybackSession
+public class TvInputSessionImpl extends RecordingTvInputService.PlaybackSession
implements Handler.Callback, TvInputSessionImplInternal.InternalListener {
private static final String TAG = "TvInputSessionImpl";
private static final boolean DEBUG = false;
@@ -169,6 +169,10 @@ public class TvInputSessionImpl extends DvrTvInputService.PlaybackSession
@Override
public long onTimeShiftGetStartPosition() {
+ Long duration = mSessionImplInternal.getDurationForRecording();
+ if (duration != null) {
+ notifyTimeShiftEndPosition(mSessionImplInternal.getStartPosition() + duration);
+ }
return mSessionImplInternal.getStartPosition();
}
@@ -194,6 +198,18 @@ public class TvInputSessionImpl extends DvrTvInputService.PlaybackSession
}
@Override
+ public void onPlayMedia(Uri recordUri) {
+ if (recordUri == null) {
+ Log.w(TAG, "onPlayMedia() is failed due to null channelUri.");
+ mSessionImplInternal.stopTune();
+ return;
+ }
+ mTuneStartTimestamp = SystemClock.elapsedRealtime();
+ mSessionImplInternal.tune(recordUri);
+ mPlayPaused = false;
+ }
+
+ @Override
public void onUnblockContent(TvContentRating unblockedRating) {
mSessionImplInternal.sendMessage(TvInputSessionImplInternal.MSG_UNBLOCKED_RATING,
unblockedRating);
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImplInternal.java b/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImplInternal.java
index 017bbda7..c49d0833 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImplInternal.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/TvInputSessionImplInternal.java
@@ -19,6 +19,7 @@ package com.android.usbtuner.tvinput;
import android.content.ContentUris;
import android.content.Context;
import android.media.MediaDataSource;
+import android.media.MediaFormat;
import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
@@ -29,7 +30,6 @@ import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemClock;
import android.text.Html;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
@@ -38,10 +38,11 @@ import android.view.Surface;
import android.view.accessibility.CaptioningManager;
import com.google.android.exoplayer.audio.AudioCapabilities;
+import com.android.tv.common.TvContentRatingCache;
import com.android.usbtuner.FileDataSource;
import com.android.usbtuner.InputStreamSource;
+import com.android.usbtuner.TunerHal;
import com.android.usbtuner.UsbTunerDataSource;
-import com.android.usbtuner.UsbTunerInterface;
import com.android.usbtuner.data.Cea708Data;
import com.android.usbtuner.data.Channel;
import com.android.usbtuner.data.PsipData.EitItem;
@@ -50,6 +51,7 @@ import com.android.usbtuner.data.Track.AtscAudioTrack;
import com.android.usbtuner.data.Track.AtscCaptionTrack;
import com.android.usbtuner.data.TunerChannel;
import com.android.usbtuner.exoplayer.CacheManager;
+import com.android.usbtuner.exoplayer.DvrStorageManager;
import com.android.usbtuner.exoplayer.MpegTsPassthroughAc3RendererBuilder;
import com.android.usbtuner.exoplayer.MpegTsPlayer;
import com.android.usbtuner.util.IsoUtils;
@@ -57,6 +59,9 @@ import com.android.usbtuner.util.StatusTextUtils;
import junit.framework.Assert;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -70,9 +75,11 @@ import java.util.concurrent.CountDownLatch;
public class TvInputSessionImplInternal implements PlaybackCacheListener,
MpegTsPlayer.VideoEventListener, MpegTsPlayer.Listener, EventDetector.EventListener,
ChannelDataManager.ProgramInfoListener, Handler.Callback {
- private static final String TAG = "TvInputSessionImplInternal";
+ private static final String TAG = "TvInputSessionInternal";
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 PLAY_FROM_RECORDING = "record";
// Public messages
public static final int MSG_SELECT_TRACK = 1;
@@ -138,7 +145,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
- private final UsbTunerInterface mUsbTunerInterface;
+ private final TunerHal mTunerHal;
private UsbTunerDataSource mTunerSource;
private FileDataSource mFileSource;
private InputStreamSource mSource;
@@ -148,6 +155,8 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
private int mEndedGeneration;
private volatile MpegTsPlayer mPlayer;
private volatile TunerChannel mChannel;
+ private String mRecordingId;
+ private volatile Long mRecordingDuration;
private final Handler mHandler;
private final HandlerThread mHandlerThread;
private int mRetryCount;
@@ -174,12 +183,13 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
private long mLastLimitInBytes = 0L;
private long mLastPositionInBytes = 0L;
private final CacheManager mCacheManager;
+ private final TvContentRatingCache mTvContentRatingCache = TvContentRatingCache.getInstance();
public TvInputSessionImplInternal(Context context, ChannelDataManager channelDataManager,
CacheManager cacheManager) {
mContext = context;
- mUsbTunerInterface = new UsbTunerInterface(context);
- if (!mUsbTunerInterface.openFirstAvailable()) {
+ mTunerHal = TunerHal.getInstance(context);
+ if (mTunerHal == null) {
throw new RuntimeException("Failed to open a DVB device");
}
@@ -192,7 +202,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
mChannelDataManager.setListener(this);
mChannelDataManager.checkDataVersion(mContext);
mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
- mTunerSource = new UsbTunerDataSource(mUsbTunerInterface, this);
+ mTunerSource = new UsbTunerDataSource(mTunerHal, this);
mFileSource = new FileDataSource(this);
mVolume = 1.0f;
mTvTracks = new ArrayList<>();
@@ -226,6 +236,36 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
return mCacheStartTimeMs;
}
+
+ private String getRecordingPath() {
+ return mContext.getCacheDir().getAbsolutePath() + "/recording" + mRecordingId;
+ }
+
+ public Long getDurationForRecording() {
+ return mRecordingDuration;
+ }
+
+ private Long getDurationForRecording(String recordingId) {
+ try {
+ 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);
+ // 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;
+ }
+ }
+
public long getCurrentPosition() {
// TODO: More precise time may be necessary.
MpegTsPlayer mpegTsPlayer = mPlayer;
@@ -419,6 +459,24 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
}
};
+ private long parseChannel(Uri uri) {
+ try {
+ List<String> paths = uri.getPathSegments();
+ if (paths.size() > 1 && paths.get(0).equals(PLAY_FROM_CHANNEL)) {
+ return ContentUris.parseId(uri);
+ }
+ } catch (UnsupportedOperationException | NumberFormatException e) {
+ }
+ return -1;
+ }
+
+ private String parseRecording(Uri uri) {
+ if (uri.getScheme().equals(PLAY_FROM_RECORDING)) {
+ return uri.getPath();
+ }
+ return null;
+ }
+
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
@@ -431,15 +489,14 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
return true;
}
Uri channelUri = (Uri) msg.obj;
- long channelId;
- try {
- channelId = ContentUris.parseId(channelUri);
- } catch (UnsupportedOperationException | NumberFormatException e) {
- channelId = -1;
- }
+ String recording = null;
+ long channelId = parseChannel(channelUri);
TunerChannel channel = (channelId == -1) ? null
: mChannelDataManager.getChannel(channelId);
- if (channel == null) {
+ if (channelId == -1) {
+ recording = parseRecording(channelUri);
+ }
+ if (channel == null && recording == null) {
Log.w(TAG, "onTune() is failed. Can't find channel for " + channelUri);
stopTune();
mInternalListener.notifyVideoUnavailable(
@@ -447,8 +504,10 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
return true;
}
mHandler.removeCallbacksAndMessages(null);
- mChannelDataManager.requestProgramsData(channel);
- prepareTune(channel);
+ if (channel != null) {
+ mChannelDataManager.requestProgramsData(channel);
+ }
+ prepareTune(channel, recording);
mInternalListener.notifyContentAllowed();
resetPlayback();
resetTvTracks();
@@ -466,7 +525,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
stopPlayback();
stopCaptionTrack();
resetTvTracks();
- mUsbTunerInterface.stopTune();
+ mTunerHal.stopTune();
mSource = null;
mInternalListener.notifyVideoUnavailable(
TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
@@ -479,7 +538,11 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
mHandler.removeCallbacksAndMessages(null);
stopPlayback();
stopCaptionTrack();
- mUsbTunerInterface.close();
+ try {
+ mTunerHal.close();
+ } catch (Exception ex) {
+ Log.e(TAG, "Error on closing tuner HAL.", ex);
+ }
mSource = null;
mReleaseLatch.countDown();
return true;
@@ -495,11 +558,11 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
resetPlayback();
} else {
// When it reaches this point, it may be due to an error that occurred in
- // the tuner device. Calling stopPlayback() and UsbTunerInterface.stopTune()
+ // the tuner device. Calling stopPlayback() and TunerHal.stopTune()
// resets the tuner device to recover from the error.
stopPlayback();
stopCaptionTrack();
- mUsbTunerInterface.stopTune();
+ mTunerHal.stopTune();
mInternalListener.notifyVideoUnavailable(
TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
@@ -523,7 +586,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
if (DEBUG) {
Log.d(TAG, "MSG_START_PLAYBACK");
}
- if (mChannel != null) {
+ if (mChannel != null || mRecordingId != null) {
startPlayback(msg.obj);
}
return true;
@@ -604,6 +667,9 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
Pair<TunerChannel, List<EitItem>> pair =
(Pair<TunerChannel, List<EitItem>>) msg.obj;
TunerChannel channel = pair.first;
+ if (mChannel == null) {
+ return true;
+ }
if (mChannel != null && mChannel.compareTo(channel) != 0) {
return true;
}
@@ -660,7 +726,8 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
if (DEBUG) {
Log.d(TAG, "MSG_DRAWN_TO_SURFACE");
}
- mCacheStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
+ mCacheStartTimeMs = mRecordStartTimeMs =
+ (mRecordingId != null) ? 0 : System.currentTimeMillis();
mInternalListener.notifyVideoAvailable();
mReportedDrawnToSurface = true;
@@ -707,6 +774,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
return true;
}
case MSG_SELECT_TRACK: {
+ // TODO : mChannel == null && mRecordingId != null
if (mChannel != null) {
doSelectTrack(msg.arg1, (String) msg.obj);
}
@@ -820,7 +888,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
positionInBytes, limitInBytes));
}
mInternalListener.sendUiMessage(TvInputSessionImpl.MSG_UI_HIDE_MESSAGE);
- if (mChannel.getType() == Channel.TYPE_TUNER
+ if (mSource != null && mChannel.getType() == Channel.TYPE_TUNER
&& positionInBytes == mLastPositionInBytes
&& limitInBytes == mLastLimitInBytes) {
mInternalListener.notifyVideoUnavailable(
@@ -886,14 +954,14 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
}
}
- private MpegTsPlayer createPlayer(AudioCapabilities capabilities) {
+ private MpegTsPlayer createPlayer(AudioCapabilities capabilities, CacheManager cacheManager) {
if (capabilities == null) {
Log.w(TAG, "No Audio Capabilities");
}
++mPlayerGeneration;
MpegTsPlayer player = new MpegTsPlayer(mPlayerGeneration,
- new MpegTsPassthroughAc3RendererBuilder(mCacheManager, this),
+ new MpegTsPassthroughAc3RendererBuilder(cacheManager, this),
mHandler, capabilities);
Log.i(TAG, "Passthrough AC3 renderer");
if (DEBUG) {
@@ -1076,7 +1144,9 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
private void stopPlayback() {
if (mPlayer != null) {
- mSource.stopStream();
+ if (mSource != null) {
+ mSource.stopStream();
+ }
mPlayer.setPlayWhenReady(false);
mPlayer.release();
mPlayer = null;
@@ -1089,10 +1159,11 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
}
private void startPlayback(Object playerObj) {
+ // TODO: provide hasAudio()/hasVideo() for play recordings.
if (mPlayer == null || mPlayer != playerObj) {
return;
}
- if (!mChannel.hasAudio()) {
+ if (mChannel != null && !mChannel.hasAudio()) {
// A channel needs to have a audio stream at least to play in exoPlayer.
mInternalListener.notifyVideoUnavailable(
TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
@@ -1102,7 +1173,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
mPlayer.setSurface(mSurface);
mPlayer.setPlayWhenReady(true);
mPlayer.setVolume(mVolume);
- if (!mChannel.hasVideo() && mChannel.hasAudio()) {
+ if (mChannel != null && !mChannel.hasVideo() && mChannel.hasAudio()) {
mInternalListener.notifyVideoUnavailable(
TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY);
} else {
@@ -1114,6 +1185,51 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
}
}
+ private void playFromChannel(long timestamp) {
+ long oldTimestamp;
+ mSource = getDataSource(mChannel.getType());
+ Assert.assertNotNull(mSource);
+ if (mSource.tuneToChannel(mChannel)) {
+ if (ENABLE_PROFILER) {
+ oldTimestamp = timestamp;
+ timestamp = SystemClock.elapsedRealtime();
+ Log.i(TAG, "[Profiler] tuneToChannel() takes " + (timestamp - oldTimestamp)
+ + " ms");
+ }
+ mSource.startStream();
+ mPlayer = createPlayer(mAudioCapabilities, mCacheManager);
+ mPlayer.setCaptionServiceNumber(Cea708Data.EMPTY_SERVICE_NUMBER);
+ mPlayer.addListener(this);
+ mPlayer.setVideoEventListener(this);
+ mPlayer.setCaptionServiceNumber(mCaptionTrack != null ?
+ mCaptionTrack.serviceNumber : Cea708Data.EMPTY_SERVICE_NUMBER);
+ mPreparingGeneration = mPlayerGeneration;
+ mPlayer.prepare((MediaDataSource) mSource);
+ mPlayerStarted = false;
+ } else {
+ // Close TunerHal when tune fails.
+ mTunerHal.stopTune();
+ mInternalListener.notifyVideoUnavailable(
+ TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+ }
+ }
+
+ private void playFromRecording() {
+ // TODO: Handle errors.
+ CacheManager cacheManager =
+ new CacheManager(new DvrStorageManager(new File(getRecordingPath()), false));
+ mSource = null;
+ mPlayer = createPlayer(mAudioCapabilities, cacheManager);
+ mPlayer.setCaptionServiceNumber(Cea708Data.EMPTY_SERVICE_NUMBER);
+ mPlayer.addListener(this);
+ mPlayer.setVideoEventListener(this);
+ mPlayer.setCaptionServiceNumber(mCaptionTrack != null ?
+ mCaptionTrack.serviceNumber : Cea708Data.EMPTY_SERVICE_NUMBER);
+ mPreparingGeneration = mPlayerGeneration;
+ mPlayer.prepare(null);
+ mPlayerStarted = false;
+ }
+
private void resetPlayback() {
long timestamp, oldTimestamp;
timestamp = SystemClock.elapsedRealtime();
@@ -1124,34 +1240,13 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
timestamp = SystemClock.elapsedRealtime();
Log.i(TAG, "[Profiler] stopPlayback() takes " + (timestamp - oldTimestamp) + " ms");
}
- if (!mChannelBlocked && mSurface != null && mChannel != null) {
+ if (!mChannelBlocked && mSurface != null) {
mInternalListener.notifyVideoUnavailable(
TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
- mSource = getDataSource(mChannel.getType());
- Assert.assertNotNull(mSource);
- if (mSource.tuneToChannel(mChannel)) {
- if (ENABLE_PROFILER) {
- oldTimestamp = timestamp;
- timestamp = SystemClock.elapsedRealtime();
- Log.i(TAG, "[Profiler] tuneToChannel() takes " + (timestamp - oldTimestamp)
- + " ms");
- }
- mSource.startStream();
- mPlayer = createPlayer(mAudioCapabilities);
- mPlayer.setCaptionServiceNumber(Cea708Data.EMPTY_SERVICE_NUMBER);
- mPlayer.addListener(this);
- mPlayer.setVideoEventListener(this);
- mPlayer.setDataSource((MediaDataSource) mSource);
- mPlayer.setCaptionServiceNumber(mCaptionTrack != null ?
- mCaptionTrack.serviceNumber : Cea708Data.EMPTY_SERVICE_NUMBER);
- mPreparingGeneration = mPlayerGeneration;
- mPlayer.prepare();
- mPlayerStarted = false;
- } else {
- // Stop tune when it fails.
- mUsbTunerInterface.stopTune();
- mInternalListener.notifyVideoUnavailable(
- TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+ if (mChannel != null) {
+ playFromChannel(timestamp);
+ } else if (mRecordingId != null){
+ playFromRecording();
}
}
}
@@ -1167,14 +1262,17 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
}
}
- private void prepareTune(TunerChannel channel) {
+ private void prepareTune(TunerChannel channel, String recording) {
mChannelBlocked = false;
mUnblockedContentRating = null;
mRetryCount = 0;
mChannel = channel;
+ mRecordingId = recording;
+ mRecordingDuration = recording != null ? getDurationForRecording(recording) : null;
mProgram = null;
mPrograms = null;
- mCacheStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
+ mCacheStartTimeMs = mRecordStartTimeMs =
+ (mRecordingId != null) ? 0 : System.currentTimeMillis();
mLastPositionMs = 0;
mCaptionTrack = null;
mHandler.sendEmptyMessage(MSG_PARENTAL_CONTROLS);
@@ -1324,12 +1422,15 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
if (currentProgram == null) {
return null;
}
- String[] ratings = TextUtils.split(currentProgram.getContentRating(), ",");
- for (String rating : ratings) {
- TvContentRating tvContentRating = TvContentRating.unflattenFromString(rating);
- if (!Objects.equals(mUnblockedContentRating, tvContentRating)
- && mTvInputManager.isRatingBlocked(tvContentRating)) {
- return tvContentRating;
+ TvContentRating[] ratings = mTvContentRatingCache
+ .getRatings(currentProgram.getContentRating());
+ if (ratings == null) {
+ return null;
+ }
+ for (TvContentRating rating : ratings) {
+ if (!Objects.equals(mUnblockedContentRating, rating) && mTvInputManager
+ .isRatingBlocked(rating)) {
+ return rating;
}
}
return null;
@@ -1343,7 +1444,7 @@ public class TvInputSessionImplInternal implements PlaybackCacheListener,
mChannelBlocked = channelBlocked;
if (mChannelBlocked) {
mHandler.removeCallbacksAndMessages(null);
- mUsbTunerInterface.stopTune();
+ mTunerHal.stopTune();
stopPlayback();
resetTvTracks();
if (contentRating != null) {
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerDebug.java b/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerDebug.java
index e0cf011d..5c24bed7 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerDebug.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerDebug.java
@@ -24,7 +24,7 @@ import android.util.Log;
*/
public class UsbTunerDebug {
private static final String TAG = "UsbTunerDebug";
- public static final boolean ENABLED = true;
+ public static final boolean ENABLED = false;
private int mVideoFrameDrop;
private int mBytesInQueue;
diff --git a/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerTvInputService.java b/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerTvInputService.java
index 7bd8bfd1..2397e5f2 100644
--- a/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerTvInputService.java
+++ b/usbtuner/src/com/android/usbtuner/tvinput/UsbTunerTvInputService.java
@@ -17,25 +17,19 @@
package com.android.usbtuner.tvinput;
import android.os.Environment;
-import android.os.Handler;
import android.util.Log;
-import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.android.exoplayer.audio.AudioCapabilitiesReceiver;
-import com.android.tv.common.dvr.DvrTvInputService;
+import com.android.tv.common.recording.TvRecording;
import com.android.usbtuner.exoplayer.CacheManager;
import com.android.usbtuner.exoplayer.TrickplayStorageManager;
import com.android.usbtuner.util.SystemPropertiesProxy;
import java.io.File;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
/**
* {@link UsbTunerTvInputService} serves TV channels coming from a usb tuner device.
*/
-public class UsbTunerTvInputService extends DvrTvInputService
- implements AudioCapabilitiesReceiver.Listener {
+public class UsbTunerTvInputService extends BaseTunerTvInputService {
private static final String TAG = "UsbTunerTvInputService";
private static final boolean DEBUG = false;
@@ -44,34 +38,14 @@ public class UsbTunerTvInputService extends DvrTvInputService
private static final int MAX_CACHE_SIZE_DEF = 2 * 1024; // 2GB
private static final int MIN_CACHE_SIZE_DEF = 256; // 256MB
- private List<TvInputSessionImpl> mTvInputSessions;
- private ChannelDataManager mChannelDataManager;
- private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
- private AudioCapabilities mAudioCapabilities;
- private CacheManager mCacheManager;
-
@Override
- public void onCreate() {
- super.onCreate();
- if (DEBUG) {
- Log.d(TAG, "onCreate");
- }
- mTvInputSessions = new CopyOnWriteArrayList<>();
- mChannelDataManager = new ChannelDataManager(getApplicationContext());
- mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(getApplicationContext(), this);
- mAudioCapabilitiesReceiver.register();
- maybeInitCacheManager();
- }
-
- private void maybeInitCacheManager() {
+ protected void maybeInitCacheManager() {
int maxCacheSizeMb = SystemPropertiesProxy.getInt(MAX_CACHE_SIZE_KEY, MAX_CACHE_SIZE_DEF);
if (maxCacheSizeMb >= MIN_CACHE_SIZE_DEF) {
boolean useExternalStorage = Environment.MEDIA_MOUNTED.equals(
Environment.getExternalStorageState()) &&
Environment.isExternalStorageRemovable();
- if (DEBUG) {
- Log.d(TAG, "useExternalStorage for trickplay: " + useExternalStorage);
- }
+ if (DEBUG) Log.d(TAG, "useExternalStorage for trickplay: " + useExternalStorage);
boolean allowToUseInternalStorage = true;
if (useExternalStorage || allowToUseInternalStorage) {
File baseDir = useExternalStorage ? getExternalCacheDir() : getCacheDir();
@@ -80,60 +54,6 @@ public class UsbTunerTvInputService extends DvrTvInputService
1024L * 1024 * maxCacheSizeMb));
}
}
- if (mCacheManager == null) {
- Log.i(TAG, "Trickplay is disabled");
- } else {
- Log.i(TAG, "Trickplay is enabled");
- }
}
- @Override
- public void onDestroy() {
- if (DEBUG) {
- Log.d(TAG, "onDestroy");
- }
- super.onDestroy();
- mChannelDataManager.release();
- mAudioCapabilitiesReceiver.unregister();
- if (mCacheManager != null) {
- mCacheManager.close();
- }
- }
-
- @Override
- public DvrSession onCreateDvrSession(String inputId) {
- return new DvrSessionImpl(this, mChannelDataManager);
- }
-
- @Override
- public DvrTvInputService.PlaybackSession onCreatePlaybackSession(String inputId) {
- if (DEBUG) {
- Log.d(TAG, "onCreateSession");
- }
- final TvInputSessionImpl session = new TvInputSessionImpl(
- this, mChannelDataManager, mCacheManager);
- mTvInputSessions.add(session);
- session.notifyAudioCapabilitiesChanged(mAudioCapabilities);
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- // STOPSHIP(DVR): Session methods cannot be called inside onCreatePlaybackSession.
- // If DvrSession is added in API. we can call them inside onCreatePlaybackSession.
- session.setOverlayViewEnabled(true);
- }
- });
- return session;
- }
-
- @Override
- public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) {
- mAudioCapabilities = audioCapabilities;
- for (TvInputSessionImpl session : mTvInputSessions) {
- if (session.isReleased()) {
- mTvInputSessions.remove(session);
- } else {
- session.notifyAudioCapabilitiesChanged(audioCapabilities);
- }
- }
- }
}
diff --git a/usbtuner/src/com/android/usbtuner/util/Ints.java b/usbtuner/src/com/android/usbtuner/util/Ints.java
index e1337eea..9a3e719d 100644
--- a/usbtuner/src/com/android/usbtuner/util/Ints.java
+++ b/usbtuner/src/com/android/usbtuner/util/Ints.java
@@ -19,7 +19,7 @@ public class Ints {
}
public static List<Integer> asList(int[] intArray) {
- List<Integer> integerList = new ArrayList<Integer>(intArray.length);
+ List<Integer> integerList = new ArrayList<>(intArray.length);
for (int data : intArray) {
integerList.add(data);
}
diff --git a/usbtuner/src/com/android/usbtuner/util/TisConfiguration.java b/usbtuner/src/com/android/usbtuner/util/TisConfiguration.java
new file mode 100644
index 00000000..1e6b0d8a
--- /dev/null
+++ b/usbtuner/src/com/android/usbtuner/util/TisConfiguration.java
@@ -0,0 +1,22 @@
+package com.android.usbtuner.util;
+
+import android.content.Context;
+
+/**
+ * A helper class of tuner configuration.
+ */
+public class TisConfiguration {
+ private static final String LC_PACKAGE_NAME = "com.android.tv";
+
+ public static boolean isPackagedWithLiveChannels(Context context) {
+ return (LC_PACKAGE_NAME.equals(context.getPackageName()));
+ }
+
+ public static boolean isInternalTunerTvInput(Context context) {
+ return (!LC_PACKAGE_NAME.equals(context.getPackageName()));
+ }
+
+ public static int getTunerHwDeviceId(Context context) {
+ return 0; // FIXME: Make it OEM configurable
+ }
+}
diff --git a/usbtuner/src/com/google/android/exoplayer/audio/AudioTrack.java b/usbtuner/src/com/google/android/exoplayer/audio/AudioTrack.java
index 0e5176b5..f44b0c9f 100644
--- a/usbtuner/src/com/google/android/exoplayer/audio/AudioTrack.java
+++ b/usbtuner/src/com/google/android/exoplayer/audio/AudioTrack.java
@@ -354,7 +354,26 @@ public final class AudioTrack {
audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId);
}
- checkAudioTrackInitialized();
+ try {
+ checkAudioTrackInitialized();
+ } catch (InitializationException e) {
+ if (encoding != C.ENCODING_AC3 || channelConfig != AudioFormat.CHANNEL_OUT_MONO) {
+ throw e;
+ }
+ // This workarounds b/25955476.
+ channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
+ if (sessionId == SESSION_ID_NOT_SET) {
+ audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM);
+ } else {
+ // Re-attach to the same audio session.
+ audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM,
+ sessionId);
+ }
+ checkAudioTrackInitialized();
+ Log.w(TAG, "AC3 Mono passthrough AudioTrack reinitialized as Stereo");
+ }
sessionId = audioTrack.getAudioSessionId();
if (enablePreV21AudioSessionWorkaround) {
diff --git a/version.mk b/version.mk
index 3b6223ad..55839297 100644
--- a/version.mk
+++ b/version.mk
@@ -48,9 +48,9 @@
base_version_major := 1
# Change this for each branch
-base_version_minor := 08
+base_version_minor := 09
# The date of the first commit checked in to the current branch
-base_version_since := 2015-10-12
+base_version_since := 2015-11-21
# code_version_major will overflow at 22
code_version_major := $(shell echo $$(($(base_version_major)+3)))
@@ -58,7 +58,7 @@ code_version_major := $(shell echo $$(($(base_version_major)+3)))
git_commit_count := $(shell git --git-dir $(LOCAL_PATH)/.git rev-list --since=$(base_version_since) --all --count HEAD)
# x86 and arm sometimes don't match.
#code_version_build := $(shell printf "%03d" $(git_commit_count))
-code_version_build := 301
+code_version_build := 419
#####################################################
#####################################################
# Collect automatic version code parameters