aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:27:19 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:27:19 +0000
commite8a0f1ba285fd06676de2bdb08456d588e8341e2 (patch)
treef4ba89447e2d7ac3355508e583a5cf0574c29af5
parentf61bdda7ea9f0ecaf4158715411dc025ed9a3061 (diff)
parentd12bfa398c56027290a9e6e4fd14f635458ec581 (diff)
downloadTV-android10-mainline-tzdata-release.tar.gz
Change-Id: If4916a588c0e85189c29cccd566a4ac49ec6328e
-rw-r--r--Android.bp20
-rw-r--r--AndroidManifest.xml21
-rw-r--r--README.md12
-rw-r--r--assets/rating_sources.html18
-rw-r--r--build.gradle87
-rw-r--r--common/Android.bp28
-rw-r--r--common/AndroidManifest.xml2
-rw-r--r--common/build.gradle68
-rw-r--r--common/src/com/android/tv/common/BaseApplication.java18
-rw-r--r--common/src/com/android/tv/common/BaseSingletons.java19
-rw-r--r--common/src/com/android/tv/common/buildtype/BuildTypeModule.java34
-rw-r--r--common/src/com/android/tv/common/buildtype/HasBuildType.java2
-rw-r--r--common/src/com/android/tv/common/compat/TvInputInfoCompat.java10
-rw-r--r--common/src/com/android/tv/common/compat/internal/recording_commands.proto1
-rw-r--r--common/src/com/android/tv/common/compat/internal/recording_events.proto2
-rw-r--r--common/src/com/android/tv/common/compat/internal/tif_commands.proto1
-rw-r--r--common/src/com/android/tv/common/compat/internal/tif_events.proto1
-rw-r--r--common/src/com/android/tv/common/customization/CustomizationManager.java21
-rw-r--r--common/src/com/android/tv/common/dagger/ApplicationModule.java8
-rw-r--r--common/src/com/android/tv/common/dagger/init/SafePreDaggerInitializer.java61
-rw-r--r--common/src/com/android/tv/common/dev/DeveloperPreference.java132
-rw-r--r--common/src/com/android/tv/common/dev/DeveloperPreferences.java71
-rw-r--r--common/src/com/android/tv/common/experiments/ExperimentFlag.java96
-rw-r--r--common/src/com/android/tv/common/experiments/ExperimentLoader.java (renamed from common/src/com/android/tv/common/flags/impl/DefaultMessagesFlags.java)22
-rw-r--r--common/src/com/android/tv/common/experiments/Experiments.java64
-rw-r--r--common/src/com/android/tv/common/feature/CommonFeatures.java6
-rw-r--r--common/src/com/android/tv/common/feature/DeveloperPreferenceFeature.java59
-rw-r--r--common/src/com/android/tv/common/feature/ExperimentFeature.java (renamed from common/src/com/android/tv/common/feature/PermissionFeature.java)26
-rw-r--r--common/src/com/android/tv/common/feature/FeatureUtils.java18
-rw-r--r--common/src/com/android/tv/common/feature/Model.java3
-rw-r--r--common/src/com/android/tv/common/feature/Sdk.java2
-rw-r--r--common/src/com/android/tv/common/flags/BackendKnobsFlags.java8
-rwxr-xr-xcommon/src/com/android/tv/common/flags/CloudEpgFlags.java3
-rwxr-xr-xcommon/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java (renamed from common/src/com/android/tv/common/flags/MessagesFlags.java)17
-rwxr-xr-xcommon/src/com/android/tv/common/flags/DvrFlags.java35
-rwxr-xr-xcommon/src/com/android/tv/common/flags/LegacyFlags.java38
-rwxr-xr-xcommon/src/com/android/tv/common/flags/SetupFlags.java36
-rwxr-xr-xcommon/src/com/android/tv/common/flags/TunerFlags.java4
-rwxr-xr-xcommon/src/com/android/tv/common/flags/UiFlags.java11
-rw-r--r--[-rwxr-xr-x]common/src/com/android/tv/common/flags/has/HasConcurrentDvrPlaybackFlags.java (renamed from common/src/com/android/tv/common/flags/StartupFlags.java)24
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java11
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultConcurrentDvrPlaybackFlags.java (renamed from common/src/com/android/tv/common/flags/impl/DefaultDvrFlags.java)11
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java21
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultLegacyFlags.java47
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultStartupFlags.java32
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java5
-rw-r--r--common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java8
-rw-r--r--common/src/com/android/tv/common/flags/impl/SettableFlagsModule.java91
-rw-r--r--common/src/com/android/tv/common/flags/proto/typed-features.proto20
-rw-r--r--common/src/com/android/tv/common/recording/RecordingStorageStatusManager.java11
-rw-r--r--common/src/com/android/tv/common/singletons/HasTvInputId.java4
-rw-r--r--common/src/com/android/tv/common/support/tvprovider/README.md6
-rw-r--r--common/src/com/android/tv/common/support/tvprovider/TvContractCompatX.java108
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java20
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java6
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/TranslationAnimationCreator.java6
-rw-r--r--common/src/com/android/tv/common/util/CommonUtils.java10
-rw-r--r--common/src/com/android/tv/common/util/Debug.java6
-rw-r--r--common/src/com/android/tv/common/util/LocationUtils.java48
-rw-r--r--common/src/com/android/tv/common/util/NetworkTrafficTags.java22
-rw-r--r--common/src/com/android/tv/common/util/PermissionUtils.java23
-rw-r--r--common/src/com/android/tv/common/util/PostalCodeUtils.java21
-rw-r--r--common/src/com/android/tv/common/util/SystemProperties.java19
-rw-r--r--common/tests/robotests/src/com/android/tv/common/TvContentRatingCacheTest.java222
-rw-r--r--common/tests/robotests/src/com/android/tv/common/actions/InputSetupActionUtilsTest.java150
-rw-r--r--common/tests/robotests/src/com/android/tv/common/compat/TvInputInfoCompatTest.java111
-rw-r--r--common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateCommandTest.java61
-rw-r--r--common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateRecordingCommandTest.java63
-rw-r--r--common/tests/robotests/src/com/android/tv/common/compat/internal/RecordingSessionEventTest.java70
-rw-r--r--common/tests/robotests/src/com/android/tv/common/compat/internal/SessionEventTest.java70
-rw-r--r--common/tests/robotests/src/com/android/tv/common/dev/DeveloperPreferenceTest.java54
-rw-r--r--common/tests/robotests/src/com/android/tv/common/support/tis/BaseTvInputServiceTest.java147
-rw-r--r--common/tests/robotests/src/com/android/tv/common/support/tis/SimpleSessionManagerTest.java124
-rw-r--r--common/tests/robotests/src/com/android/tv/common/support/tis/TisSessionTest.java209
-rw-r--r--common/tests/robotests/src/com/android/tv/common/support/tis/WrappedSessionTest.java190
-rw-r--r--common/tests/robotests/src/com/android/tv/common/support/tvprovider/TvContractCompatXTest.java71
-rw-r--r--common/tests/robotests/src/com/android/tv/common/util/CommonUtilsTest.java78
-rw-r--r--common/tests/robotests/src/com/android/tv/common/util/ContentUriUtilsTest.java48
-rw-r--r--gradle.properties3
-rw-r--r--jni/DvbManager.cpp132
-rw-r--r--jni/DvbManager.h9
-rw-r--r--jni/tunertvinput_jni.cpp62
-rwxr-xr-xjni/tunertvinput_jni.h23
-rw-r--r--libs/Android.bp92
-rw-r--r--libs/auto-factory-1.0-beta2.jarbin0 -> 56167 bytes
-rw-r--r--libs/auto-value-1.5.2.jarbin0 -> 1611730 bytes
-rw-r--r--libs/dagger-2.15.jarbin0 -> 39406 bytes
-rw-r--r--libs/dagger-android-2.15.aarbin0 -> 23228 bytes
-rw-r--r--libs/dagger-android-jarimpl-2.15.jarbin0 -> 28057 bytes
-rw-r--r--libs/dagger-android-processor-2.15.jarbin0 -> 111197 bytes
-rw-r--r--libs/dagger-android-support-2.15.aarbin0 -> 19089 bytes
-rw-r--r--libs/dagger-android-support-jarimpl-2.15.jarbin0 -> 11346 bytes
-rw-r--r--libs/dagger-compiler-2.15.jarbin0 -> 882144 bytes
-rw-r--r--libs/dagger-producers-2.15.jarbin0 -> 71006 bytes
-rw-r--r--libs/dagger-spi-2.15.jarbin0 -> 125799 bytes
-rw-r--r--libs/error_prone_annotations-2.3.1.jarbin0 -> 13162 bytes
-rw-r--r--libs/exoplayer-core-2.10.1.aarbin1510864 -> 0 bytes
-rw-r--r--libs/exoplayer-core-2.9.0.aarbin0 -> 1353252 bytes
-rw-r--r--libs/google-java-format-1.4-all-deps.jar (renamed from libs/google-java-format-1.7-all-deps.jar)bin6093741 -> 5437064 bytes
-rw-r--r--libs/guava-23.3-jre.jarbin0 -> 2655564 bytes
-rw-r--r--libs/guava-23.5-jre.jarbin0 -> 2658862 bytes
-rw-r--r--libs/guava-23.6-android.jarbin0 -> 2588045 bytes
-rw-r--r--libs/javapoet-1.8.0.jarbin0 -> 92125 bytes
-rw-r--r--libs/javawriter-2.5.1.jarbin0 -> 14012 bytes
-rw-r--r--libs/m2/animal-sniffer-annotations-1.17.jarbin3448 -> 0 bytes
-rw-r--r--libs/m2/auto-common-0.10.jarbin89662 -> 0 bytes
-rw-r--r--libs/m2/auto-factory-1.0-beta6.jarbin75628 -> 0 bytes
-rw-r--r--libs/m2/auto-value-1.5.3.jarbin1707494 -> 0 bytes
-rw-r--r--libs/m2/checker-qual-2.8.1.jarbin200629 -> 0 bytes
-rw-r--r--libs/m2/dagger-2.23.jarbin36812 -> 0 bytes
-rw-r--r--libs/m2/dagger-android-2.23.aarbin18638 -> 0 bytes
-rw-r--r--libs/m2/dagger-android-jarimpl-2.23.jarbin22436 -> 0 bytes
-rw-r--r--libs/m2/dagger-android-processor-2.23.jarbin116407 -> 0 bytes
-rw-r--r--libs/m2/dagger-compiler-2.23.jarbin1235381 -> 0 bytes
-rw-r--r--libs/m2/dagger-jarjar-rules.txt4
-rw-r--r--libs/m2/dagger-producers-2.23.jarbin96937 -> 0 bytes
-rw-r--r--libs/m2/dagger-spi-2.23.jarbin135080 -> 0 bytes
-rw-r--r--libs/m2/error_prone_annotations-2.3.2.jarbin13166 -> 0 bytes
-rw-r--r--libs/m2/failureaccess-1.0.1.jarbin4617 -> 0 bytes
-rw-r--r--libs/m2/guava-28.0-android.jarbin2601970 -> 0 bytes
-rw-r--r--libs/m2/guava-28.0-jre.jarbin2746681 -> 0 bytes
-rw-r--r--libs/m2/j2objc-annotations-1.3.jarbin8781 -> 0 bytes
-rw-r--r--libs/m2/javac-shaded-9-dev-r4023-3.jarbin2838187 -> 0 bytes
-rw-r--r--libs/m2/javapoet-1.11.1.jarbin99074 -> 0 bytes
-rw-r--r--libs/m2/jsr305-3.0.2.jarbin19936 -> 0 bytes
-rw-r--r--libs/m2/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jarbin2199 -> 0 bytes
-rw-r--r--libs/m2/pom-jre.xml47
-rw-r--r--libs/m2/pom.xml98
-rw-r--r--libs/m2/protobuf-java-3.7.0.jarbin1424558 -> 0 bytes
-rwxr-xr-xlibs/m2/update.sh37
-rw-r--r--libs/truth-0.36.jarbin0 -> 164334 bytes
-rw-r--r--libs/truth-0.45.jarbin257064 -> 0 bytes
-rw-r--r--partner_support/AndroidManifest.xml2
-rw-r--r--partner_support/g3doc/CloudEpgForPartners.md112
-rw-r--r--partner_support/g3doc/SeriesIdColumnForPartners.md30
-rw-r--r--partner_support/g3doc/TurnOffEmbeddedTuner.md15
-rw-r--r--partner_support/sample_customization/AndroidManifest.xml2
-rw-r--r--partner_support/samples/Android.bp25
-rw-r--r--partner_support/samples/Android.mk33
-rw-r--r--partner_support/samples/AndroidManifest.xml2
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/ChannelScanFragment.java8
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/LineupSelectionFragment.java13
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/LocationFragment.java8
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/ResultFragment.java8
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/SampleTvInputSetupActivity.java2
-rw-r--r--partner_support/samples/src/com/example/partnersupportsampletvinput/WelcomeFragment.java8
-rw-r--r--partner_support/src/com/google/android/tv/partner/support/EpgInput.java2
-rw-r--r--partner_support/src/com/google/android/tv/partner/support/TunerSetupUtils.java3
-rw-r--r--partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/BaseCustomizationTest.java8
-rw-r--r--partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/TunerSetupUtilsTest.java12
-rw-r--r--res/layout/details_overview.xml4
-rw-r--r--res/layout/dvr_details_description.xml2
-rw-r--r--res/layout/item_list.xml2
-rw-r--r--res/layout/option_fragment.xml2
-rw-r--r--res/layout/pin_dialog.xml4
-rw-r--r--res/layout/priority_settings_action_item.xml14
-rw-r--r--res/layout/program_guide_side_panel.xml4
-rw-r--r--res/values/arrays-custom.xml45
-rw-r--r--res/values/arrays.xml20
-rw-r--r--res/values/rating_system_strings.xml23
-rw-r--r--res/values/strings-custom.xml13
-rw-r--r--res/values/strings.xml73
-rw-r--r--res/xml/tv_content_rating_systems.xml223
-rw-r--r--settings.gradle2
-rw-r--r--src/com/android/tv/LauncherActivity.java8
-rw-r--r--src/com/android/tv/MainActivity.java116
-rw-r--r--src/com/android/tv/MediaSessionWrapper.java3
-rw-r--r--src/com/android/tv/SetupPassthroughActivity.java97
-rw-r--r--src/com/android/tv/TimeShiftManager.java25
-rw-r--r--src/com/android/tv/TvApplication.java128
-rw-r--r--src/com/android/tv/TvSingletons.java46
-rw-r--r--src/com/android/tv/app/LiveTvApplication.java67
-rw-r--r--src/com/android/tv/app/LiveTvApplicationComponent.java8
-rw-r--r--src/com/android/tv/app/LiveTvModule.java31
-rw-r--r--src/com/android/tv/data/BaseProgram.java208
-rw-r--r--src/com/android/tv/data/BaseProgramImpl.java86
-rw-r--r--src/com/android/tv/data/ChannelDataManager.java30
-rw-r--r--src/com/android/tv/data/InternalDataUtils.java7
-rw-r--r--src/com/android/tv/data/OnCurrentProgramUpdatedListener.java2
-rw-r--r--src/com/android/tv/data/PreviewDataManager.java15
-rw-r--r--src/com/android/tv/data/PreviewProgramContent.java10
-rw-r--r--src/com/android/tv/data/Program.java (renamed from src/com/android/tv/data/ProgramImpl.java)191
-rw-r--r--src/com/android/tv/data/ProgramDataManager.java190
-rw-r--r--src/com/android/tv/data/api/BaseProgram.java141
-rw-r--r--src/com/android/tv/data/api/Program.java141
-rw-r--r--src/com/android/tv/data/epg/EpgFetchHelper.java13
-rw-r--r--src/com/android/tv/data/epg/EpgFetchService.java14
-rw-r--r--src/com/android/tv/data/epg/EpgFetcherImpl.java56
-rw-r--r--src/com/android/tv/data/epg/EpgInputWhiteList.java16
-rw-r--r--src/com/android/tv/data/epg/EpgReader.java9
-rw-r--r--src/com/android/tv/data/epg/StubEpgReader.java10
-rw-r--r--src/com/android/tv/dialog/PinDialogFragment.java33
-rw-r--r--src/com/android/tv/dialog/picker/PinPicker.java131
-rw-r--r--src/com/android/tv/dialog/picker/TvPinPicker.java54
-rw-r--r--src/com/android/tv/dvr/DvrDataManagerImpl.java60
-rw-r--r--src/com/android/tv/dvr/DvrManager.java6
-rw-r--r--src/com/android/tv/dvr/DvrScheduleManager.java8
-rw-r--r--src/com/android/tv/dvr/DvrStorageStatusManager.java2
-rw-r--r--src/com/android/tv/dvr/DvrWatchedPositionManager.java4
-rw-r--r--src/com/android/tv/dvr/data/RecordedProgram.java5
-rw-r--r--src/com/android/tv/dvr/data/ScheduledRecording.java6
-rw-r--r--src/com/android/tv/dvr/data/SeriesRecording.java10
-rw-r--r--src/com/android/tv/dvr/provider/DvrContract.java9
-rw-r--r--src/com/android/tv/dvr/provider/DvrDatabaseHelper.java19
-rw-r--r--src/com/android/tv/dvr/provider/DvrDbFuture.java98
-rw-r--r--src/com/android/tv/dvr/provider/DvrDbSync.java24
-rw-r--r--src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java13
-rw-r--r--src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java12
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrConflictFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrScheduleFragment.java13
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java22
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java8
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java24
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java7
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java18
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java10
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrUiHelper.java54
-rw-r--r--src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/SortedArrayAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java25
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContent.java13
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java4
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java23
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java18
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingCardView.java18
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java24
-rw-r--r--src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java20
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java44
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java10
-rw-r--r--src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java3
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java3
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java7
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java19
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java18
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java65
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlayer.java13
-rw-r--r--src/com/android/tv/features/TvFeatures.java22
-rw-r--r--src/com/android/tv/guide/GenreListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramGrid.java17
-rw-r--r--src/com/android/tv/guide/ProgramGuide.java25
-rw-r--r--src/com/android/tv/guide/ProgramItemView.java22
-rw-r--r--src/com/android/tv/guide/ProgramListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramManager.java40
-rw-r--r--src/com/android/tv/guide/ProgramRow.java2
-rw-r--r--src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java4
-rw-r--r--src/com/android/tv/guide/ProgramTableAdapter.java44
-rw-r--r--src/com/android/tv/guide/TimeListAdapter.java2
-rw-r--r--src/com/android/tv/guide/TimelineGridView.java4
-rw-r--r--src/com/android/tv/menu/ActionCardView.java8
-rw-r--r--src/com/android/tv/menu/AppLinkCardView.java2
-rw-r--r--src/com/android/tv/menu/BaseCardView.java8
-rw-r--r--src/com/android/tv/menu/ChannelCardView.java4
-rw-r--r--src/com/android/tv/menu/ChannelsPosterPrefetcher.java4
-rw-r--r--src/com/android/tv/menu/ChannelsRow.java1
-rw-r--r--src/com/android/tv/menu/ChannelsRowAdapter.java14
-rw-r--r--src/com/android/tv/menu/ItemListRowView.java15
-rw-r--r--src/com/android/tv/menu/Menu.java2
-rw-r--r--src/com/android/tv/menu/MenuLayoutManager.java8
-rw-r--r--src/com/android/tv/menu/MenuRow.java17
-rw-r--r--src/com/android/tv/menu/MenuRowFactory.java17
-rw-r--r--src/com/android/tv/menu/MenuRowView.java16
-rw-r--r--src/com/android/tv/menu/MenuView.java59
-rw-r--r--src/com/android/tv/menu/PlayControlsButton.java8
-rw-r--r--src/com/android/tv/menu/PlayControlsRowView.java8
-rw-r--r--src/com/android/tv/menu/TvOptionsRowAdapter.java11
-rw-r--r--src/com/android/tv/modules/TvApplicationModule.java70
-rw-r--r--src/com/android/tv/modules/TvSingletonsModule.java7
-rw-r--r--src/com/android/tv/onboarding/OnboardingActivity.java4
-rw-r--r--src/com/android/tv/onboarding/SetupSourcesFragment.java63
-rw-r--r--src/com/android/tv/onboarding/WelcomeFragment.java8
-rw-r--r--src/com/android/tv/parental/ContentRatingsManager.java16
-rw-r--r--src/com/android/tv/parental/ParentalControlSettings.java8
-rw-r--r--src/com/android/tv/perf/PerformanceMonitor.java10
-rw-r--r--src/com/android/tv/perf/PerformanceMonitorManager.java38
-rw-r--r--src/com/android/tv/perf/PerformanceMonitorManagerFactory.java (renamed from common/src/com/android/tv/common/buildtype/BuildTypeFactory.java)30
-rw-r--r--src/com/android/tv/perf/StartupMeasure.java12
-rw-r--r--src/com/android/tv/perf/StartupMeasureFactory.java43
-rw-r--r--src/com/android/tv/perf/stub/StubPerformanceMonitor.java5
-rw-r--r--src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java (renamed from common/src/com/android/tv/common/flags/impl/DefaultSetupFlags.java)26
-rw-r--r--src/com/android/tv/receiver/AudioCapabilitiesReceiver.java2
-rw-r--r--src/com/android/tv/receiver/PackageIntentsReceiver.java2
-rw-r--r--src/com/android/tv/recommendation/ChannelPreviewUpdater.java5
-rw-r--r--src/com/android/tv/recommendation/ChannelRecord.java4
-rw-r--r--src/com/android/tv/recommendation/NotificationService.java4
-rw-r--r--src/com/android/tv/recommendation/RecommendationDataManager.java12
-rw-r--r--src/com/android/tv/recommendation/Recommender.java4
-rw-r--r--src/com/android/tv/recommendation/RoutineWatchEvaluator.java4
-rw-r--r--src/com/android/tv/recommendation/WatchedProgram.java2
-rw-r--r--src/com/android/tv/search/DataManagerSearch.java5
-rw-r--r--src/com/android/tv/search/LocalSearchProvider.java31
-rw-r--r--src/com/android/tv/search/ProgramGuideSearchFragment.java24
-rw-r--r--src/com/android/tv/search/TvProviderSearch.java2
-rw-r--r--src/com/android/tv/setup/SystemSetupActivity.java23
-rw-r--r--src/com/android/tv/ui/AppLayerTvView.java15
-rw-r--r--src/com/android/tv/ui/ChannelBannerView.java50
-rw-r--r--src/com/android/tv/ui/DetailsActivity.java19
-rw-r--r--src/com/android/tv/ui/GuidedActionsStylistWithDivider.java6
-rw-r--r--src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java2
-rw-r--r--src/com/android/tv/ui/ProgramDetailsFragment.java28
-rw-r--r--src/com/android/tv/ui/SelectInputView.java4
-rw-r--r--src/com/android/tv/ui/TunableTvView.java44
-rw-r--r--src/com/android/tv/ui/TvOverlayManager.java27
-rw-r--r--src/com/android/tv/ui/ViewUtils.java5
-rw-r--r--src/com/android/tv/ui/sidepanel/ChannelCheckItem.java3
-rw-r--r--src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java56
-rw-r--r--src/com/android/tv/ui/sidepanel/SettingsFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragment.java18
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java29
-rw-r--r--src/com/android/tv/util/AsyncDbTask.java34
-rw-r--r--src/com/android/tv/util/OnboardingUtils.java9
-rw-r--r--src/com/android/tv/util/SetupUtils.java3
-rw-r--r--src/com/android/tv/util/SqlParams.java (renamed from common/src/com/android/tv/common/util/sql/SqlParams.java)2
-rw-r--r--src/com/android/tv/util/TvInputManagerHelper.java29
-rw-r--r--src/com/android/tv/util/TvProviderUtils.java12
-rw-r--r--src/com/android/tv/util/TvTrackInfoUtils.java135
-rw-r--r--src/com/android/tv/util/Utils.java40
-rw-r--r--src/com/android/tv/util/account/AccountHelper.java7
-rw-r--r--src/com/android/tv/util/account/AccountHelperImpl.java12
-rw-r--r--src/com/android/tv/util/images/ImageLoader.java80
-rw-r--r--tests/common/Android.bp50
-rw-r--r--tests/common/Android.mk28
-rw-r--r--tests/common/AndroidManifest.xml2
-rw-r--r--tests/common/src/com/android/tv/testing/ChannelNumberSubject.java31
-rw-r--r--tests/common/src/com/android/tv/testing/ComparatorTester.java242
-rw-r--r--tests/common/src/com/android/tv/testing/EpgTestData.java12
-rw-r--r--tests/common/src/com/android/tv/testing/FakeClock.java (renamed from tests/common/src/com/android/tv/testing/fakes/FakeClock.java)2
-rw-r--r--tests/common/src/com/android/tv/testing/FakeEpgReader.java9
-rw-r--r--tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java3
-rw-r--r--tests/common/src/com/android/tv/testing/FakeTvProvider.java (renamed from tests/common/src/com/android/tv/testing/fakes/FakeTvProvider.java)4
-rw-r--r--tests/common/src/com/android/tv/testing/TestSingletonApp.java90
-rw-r--r--tests/common/src/com/android/tv/testing/constants/ConfigConstants.java2
-rw-r--r--tests/common/src/com/android/tv/testing/robo/ContentProviders.java40
-rw-r--r--tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java36
-rw-r--r--tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java89
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java4
-rw-r--r--tests/func/AndroidManifest.xml2
-rw-r--r--tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java2
-rw-r--r--tests/input/AndroidManifest.xml2
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputService.java2
-rw-r--r--tests/jank/AndroidManifest.xml2
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/Utils.java2
-rw-r--r--tests/robotests/Android.mk76
-rw-r--r--tests/robotests/README.md5
-rw-r--r--tests/robotests/src/com/android/tv/MainActivityRoboTest.java172
-rw-r--r--tests/robotests/src/com/android/tv/MediaSessionWrapperTest.java165
-rw-r--r--tests/robotests/src/com/android/tv/SetupPassthroughActivityTest.java447
-rw-r--r--tests/robotests/src/com/android/tv/ShadowTvView.java106
-rw-r--r--tests/robotests/src/com/android/tv/TvActivityTest.java48
-rw-r--r--tests/robotests/src/com/android/tv/audio/AudioManagerHelperTest.java262
-rw-r--r--tests/robotests/src/com/android/tv/data/ChannelNumberTest.java176
-rw-r--r--tests/robotests/src/com/android/tv/data/GenreItemTest.java95
-rw-r--r--tests/robotests/src/com/android/tv/data/PreviewDataManagerTest.java214
-rw-r--r--tests/robotests/src/com/android/tv/data/ProgramDataManagerTest.java316
-rw-r--r--tests/robotests/src/com/android/tv/data/ProgramTest.java276
-rw-r--r--tests/robotests/src/com/android/tv/data/TvInputNewComparatorTest.java102
-rw-r--r--tests/robotests/src/com/android/tv/data/WatchedHistoryManagerTest.java144
-rw-r--r--tests/robotests/src/com/android/tv/data/api/ProgramTest.java119
-rw-r--r--tests/robotests/src/com/android/tv/data/epg/EpgFetcherImplTest.java313
-rw-r--r--tests/robotests/src/com/android/tv/data/epg/EpgInputWhiteListTest.java129
-rw-r--r--tests/robotests/src/com/android/tv/dvr/BaseDvrDataManagerTest.java96
-rw-r--r--tests/robotests/src/com/android/tv/dvr/DvrDataManagerImplTest.java85
-rw-r--r--tests/robotests/src/com/android/tv/dvr/DvrScheduleManagerTest.java883
-rw-r--r--tests/robotests/src/com/android/tv/dvr/ScheduledRecordingTest.java126
-rw-r--r--tests/robotests/src/com/android/tv/dvr/data/SeriesRecordingTest.java147
-rw-r--r--tests/robotests/src/com/android/tv/dvr/provider/DvrDbSyncTest.java178
-rw-r--r--tests/robotests/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java92
-rw-r--r--tests/robotests/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java259
-rw-r--r--tests/robotests/src/com/android/tv/dvr/recorder/RecordingTaskTest.java164
-rw-r--r--tests/robotests/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java136
-rw-r--r--tests/robotests/src/com/android/tv/dvr/recorder/SchedulerTest.java136
-rw-r--r--tests/robotests/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java154
-rw-r--r--tests/robotests/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java255
-rw-r--r--tests/robotests/src/com/android/tv/dvr/ui/browse/DvrBrowseFragmentTest.java64
-rw-r--r--tests/robotests/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapterTest.java278
-rw-r--r--tests/robotests/src/com/android/tv/dvr/ui/playback/DvrPlayerTest.java76
-rw-r--r--tests/robotests/src/com/android/tv/guide/ProgramItemViewTest.java288
-rw-r--r--tests/robotests/src/com/android/tv/guide/ProgramTableAdapterTest.java125
-rw-r--r--tests/robotests/src/com/android/tv/search/FakeSearchInterface.java62
-rw-r--r--tests/robotests/src/com/android/tv/search/LocalSearchProviderTest.java257
-rw-r--r--tests/robotests/src/com/android/tv/testing/TvRobolectricTestRunner.java84
-rw-r--r--tests/robotests/src/com/android/tv/ui/ChannelBannerViewTest.java158
-rw-r--r--tests/robotests/src/com/android/tv/ui/hideable/AutoHideSchedulerTest.java117
-rw-r--r--tests/robotests/src/com/android/tv/util/MultiLongSparseArrayTest.java105
-rw-r--r--tests/robotests/src/com/android/tv/util/TvInputManagerHelperRoboTest.java52
-rw-r--r--tests/robotests/src/com/android/tv/util/TvProviderUtilsTest.java128
-rw-r--r--tests/robotests/src/com/android/tv/util/TvTrackInfoUtilsTest.java385
-rw-r--r--tests/robotests/src/com/android/tv/util/UtilsTest.java495
-rw-r--r--tests/unit/Android.mk2
-rw-r--r--tests/unit/AndroidManifest.xml2
-rw-r--r--tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java24
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java52
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelImplTest.java48
-rw-r--r--tests/unit/src/com/android/tv/features/FeaturesTest.java36
-rw-r--r--tests/unit/src/com/android/tv/menu/MenuTest.java7
-rw-r--r--tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java29
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java25
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java31
-rw-r--r--tests/unit/src/com/android/tv/util/MockTvSingletons.java45
-rw-r--r--tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java57
-rw-r--r--tests/unit/src/com/android/tv/util/images/ImageCacheTest.java12
-rw-r--r--tuner/Android.bp20
-rw-r--r--tuner/AndroidManifest.xml2
-rwxr-xr-xtuner/SampleDvbTuner/AndroidManifest.xml4
-rw-r--r--tuner/SampleDvbTuner/build.gradle71
-rw-r--r--tuner/SampleDvbTuner/robotests/javatests/com/android/tv/tuner/sample/dvb/util/SampleDvbConstantsTest.java45
-rw-r--r--tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/AndroidManifest.xml4
-rw-r--r--tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTuner.java21
-rw-r--r--tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerModule.java18
-rw-r--r--tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/setup/SampleDvbTunerSetupActivity.java8
-rw-r--r--tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/util/SampleDvbConstants.java26
-rwxr-xr-xtuner/SampleNetworkTuner/AndroidManifest.xml5
-rw-r--r--tuner/SampleNetworkTuner/build.gradle71
-rw-r--r--tuner/SampleNetworkTuner/robotests/javatests/com/android/tv/tuner/sample/network/util/SampleNetworkConstantsTest.java45
-rw-r--r--tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/AndroidManifest.xml5
-rw-r--r--tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTuner.java21
-rw-r--r--tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerModule.java18
-rw-r--r--tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/setup/SampleNetworkTunerSetupActivity.java7
-rw-r--r--tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/util/SampleNetworkConstants.java26
-rw-r--r--tuner/build.gradle90
-rw-r--r--tuner/proto/Android.bp3
-rw-r--r--tuner/proto/channel.proto45
-rw-r--r--tuner/proto/track.proto9
-rw-r--r--tuner/res/layout/guided_action_editable.xml10
-rw-r--r--tuner/res/raw/ut_euro_dvbt_all65
-rw-r--r--tuner/src/com/android/tv/tuner/DvbDeviceAccessor.java (renamed from tuner/src/com/android/tv/tuner/dvb/DvbDeviceAccessor.java)2
-rw-r--r--tuner/src/com/android/tv/tuner/DvbTunerHal.java (renamed from tuner/src/com/android/tv/tuner/dvb/DvbTunerHal.java)5
-rw-r--r--tuner/src/com/android/tv/tuner/TunerHal.java85
-rw-r--r--tuner/src/com/android/tv/tuner/api/ScanChannel.java47
-rw-r--r--tuner/src/com/android/tv/tuner/api/Tuner.java15
-rw-r--r--tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java (renamed from tuner/src/com/android/tv/tuner/dvb/DvbTunerHalFactory.java)37
-rw-r--r--tuner/src/com/android/tv/tuner/cc/CaptionLayout.java2
-rw-r--r--tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java4
-rw-r--r--tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java6
-rw-r--r--tuner/src/com/android/tv/tuner/data/Cea708Parser.java18
-rw-r--r--tuner/src/com/android/tv/tuner/data/PsiData.java4
-rw-r--r--tuner/src/com/android/tv/tuner/data/PsipData.java14
-rw-r--r--tuner/src/com/android/tv/tuner/data/SectionParser.java94
-rw-r--r--tuner/src/com/android/tv/tuner/data/TunerChannel.java342
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java129
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java27
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java7
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java40
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/MpegTsSampleExtractor.java49
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java3
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java9
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java5
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java40
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java67
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer2/VideoRendererExoV2.java25
-rw-r--r--tuner/src/com/android/tv/tuner/features/TunerFeatures.java9
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunChannelScan.java206
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunControlSocket.java226
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDevice.java177
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDiscover.java446
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunInterface.java134
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHal.java250
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHalFactory.java62
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerManager.java122
-rw-r--r--tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunUtils.java194
-rw-r--r--tuner/src/com/android/tv/tuner/modules/TunerModule.java79
-rw-r--r--tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java12
-rw-r--r--tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java1
-rw-r--r--tuner/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java7
-rw-r--r--tuner/src/com/android/tv/tuner/setup/LineupFragment.java4
-rw-r--r--tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java119
-rw-r--r--tuner/src/com/android/tv/tuner/setup/LocationFragment.java18
-rw-r--r--tuner/src/com/android/tv/tuner/setup/PostalCodeFragment.java6
-rw-r--r--tuner/src/com/android/tv/tuner/setup/ScanFragment.java90
-rw-r--r--tuner/src/com/android/tv/tuner/setup/ScanResultFragment.java4
-rw-r--r--tuner/src/com/android/tv/tuner/setup/WelcomeFragment.java4
-rw-r--r--tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java15
-rw-r--r--tuner/src/com/android/tv/tuner/source/FileSourceEventDetector.java4
-rw-r--r--tuner/src/com/android/tv/tuner/source/FileTsStreamer.java25
-rw-r--r--tuner/src/com/android/tv/tuner/source/TsDataSource.java2
-rw-r--r--tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java2
-rw-r--r--tuner/src/com/android/tv/tuner/source/TunerTsStreamer.java43
-rw-r--r--tuner/src/com/android/tv/tuner/ts/EventDetector.java22
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java78
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java49
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java126
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerSession.java28
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java28
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerSessionOverlay.java10
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java165
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java156
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/datamanager/ChannelDataManager.java15
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/factory/TunerRecordingSessionFactory.java41
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java34
-rw-r--r--tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java49
-rw-r--r--tuner/tests/robotests/Android.mk68
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/data/SectionParserTest.java181
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/dvb/DvbTunerHalTest.java93
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/AssetDataSource.java134
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/SampleSourceExtractorTest.java298
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/testing/TvTunerRobolectricTestRunner.java74
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java201
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java200
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/datamanager/ChannelDataManagerTest.java90
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/util/PostalCodeUtilsTest.java84
-rw-r--r--tuner/tests/testing/Android.mk2
-rw-r--r--tuner/tests/testing/AndroidManifest.xml2
-rw-r--r--tuner/tests/unittests/javatests/AndroidManifest.xml2
-rw-r--r--tuner/tests/unittests/javatests/com/android/tv/tuner/AndroidManifest.xml4
-rw-r--r--tuner/tests/unittests/javatests/com/android/tv/tuner/ZappingTimeTest.java43
-rw-r--r--tuner/tests/unittests/javatests/com/android/tv/tuner/layout/tests/AndroidManifest.xml2
-rw-r--r--tuner/tests/unittests/javatests/com/android/tv/tuner/setup/AndroidManifest.xml31
-rw-r--r--tuner/tests/unittests/javatests/com/android/tv/tuner/setup/TunerHalCreatorTest.java8
537 files changed, 4194 insertions, 20555 deletions
diff --git a/Android.bp b/Android.bp
index 83c232b1..42686365 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,8 +14,8 @@
// limitations under the License.
//
-version_name = "1.23-asop"
-version_code = "417000410"
+version_name = "1.20-asop"
+version_code = "417000328"
android_app {
name: "LiveTv",
@@ -44,13 +44,16 @@ android_app {
static_libs: [
"android-support-annotations",
"android-support-compat",
- "android-support-v7-recyclerview",
- "androidx.legacy_legacy-support-core-ui",
- "androidx.leanback_leanback",
- "androidx.leanback_leanback-preference",
- "androidx.palette_palette",
- "androidx.preference_preference",
+ "android-support-core-ui",
"androidx.tvprovider_tvprovider",
+ "android-support-v4",
+ "android-support-v7-appcompat",
+ "android-support-v7-palette",
+ "android-support-v7-preference",
+ "android-support-v7-recyclerview",
+ "android-support-v14-preference",
+ "android-support-v17-leanback",
+ "android-support-v17-preference-leanback",
"jsr330",
"live-channels-partner-support",
"live-tv-tuner-proto",
@@ -59,7 +62,6 @@ android_app {
"tv-auto-factory-jar",
"tv-common",
"tv-error-prone-annotations-jar",
- "tv-javax-annotations-jar",
"tv-lib-dagger",
"tv-lib-exoplayer",
"tv-lib-exoplayer-v2-core",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7110160f..a3988239 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,12 +16,12 @@
-->
<!-- This manifest is for LiveTv -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.tv" >
<uses-sdk
android:minSdkVersion="23"
- android:targetSdkVersion="28" />
+ android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -79,7 +79,8 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.TV"
- tools:replace="android:appComponentFactory" >
+ tools:replace="android:appComponentFactory">
+ >
<!-- providers are listed here to keep them separate from the internal versions -->
<provider
@@ -253,16 +254,12 @@
android:name="com.android.tv.recommendation.ChannelPreviewUpdater$ChannelPreviewUpdateService"
android:permission="android.permission.BIND_JOB_SERVICE" />
- <receiver
- android:name="com.android.tv.receiver.BootCompletedReceiver"
- android:exported="true" >
+ <receiver android:name="com.android.tv.receiver.BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
- <receiver
- android:name="com.android.tv.receiver.PackageIntentsReceiver"
- android:exported="true" >
+ <receiver android:name="com.android.tv.receiver.PackageIntentsReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<!-- PACKAGE_CHANGED for package enabled/disabled notification -->
@@ -293,13 +290,11 @@
android:name="com.android.tv.dvr.recorder.DvrRecordingService"
android:label="@string/dvr_service_name" />
- <receiver
- android:name="com.android.tv.dvr.recorder.DvrStartRecordingReceiver"
- android:exported="false" />
+ <receiver android:name="com.android.tv.dvr.recorder.DvrStartRecordingReceiver" />
<service
android:name="com.android.tv.data.epg.EpgFetchService"
android:permission="android.permission.BIND_JOB_SERVICE" />
</application>
-</manifest> \ No newline at end of file
+</manifest>
diff --git a/README.md b/README.md
index 0659bbd5..63c1f449 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,18 @@
__Live TV__ is the Open Source reference application for watching TV on Android TVs.
+## Source
+
+The source of truth is an internal google repository (aka google3) at
+cs/third_party/java_src/android_app/live_channels
+
+Changes are made in the google3 repository and automatically pushed here.
+
+The following files are only in the android repository and must be changed there.
+
+* *.mk
+* \*\*/lib/\*.\*
+
## AOSP instructions
To install LiveTv
diff --git a/assets/rating_sources.html b/assets/rating_sources.html
index ff4a0052..50da7cc7 100644
--- a/assets/rating_sources.html
+++ b/assets/rating_sources.html
@@ -89,22 +89,4 @@
<pre>
Source: http://www.mpaa.org/film-ratings/
</pre>
-<ul>
- <li>TV content rating system strings for DTMB</li>
-</ul>
-<pre>
- Source: http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=59E83CA701AEB4248E115BC043688FEC
-</pre>
-<ul>
- <li>Implementations details of TV content rating system strings for New Zealand</li>
-</ul>
-<pre>
- Source: https://bsa.govt.nz/images/03_BSA_FREE-TO-AIR-TV_CLASSIFICATIONS_DRAFT.pdf
-</pre>
-<ul>
- <li>TV content rating system strings for Thailand</li>
-</ul>
-<pre>
- Source: https://broadcast.nbtc.go.th/law/dwl.php?id=NjAwODAwMDAwMDAx&file=ZGF0YS9kb2N1bWVudC9sYXcvZG9jL3RoLzYwMDgwMDAwMDAwMS5wZGY=
-</pre>
</body></html>
diff --git a/build.gradle b/build.gradle
index 10cddcc1..23e3dbd1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,28 +18,37 @@
/*
* Experimental gradle configuration. This file may not be up to date.
*/
-apply plugin: 'com.android.application'
buildscript {
repositories {
+ mavenCentral()
google()
- jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.4.2'
- classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'
}
}
-
+apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
-
- compileOptions() {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ dexOptions {
+ preDexLibraries = false
+ additionalParameters=['--core-library']
+ javaMaxHeapSize "6g"
+ }
+ android {
+ defaultConfig {
+ resConfigs "en"
+ }
+ }
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
}
-
buildTypes {
debug {
minifyEnabled false
@@ -48,15 +57,10 @@ android {
minifyEnabled true
}
}
-
- defaultConfig {
- minSdkVersion 23
- resConfigs "en"
- targetSdkVersion 28
- versionCode 1
- versionName "1.0"
+ compileOptions() {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
-
sourceSets {
main {
res.srcDirs = ['res', 'material_res']
@@ -66,33 +70,30 @@ android {
}
}
-allprojects {
- repositories {
- google()
- jcenter()
- }
+repositories {
+ mavenCentral()
+ jcenter()
+ google()
}
dependencies {
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.core:core:1.0.2'
- implementation 'androidx.palette:palette:1.0.0'
- implementation 'androidx.leanback:leanback:1.1.0-alpha02'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
- implementation 'androidx.tvprovider:tvprovider:1.0.0'
-
- annotationProcessor 'com.google.auto.factory:auto-factory:1.0-beta6'
- implementation 'com.google.auto.factory:auto-factory:1.0-beta6'
- annotationProcessor 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.dagger:dagger:2.23'
- implementation 'com.google.dagger:dagger-android:2.23'
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.23'
- annotationProcessor 'com.google.dagger:dagger-compiler:2.23'
- implementation 'com.google.guava:guava:28.0-jre'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.palette:palette:1.0.0'
+ implementation 'androidx.leanback:leanback:1.0.0'
+ implementation "androidx.tvprovider:tvprovider:1.0.0"
+ implementation "androidx.recyclerview:recyclerview:1.0.0"
+ implementation "androidx.recyclerview:recyclerview-selection:1.0.0"
+ implementation "androidx.palette:palette:1.0.0"
- implementation 'javax.inject:javax.inject:1'
+ implementation 'com.google.dagger:dagger:2.18'
+ implementation 'com.google.dagger:dagger-android:2.18'
+ annotationProcessor 'com.google.dagger:dagger-compiler:2.18'
+ annotationProcessor 'com.google.dagger:dagger-android-processor:2.18'
- implementation project(':common')
-}
+ /*Not building with latest one (1.6.3)*/
+ annotationProcessor 'com.google.auto.value:auto-value:1.5.4'
+ implementation 'com.google.auto.value:auto-value:1.5.4'
+ implementation 'javax.inject:javax.inject:1'
+ implementation 'com.google.guava:guava:26.0-android'
+ implementation project(':common')
+} \ No newline at end of file
diff --git a/common/Android.bp b/common/Android.bp
index 728587f6..63759d40 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -28,28 +28,22 @@ android_library {
resource_dirs: ["res"],
libs: [
- "android-support-annotations",
"tv-auto-value-jar",
"tv-auto-factory-jar",
+ "android-support-annotations",
"tv-error-prone-annotations-jar",
- "tv-javax-annotations-jar",
-
+ "tv-guava-android-jar",
+ "jsr330",
+ "tv-lib-dagger",
+ "tv-lib-exoplayer",
+ "tv-lib-exoplayer-v2-core",
+ "android-support-compat",
+ "android-support-core-ui",
+ "android-support-v7-recyclerview",
+ "android-support-v17-leanback",
],
- static_libs: [
- "androidx.legacy_legacy-support-core-ui",
- "androidx.appcompat_appcompat",
- "androidx.preference_preference",
- "androidx.leanback_leanback",
- "androidx.tvprovider_tvprovider",
- "tv-guava-android-jar",
- "tv-guava-failureaccess-jar",
- "jsr330",
- "tv-lib-dagger",
- "tv-lib-exoplayer",
- "tv-lib-exoplayer-v2-core",
- "tv-lib-dagger-android",
- ],
+ static_libs: ["tv-lib-dagger-android"],
plugins: [
"tv-auto-value",
diff --git a/common/AndroidManifest.xml b/common/AndroidManifest.xml
index eb7de572..7002d5fb 100644
--- a/common/AndroidManifest.xml
+++ b/common/AndroidManifest.xml
@@ -17,6 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.common"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application />
</manifest>
diff --git a/common/build.gradle b/common/build.gradle
index b7bc8865..f3714758 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -21,24 +21,37 @@
apply plugin: 'com.android.library'
apply plugin: 'com.google.protobuf'
-
+buildscript {
+ repositories {
+ mavenCentral()
+ google()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'
+ }
+}
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
+ dexOptions {
+ preDexLibraries = false
+ additionalParameters = ['--core-library']
+ javaMaxHeapSize "6g"
+ }
- compileOptions() {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ android {
+ defaultConfig {
+ resConfigs "en"
+ }
}
defaultConfig {
minSdkVersion 23
- resConfigs "en"
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
-
buildTypes {
debug {
minifyEnabled false
@@ -53,6 +66,10 @@ android {
buildConfigField "boolean", "NO_JNI_TEST", "false"
}
}
+ compileOptions() {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
sourceSets {
main {
@@ -62,32 +79,29 @@ android {
proto {
srcDir 'src/com/android/tv/common/compat/internal'
}
- proto {
- srcDir 'src/com/android/tv/common/flags/proto'
- }
}
}
}
-dependencies {
- implementation 'androidx.annotation:annotation:1.1.0'
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.leanback:leanback:1.1.0-alpha02'
- implementation 'androidx.palette:palette:1.0.0'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
- implementation 'androidx.tvprovider:tvprovider:1.0.0'
+repositories {
+ mavenCentral()
+ google()
+}
- implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'
- implementation 'com.google.android.exoplayer:exoplayer-core:2.10.1'
- annotationProcessor 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.dagger:dagger:2.23'
- implementation 'com.google.dagger:dagger-android:2.23'
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.23'
- annotationProcessor 'com.google.dagger:dagger-compiler:2.23'
- implementation 'com.google.guava:guava:28.0-jre'
- implementation 'com.google.protobuf:protobuf-java:3.0.0'
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.palette:palette:1.0.0'
+ implementation 'androidx.leanback:leanback:1.0.0'
+ implementation "androidx.tvprovider:tvprovider:1.0.0"
+ implementation "androidx.recyclerview:recyclerview:1.0.0"
+ implementation "androidx.recyclerview:recyclerview-selection:1.0.0"
+ implementation "androidx.palette:palette:1.0.0"
+ implementation 'com.google.guava:guava:26.0-android'
+ implementation 'com.google.protobuf:protobuf-java:3.0.0'
+ implementation 'com.google.dagger:dagger:2.18'
+ implementation 'com.google.dagger:dagger-android:2.18'
+ annotationProcessor 'com.google.dagger:dagger-compiler:2.18'
+ annotationProcessor 'com.google.dagger:dagger-android-processor:2.18'
}
protobuf {
// Configure the protoc executable
diff --git a/common/src/com/android/tv/common/BaseApplication.java b/common/src/com/android/tv/common/BaseApplication.java
index 1a421209..45c32567 100644
--- a/common/src/com/android/tv/common/BaseApplication.java
+++ b/common/src/com/android/tv/common/BaseApplication.java
@@ -21,22 +21,17 @@ import android.content.Context;
import android.os.Build;
import android.os.StrictMode;
import android.support.annotation.VisibleForTesting;
-
-import com.android.tv.common.dev.DeveloperPreferences;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.util.Clock;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
-
-import dagger.Lazy;
+import com.android.tv.common.util.SystemProperties;
import dagger.android.DaggerApplication;
-import javax.inject.Inject;
-
-/** The base application class for TV applications. */
+/** The base application class for Live TV applications. */
public abstract class BaseApplication extends DaggerApplication implements BaseSingletons {
- @Inject Lazy<RecordingStorageStatusManager> mRecordingStorageStatusManager;
+ private RecordingStorageStatusManager mRecordingStorageStatusManager;
/**
* An instance of {@link BaseSingletons}. Note that this can be set directly only for the test
@@ -70,7 +65,7 @@ public abstract class BaseApplication extends DaggerApplication implements BaseS
// Only set StrictMode for ENG builds because the build server only produces userdebug
// builds.
- if (BuildConfig.ENG && DeveloperPreferences.ALLOW_STRICT_MODE.get(this)) {
+ if (BuildConfig.ENG && SystemProperties.ALLOW_STRICT_MODE.getValue()) {
StrictMode.ThreadPolicy.Builder threadPolicyBuilder =
new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog();
// TODO(b/69565157): Turn penaltyDeath on for VMPolicy when tests are fixed.
@@ -104,6 +99,9 @@ public abstract class BaseApplication extends DaggerApplication implements BaseS
@Override
@TargetApi(Build.VERSION_CODES.N)
public RecordingStorageStatusManager getRecordingStorageStatusManager() {
- return mRecordingStorageStatusManager.get();
+ if (mRecordingStorageStatusManager == null) {
+ mRecordingStorageStatusManager = new RecordingStorageStatusManager(this);
+ }
+ return mRecordingStorageStatusManager;
}
}
diff --git a/common/src/com/android/tv/common/BaseSingletons.java b/common/src/com/android/tv/common/BaseSingletons.java
index 8a3820d1..10530617 100644
--- a/common/src/com/android/tv/common/BaseSingletons.java
+++ b/common/src/com/android/tv/common/BaseSingletons.java
@@ -18,28 +18,15 @@ package com.android.tv.common;
import com.android.tv.common.buildtype.HasBuildType;
import com.android.tv.common.flags.has.HasCloudEpgFlags;
+import com.android.tv.common.flags.has.HasConcurrentDvrPlaybackFlags;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.util.Clock;
/** Injection point for the base app */
-public interface BaseSingletons extends HasCloudEpgFlags, HasBuildType {
+public interface BaseSingletons
+ extends HasCloudEpgFlags, HasBuildType, HasConcurrentDvrPlaybackFlags {
- /*
- * Do not add any new methods here.
- *
- * To move a getter to Injection.
- * 1. Make a type injectable @Singleton.
- * 2. Mark the getter here as deprecated.
- * 3. Lazily inject the object in TvApplication.
- * 4. Move easy usages of getters to injection instead.
- * 5. Delete the method when all usages are migrated.
- */
-
- /* @deprecated use injection instead. */
- @Deprecated
Clock getClock();
- /* @deprecated use injection instead. */
- @Deprecated
RecordingStorageStatusManager getRecordingStorageStatusManager();
}
diff --git a/common/src/com/android/tv/common/buildtype/BuildTypeModule.java b/common/src/com/android/tv/common/buildtype/BuildTypeModule.java
deleted file mode 100644
index 43f398d5..00000000
--- a/common/src/com/android/tv/common/buildtype/BuildTypeModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.buildtype;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-
-/** Provides BuildType */
-@Module
-public class BuildTypeModule {
- private static final HasBuildType.BuildType BUILD_TYPE =
- BuildTypeFactory.create().getBuildType();
-
- @Provides
- @Reusable
- HasBuildType.BuildType providesBuildType() {
- return BUILD_TYPE;
- }
-}
diff --git a/common/src/com/android/tv/common/buildtype/HasBuildType.java b/common/src/com/android/tv/common/buildtype/HasBuildType.java
index addac07e..7d5677c9 100644
--- a/common/src/com/android/tv/common/buildtype/HasBuildType.java
+++ b/common/src/com/android/tv/common/buildtype/HasBuildType.java
@@ -30,7 +30,5 @@ public interface HasBuildType {
PROD
}
- /** @deprecated use injection instead. */
- @Deprecated
BuildType getBuildType();
}
diff --git a/common/src/com/android/tv/common/compat/TvInputInfoCompat.java b/common/src/com/android/tv/common/compat/TvInputInfoCompat.java
index 2f06d943..685a3ed9 100644
--- a/common/src/com/android/tv/common/compat/TvInputInfoCompat.java
+++ b/common/src/com/android/tv/common/compat/TvInputInfoCompat.java
@@ -45,12 +45,13 @@ public class TvInputInfoCompat {
private final Context mContext;
private final TvInputInfo mTvInputInfo;
- private boolean mAudioOnly;
- private boolean mAudioAttributeInit = false;
+ private final boolean mAudioOnly;
public TvInputInfoCompat(Context context, TvInputInfo tvInputInfo) {
mContext = context;
mTvInputInfo = tvInputInfo;
+ // TODO(b/112938832): use tvInputInfo.isAudioOnly() when SDK is updated
+ mAudioOnly = Boolean.parseBoolean(getExtras().get(ATTRIBUTE_NAME_AUDIO_ONLY));
}
public TvInputInfo getTvInputInfo() {
@@ -58,11 +59,6 @@ public class TvInputInfoCompat {
}
public boolean isAudioOnly() {
- // TODO(b/112938832): use tvInputInfo.isAudioOnly() when SDK is updated
- if (!mAudioAttributeInit) {
- mAudioOnly = Boolean.parseBoolean(getExtras().get(ATTRIBUTE_NAME_AUDIO_ONLY));
- mAudioAttributeInit = true;
- }
return mAudioOnly;
}
diff --git a/common/src/com/android/tv/common/compat/internal/recording_commands.proto b/common/src/com/android/tv/common/compat/internal/recording_commands.proto
index c247e781..ce59bfa0 100644
--- a/common/src/com/android/tv/common/compat/internal/recording_commands.proto
+++ b/common/src/com/android/tv/common/compat/internal/recording_commands.proto
@@ -19,7 +19,6 @@
// package and should not be used outside it.
syntax = "proto3";
-
package android.tv.common.compat.internal;
option java_outer_classname = "RecordingCommands";
diff --git a/common/src/com/android/tv/common/compat/internal/recording_events.proto b/common/src/com/android/tv/common/compat/internal/recording_events.proto
index fffa62ab..68db5ddf 100644
--- a/common/src/com/android/tv/common/compat/internal/recording_events.proto
+++ b/common/src/com/android/tv/common/compat/internal/recording_events.proto
@@ -18,7 +18,6 @@
// support new features on older devices. NOTE: this proto is internal to this
// package and should not be used outside it.
syntax = "proto3";
-
package android.tv.common.compat.internal;
option java_outer_classname = "RecordingEvents";
@@ -47,3 +46,4 @@ message RecordingStarted {
// Recording URI.
string uri = 1;
}
+
diff --git a/common/src/com/android/tv/common/compat/internal/tif_commands.proto b/common/src/com/android/tv/common/compat/internal/tif_commands.proto
index b69d4870..d5867703 100644
--- a/common/src/com/android/tv/common/compat/internal/tif_commands.proto
+++ b/common/src/com/android/tv/common/compat/internal/tif_commands.proto
@@ -19,7 +19,6 @@
// package and should not be used outside it.
syntax = "proto3";
-
package android.tv.common.compat.internal;
option java_outer_classname = "Commands";
diff --git a/common/src/com/android/tv/common/compat/internal/tif_events.proto b/common/src/com/android/tv/common/compat/internal/tif_events.proto
index b15a884a..6e71ae11 100644
--- a/common/src/com/android/tv/common/compat/internal/tif_events.proto
+++ b/common/src/com/android/tv/common/compat/internal/tif_events.proto
@@ -18,7 +18,6 @@
// support new features on older devices. NOTE: this proto is internal to this
// package and should not be used outside it.
syntax = "proto3";
-
package android.tv.common.compat.internal;
option java_outer_classname = "Events";
diff --git a/common/src/com/android/tv/common/customization/CustomizationManager.java b/common/src/com/android/tv/common/customization/CustomizationManager.java
index 5a29d7c0..09ecaef8 100644
--- a/common/src/com/android/tv/common/customization/CustomizationManager.java
+++ b/common/src/com/android/tv/common/customization/CustomizationManager.java
@@ -97,8 +97,8 @@ public class CustomizationManager {
/**
* Returns {@code true} if there's a customization package installed and it specifies built-in
- * tuner devices are available. The built-in tuner should support DVB API to be recognized by TV
- * app.
+ * tuner devices are available. The built-in tuner should support DVB API to be recognized by
+ * Live TV.
*/
public static boolean hasLinuxDvbBuiltInTuner(Context context) {
if (sHasLinuxDvbBuiltInTuner == null) {
@@ -156,26 +156,11 @@ public class CustomizationManager {
private static String getCustomizationPackageName(Context context) {
if (sCustomizationPackage == null) {
- sCustomizationPackage = "";
List<PackageInfo> packageInfos =
context.getPackageManager()
.getPackagesHoldingPermissions(CUSTOMIZE_PERMISSIONS, 0);
- if (packageInfos.size() != 0) {
- /** Iterate through all packages returning the first vendor customizer */
- for (PackageInfo packageInfo : packageInfos) {
- if (packageInfo.packageName.startsWith("com.android") == false) {
- sCustomizationPackage = packageInfo.packageName;
- break;
- }
- }
-
- /** If no vendor package found, return first in the list */
- if (sCustomizationPackage == "") {
- sCustomizationPackage = packageInfos.get(0).packageName;
- }
- }
+ sCustomizationPackage = packageInfos.size() == 0 ? "" : packageInfos.get(0).packageName;
}
-
return sCustomizationPackage;
}
diff --git a/common/src/com/android/tv/common/dagger/ApplicationModule.java b/common/src/com/android/tv/common/dagger/ApplicationModule.java
index be9cf885..4655f777 100644
--- a/common/src/com/android/tv/common/dagger/ApplicationModule.java
+++ b/common/src/com/android/tv/common/dagger/ApplicationModule.java
@@ -21,10 +21,8 @@ import android.content.Context;
import android.os.Looper;
import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.dagger.annotations.MainLooper;
-import com.android.tv.common.util.Clock;
import dagger.Module;
import dagger.Provides;
-import dagger.Reusable;
/**
* Provides application-scope qualifiers for the {@link Application}, the application context, and
@@ -59,10 +57,4 @@ public final class ApplicationModule {
ContentResolver provideContentResolver() {
return mApplication.getContentResolver();
}
-
- @Provides
- @Reusable
- static Clock providesClock() {
- return Clock.SYSTEM;
- }
}
diff --git a/common/src/com/android/tv/common/dagger/init/SafePreDaggerInitializer.java b/common/src/com/android/tv/common/dagger/init/SafePreDaggerInitializer.java
deleted file mode 100644
index 9465d929..00000000
--- a/common/src/com/android/tv/common/dagger/init/SafePreDaggerInitializer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.dagger.init;
-
-import android.content.Context;
-import android.util.Log;
-
-/**
- * Initializes objects one time only.
- *
- * <p>This is needed because ContentProviders can be created before Application.onCreate
- */
-public final class SafePreDaggerInitializer {
- private interface Initialize {
- void init(Context context);
- }
-
- private static final String TAG = "SafePreDaggerInitializer";
-
- private static boolean initialized = false;
- private static Context oldContext;
-
- private static final Initialize[] sList =
- new Initialize[] {
- /* Begin_AOSP_Comment_Out
- com.google.android.libraries.phenotype.client.PhenotypeContext::setContext
- End_AOSP_Comment_Out */
- };
-
- public static synchronized void init(Context context) {
- if (!initialized) {
- for (Initialize i : sList) {
- i.init(context);
- }
- oldContext = context;
- initialized = true;
- } else if (oldContext != context) {
- Log.w(
- TAG,
- "init called more than once, skipping. Old context was "
- + oldContext
- + " new context is "
- + context);
- }
- }
-
- private SafePreDaggerInitializer() {}
-}
diff --git a/common/src/com/android/tv/common/dev/DeveloperPreference.java b/common/src/com/android/tv/common/dev/DeveloperPreference.java
deleted file mode 100644
index b1c401b0..00000000
--- a/common/src/com/android/tv/common/dev/DeveloperPreference.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.dev;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-
-/** Preferences available to developers */
-public abstract class DeveloperPreference<T> {
-
- private static final String PREFERENCE_FILE_NAME =
- "com.android.tv.common.dev.DeveloperPreference";
-
- /**
- * Create a boolean developer preference.
- *
- * @param key the developer setting key.
- * @param defaultValue the value to return if the setting is undefined or empty.
- */
- public static DeveloperPreference<Boolean> create(String key, boolean defaultValue) {
- return new DeveloperBooleanPreference(key, defaultValue);
- }
-
- @VisibleForTesting
- static final SharedPreferences getPreferences(Context context) {
- return context.getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_PRIVATE);
- }
-
- /**
- * Create a int developer preference.
- *
- * @param key the developer setting key.
- * @param defaultValue the value to return if the setting is undefined or empty.
- */
- public static DeveloperPreference<Integer> create(String key, int defaultValue) {
- return new DeveloperIntegerPreference(key, defaultValue);
- }
-
- final String mKey;
- final T mDefaultValue;
- private T mValue;
-
- private DeveloperPreference(String key, T defaultValue) {
- mKey = key;
- mValue = null;
- mDefaultValue = defaultValue;
- }
-
- /** Set the value. */
- public final void set(Context context, T value) {
- mValue = value;
- storeValue(context, value);
- }
-
- protected abstract void storeValue(Context context, T value);
-
- /** Get the current value, or the default if the value is not set. */
- public final T get(Context context) {
- mValue = getStoredValue(context);
- return mValue;
- }
-
- /** Get the current value, or the default if the value is not set or context is null. */
- public final T getDefaultIfContextNull(@Nullable Context context) {
- return context == null ? mDefaultValue : getStoredValue(context);
- }
-
- protected abstract T getStoredValue(Context context);
-
- /**
- * Clears the current value.
- *
- * <p>Future calls to {@link #get(Context)} will return the default value.
- */
- public final void clear(Context context) {
- getPreferences(context).edit().remove(mKey);
- }
-
- @Override
- public final String toString() {
- return "[" + mKey + "]=" + mValue + " Default value : " + mDefaultValue;
- }
-
- private static final class DeveloperBooleanPreference extends DeveloperPreference<Boolean> {
-
- private DeveloperBooleanPreference(String key, Boolean defaultValue) {
- super(key, defaultValue);
- }
-
- @Override
- public void storeValue(Context context, Boolean value) {
- getPreferences(context).edit().putBoolean(mKey, value).apply();
- }
-
- @Override
- public Boolean getStoredValue(Context context) {
- return getPreferences(context).getBoolean(mKey, mDefaultValue);
- }
- }
-
- private static final class DeveloperIntegerPreference extends DeveloperPreference<Integer> {
-
- private DeveloperIntegerPreference(String key, Integer defaultValue) {
- super(key, defaultValue);
- }
-
- @Override
- protected void storeValue(Context context, Integer value) {
- getPreferences(context).edit().putInt(mKey, value).apply();
- }
-
- @Override
- protected Integer getStoredValue(Context context) {
- return getPreferences(context).getInt(mKey, mDefaultValue);
- }
- }
-}
diff --git a/common/src/com/android/tv/common/dev/DeveloperPreferences.java b/common/src/com/android/tv/common/dev/DeveloperPreferences.java
deleted file mode 100644
index 9c83b649..00000000
--- a/common/src/com/android/tv/common/dev/DeveloperPreferences.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.dev;
-
-/** A class about the constants for TV Developer preferences. */
-public final class DeveloperPreferences {
-
- /**
- * Allow Google Analytics for eng builds.
- *
- * <p>Defaults to {@code false}.
- */
- public static final DeveloperPreference<Boolean> ALLOW_ANALYTICS_IN_ENG =
- DeveloperPreference.create("tv_allow_analytics_in_eng", false);
-
- /**
- * Allow Strict mode for debug builds.
- *
- * <p>Defaults to {@code true}.
- */
- public static final DeveloperPreference<Boolean> ALLOW_STRICT_MODE =
- DeveloperPreference.create("tv_allow_strict_mode", true);
-
- /**
- * When true {@link android.view.KeyEvent}s are logged.
- *
- * <p>Defaults to {@code false}.
- */
- public static final DeveloperPreference<Boolean> LOG_KEYEVENT =
- DeveloperPreference.create("tv_log_keyevent", false);
-
- /**
- * When true debug keys are used.
- *
- * <p>Defaults to {@code false}.
- */
- public static final DeveloperPreference<Boolean> USE_DEBUG_KEYS =
- DeveloperPreference.create("tv_use_debug_keys", false);
-
- /**
- * Send {@link com.android.tv.analytics.Tracker} information.
- *
- * <p>Defaults to {@code true}.
- */
- public static final DeveloperPreference<Boolean> USE_TRACKER =
- DeveloperPreference.create("tv_use_tracker", true);
-
- /**
- * Maximum buffer size in MegaBytes.
- *
- * <p>Defaults to 2MB.
- */
- public static final DeveloperPreference<Integer> MAX_BUFFER_SIZE_MBYTES =
- DeveloperPreference.create("tv.tuner.buffersize_mbytes", 2 * 1024);
-
- private DeveloperPreferences() {}
-}
diff --git a/common/src/com/android/tv/common/experiments/ExperimentFlag.java b/common/src/com/android/tv/common/experiments/ExperimentFlag.java
new file mode 100644
index 00000000..b8370ad6
--- /dev/null
+++ b/common/src/com/android/tv/common/experiments/ExperimentFlag.java
@@ -0,0 +1,96 @@
+/*
+ * 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.experiments;
+
+import android.support.annotation.VisibleForTesting;
+import com.android.tv.common.BuildConfig;
+
+import com.google.common.base.Supplier;
+
+/** Experiments return values based on user, device and other criteria. */
+public final class ExperimentFlag<T> {
+
+ // NOTE: sAllowOverrides IS NEVER USED in the non AOSP version.
+ private static boolean sAllowOverrides = false;
+
+ @VisibleForTesting
+ public static void initForTest() {
+ /* Begin_AOSP_Comment_Out
+ if (!BuildConfig.AOSP) {
+ PhenotypeFlag.initForTest();
+ return;
+ }
+ End_AOSP_Comment_Out */
+ sAllowOverrides = true;
+ }
+
+ /** Returns a boolean experiment */
+ public static ExperimentFlag<Boolean> createFlag(
+// AOSP_Comment_Out Supplier<Boolean> phenotypeFlag,
+ boolean defaultValue) {
+ return new ExperimentFlag<>(
+// AOSP_Comment_Out phenotypeFlag,
+ defaultValue);
+ }
+
+ private final T mDefaultValue;
+// AOSP_Comment_Out private final Supplier<T> mPhenotypeFlag;
+
+// AOSP_Comment_Out // NOTE: mOverrideValue IS NEVER USED in the non AOSP version.
+ private T mOverrideValue = null;
+ // mOverridden IS NEVER USED in the non AOSP version.
+ private boolean mOverridden = false;
+
+ private ExperimentFlag(
+// AOSP_Comment_Out Supplier<T> phenotypeFlag,
+ // NOTE: defaultValue IS NEVER USED in the non AOSP version.
+ T defaultValue) {
+ mDefaultValue = defaultValue;
+// AOSP_Comment_Out mPhenotypeFlag = phenotypeFlag;
+ }
+
+ /** Returns value for this experiment */
+ public T get() {
+ /* Begin_AOSP_Comment_Out
+ if (!BuildConfig.AOSP) {
+ return mPhenotypeFlag.get();
+ }
+ End_AOSP_Comment_Out */
+ return sAllowOverrides && mOverridden ? mOverrideValue : mDefaultValue;
+ }
+
+ @VisibleForTesting
+ public void override(T t) {
+
+ if (sAllowOverrides) {
+ mOverridden = true;
+ mOverrideValue = t;
+ }
+ }
+
+ @VisibleForTesting
+ public void resetOverride() {
+ mOverridden = false;
+ }
+
+ /* Begin_AOSP_Comment_Out
+ @VisibleForTesting
+ T getAospDefaultValueForTesting() {
+ return mDefaultValue;
+ }
+ End_AOSP_Comment_Out */
+}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultMessagesFlags.java b/common/src/com/android/tv/common/experiments/ExperimentLoader.java
index f2130a33..5f012e11 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultMessagesFlags.java
+++ b/common/src/com/android/tv/common/experiments/ExperimentLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,18 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tv.common.flags.impl;
-/**
- * Default flag values for {@link
- * com.android.tv.common.flags.MessagesFlags}.
- */
-public final class DefaultMessagesFlags
- implements com.android.tv.common.flags.MessagesFlags {
+package com.android.tv.common.experiments;
- @Override
- public boolean compiled() {
- return true;
- }
+import android.content.Context;
+/** Used to sync {@link ExperimentFlag}s. */
+public class ExperimentLoader {
+
+ /** Starts a background task to update {@link ExperimentFlag}s */
+ public void asyncRefreshExperiments(Context context) {
+ // Override for your experiment system
+ }
}
diff --git a/common/src/com/android/tv/common/experiments/Experiments.java b/common/src/com/android/tv/common/experiments/Experiments.java
new file mode 100644
index 00000000..9bfdb547
--- /dev/null
+++ b/common/src/com/android/tv/common/experiments/Experiments.java
@@ -0,0 +1,64 @@
+/*
+ * 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.experiments;
+
+import static com.android.tv.common.experiments.ExperimentFlag.createFlag;
+
+import com.android.tv.common.BuildConfig;
+// AOSP_Comment_Out import com.android.tv.common.flags.LiveChannels;
+
+/**
+ * Set of experiments visible in AOSP.
+ *
+ * <p>This file is maintained by hand.
+ */
+public final class Experiments {
+ public static final ExperimentFlag<Boolean> ENABLE_UNRATED_CONTENT_SETTINGS =
+ ExperimentFlag.createFlag(
+// AOSP_Comment_Out LiveChannels::enableUnratedContentSettings,
+ false);
+
+ /** Turn analytics on or off based on the System Checkbox for logging. */
+ public static final ExperimentFlag<Boolean> ENABLE_ANALYTICS_VIA_CHECKBOX =
+ createFlag(
+// AOSP_Comment_Out LiveChannels::enableAnalyticsViaCheckbox,
+ false);
+
+ /**
+ * Allow developer features such as the dev menu and other aids.
+ *
+ * <p>These features are available to select users(aka fishfooders) on production builds.
+ */
+ public static final ExperimentFlag<Boolean> ENABLE_DEVELOPER_FEATURES =
+ ExperimentFlag.createFlag(
+// AOSP_Comment_Out LiveChannels::enableDeveloperFeatures,
+ BuildConfig.ENG);
+
+ /**
+ * Allow QA features.
+ *
+ * <p>These features must be carefully limited, keeping QA differences to a minimum.
+ *
+ * <p>These features are available to select users(aka QA) on production builds.
+ */
+ public static final ExperimentFlag<Boolean> ENABLE_QA_FEATURES =
+ ExperimentFlag.createFlag(
+// AOSP_Comment_Out LiveChannels::enableQaFeatures,
+ false);
+
+ private Experiments() {}
+}
diff --git a/common/src/com/android/tv/common/feature/CommonFeatures.java b/common/src/com/android/tv/common/feature/CommonFeatures.java
index abe4c1df..04052a7c 100644
--- a/common/src/com/android/tv/common/feature/CommonFeatures.java
+++ b/common/src/com/android/tv/common/feature/CommonFeatures.java
@@ -23,14 +23,12 @@ import static com.android.tv.common.feature.TestableFeature.createTestableFeatur
import android.content.Context;
import android.util.Log;
-
import com.android.tv.common.flags.has.HasCloudEpgFlags;
import com.android.tv.common.util.LocationUtils;
-
import com.android.tv.common.flags.CloudEpgFlags;
/**
- * List of {@link Feature} that affect more than just the TV app.
+ * List of {@link Feature} that affect more than just the Live TV app.
*
* <p>Remove the {@code Feature} once it is launched.
*/
@@ -54,7 +52,7 @@ public class CommonFeatures {
* <p>Enables dvr recording regardless of storage status.
*/
public static final Feature FORCE_RECORDING_UNTIL_NO_SPACE =
- DeveloperPreferenceFeature.create("force_recording_until_no_space", false);
+ PropertyFeature.create("force_recording_until_no_space", false);
/** Show postal code fragment before channel scan. */
public static final Feature ENABLE_CLOUD_EPG_REGION =
diff --git a/common/src/com/android/tv/common/feature/DeveloperPreferenceFeature.java b/common/src/com/android/tv/common/feature/DeveloperPreferenceFeature.java
deleted file mode 100644
index 1f98547a..00000000
--- a/common/src/com/android/tv/common/feature/DeveloperPreferenceFeature.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 com.android.tv.common.dev.DeveloperPreference;
-
-/** A {@link Feature} based on {@link DeveloperPreference<Boolean>}. */
-public class DeveloperPreferenceFeature implements Feature {
-
- private final DeveloperPreference<Boolean> mPreference;
-
- /**
- * Create a developer preference feature.
- *
- * @param key the developer setting key.
- * @param defaultValue the value to return if the setting is undefined or empty.
- */
- public static DeveloperPreferenceFeature create(String key, boolean defaultValue) {
- return from(DeveloperPreference.create(key, defaultValue));
- }
-
- /**
- * Create a developer preference feature from an exiting {@link DeveloperPreference<Boolean>}.
- */
- public static DeveloperPreferenceFeature from(
- DeveloperPreference<Boolean> developerPreference) {
- return new DeveloperPreferenceFeature(developerPreference);
- }
-
- private DeveloperPreferenceFeature(DeveloperPreference<Boolean> mPreference) {
- this.mPreference = mPreference;
- }
-
- @Override
- public boolean isEnabled(Context context) {
- return mPreference.get(context);
- }
-
- @Override
- public String toString() {
- return mPreference.toString();
- }
-}
diff --git a/common/src/com/android/tv/common/feature/PermissionFeature.java b/common/src/com/android/tv/common/feature/ExperimentFeature.java
index 02611785..820eda49 100644
--- a/common/src/com/android/tv/common/feature/PermissionFeature.java
+++ b/common/src/com/android/tv/common/feature/ExperimentFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,22 +17,28 @@
package com.android.tv.common.feature;
import android.content.Context;
-import android.content.pm.PackageManager;
+import com.android.tv.common.experiments.ExperimentFlag;
-/** A feature that is only available when {@code permissionName} is granted. */
-public class PermissionFeature implements Feature {
+/** A {@link Feature} base on an {@link ExperimentFlag}. */
+public final class ExperimentFeature implements Feature {
- public static final PermissionFeature DVB_DEVICE_PERMISSION =
- new PermissionFeature("android.permission.DVB_DEVICE");
+ public static Feature from(ExperimentFlag<Boolean> flag) {
+ return new ExperimentFeature(flag);
+ }
- private final String permissionName;
+ private final ExperimentFlag<Boolean> mFlag;
- private PermissionFeature(String permissionName) {
- this.permissionName = permissionName;
+ private ExperimentFeature(ExperimentFlag<Boolean> flag) {
+ mFlag = flag;
}
@Override
public boolean isEnabled(Context context) {
- return context.checkSelfPermission(permissionName) == PackageManager.PERMISSION_GRANTED;
+ return mFlag.get();
+ }
+
+ @Override
+ public String toString() {
+ return "ExperimentFeature for " + mFlag;
}
}
diff --git a/common/src/com/android/tv/common/feature/FeatureUtils.java b/common/src/com/android/tv/common/feature/FeatureUtils.java
index e6192cd4..aaed6c82 100644
--- a/common/src/com/android/tv/common/feature/FeatureUtils.java
+++ b/common/src/com/android/tv/common/feature/FeatureUtils.java
@@ -17,6 +17,7 @@
package com.android.tv.common.feature;
import android.content.Context;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.util.CommonUtils;
import java.util.Arrays;
@@ -70,6 +71,23 @@ public class FeatureUtils {
}
};
}
+ /**
+ * A feature available in AOSP.
+ *
+ * @param googleFeature the feature used in non AOSP builds
+ * @param aospFeature the feature used in AOSP builds
+ */
+ public static Feature aospFeature(
+// AOSP_Comment_Out final Feature googleFeature,
+ final Feature aospFeature) {
+ /* Begin_AOSP_Comment_Out
+ if (!BuildConfig.AOSP) {
+ return googleFeature;
+ } else {
+ End_AOSP_Comment_Out */
+ return aospFeature;
+// AOSP_Comment_Out }
+ }
/**
* Returns a feature that is opposite of the given {@code feature}.
diff --git a/common/src/com/android/tv/common/feature/Model.java b/common/src/com/android/tv/common/feature/Model.java
index 450cd216..7aa5148e 100644
--- a/common/src/com/android/tv/common/feature/Model.java
+++ b/common/src/com/android/tv/common/feature/Model.java
@@ -21,11 +21,10 @@ import android.content.Context;
/** Holder for {@link android.os.Build#MODEL} features. */
public interface Model {
- ModelFeature ARCHER = new ModelFeature("Archer");
ModelFeature NEXUS_PLAYER = new ModelFeature("Nexus Player");
/** True when the {@link android.os.Build#MODEL} equals the {@code model} given. */
- final class ModelFeature implements Feature {
+ public static final class ModelFeature implements Feature {
private final String mModel;
private ModelFeature(String model) {
diff --git a/common/src/com/android/tv/common/feature/Sdk.java b/common/src/com/android/tv/common/feature/Sdk.java
index 54bc1bbd..4b0a925f 100644
--- a/common/src/com/android/tv/common/feature/Sdk.java
+++ b/common/src/com/android/tv/common/feature/Sdk.java
@@ -29,6 +29,8 @@ public final class Sdk {
public static final Feature AT_LEAST_O = new AtLeast(VERSION_CODES.O);
+ public static final Feature AT_LEAST_P = new AtLeast(VERSION_CODES.P); // AOSP_OC:strip_line
+
private static final class AtLeast implements Feature {
private final int versionCode;
diff --git a/common/src/com/android/tv/common/flags/BackendKnobsFlags.java b/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
index 3b65df56..69bac7a0 100644
--- a/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
+++ b/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
package com.android.tv.common.flags;
/** Flags for tuning non ui behavior */
@@ -27,8 +26,8 @@ public interface BackendKnobsFlags {
*/
boolean compiled();
- /** Number of channels to batch together when fetching programs */
- long epgFetcherChannelsPerProgramFetch();
+ /** Enable fetching only part of the program data. */
+ boolean enablePartialProgramFetch();
/** EPG fetcher interval in hours */
long epgFetcherIntervalHour();
@@ -36,6 +35,9 @@ public interface BackendKnobsFlags {
/** Target channel count for EPG. It is used to adjust the EPG length */
long epgTargetChannelCount();
+ /** Enables fetching a few hours of programs only when the epg is scrolled to that time. */
+ boolean fetchProgramsAsNeeded();
+
/** How many hours of programs are loaded in the program guide for during the initial fetch */
long programGuideInitialFetchHours();
diff --git a/common/src/com/android/tv/common/flags/CloudEpgFlags.java b/common/src/com/android/tv/common/flags/CloudEpgFlags.java
index db2789c3..ab4c6a17 100755
--- a/common/src/com/android/tv/common/flags/CloudEpgFlags.java
+++ b/common/src/com/android/tv/common/flags/CloudEpgFlags.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
package com.android.tv.common.flags;
/** Flags for Cloud EPG */
@@ -30,6 +29,6 @@ public interface CloudEpgFlags {
/** Is the device in a region supported by Cloud Epg */
boolean supportedRegion();
- /** List of input ids that the TV app will update their EPG. */
+ /** List of input ids that Live TV will update their EPG. */
String thirdPartyEpgInputsCsv();
}
diff --git a/common/src/com/android/tv/common/flags/MessagesFlags.java b/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java
index 596442fe..1afff793 100755
--- a/common/src/com/android/tv/common/flags/MessagesFlags.java
+++ b/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java
@@ -13,17 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
package com.android.tv.common.flags;
-/**
- * Message flags.
- *
- * <p>Used to hide new messages until all translations are ready.
- *
- * <p>Production releases never include the messages protected by these flags.
- */
-public interface MessagesFlags {
+/** Flags allowing concurrent DVR playback */
+public interface ConcurrentDvrPlaybackFlags {
/**
* Whether or not this feature is compiled into this build.
@@ -32,4 +25,10 @@ public interface MessagesFlags {
* code generation.
*/
boolean compiled();
+
+ /** Enable playback of DVR playback during recording */
+ boolean enabled();
+
+ /** Enable tuner using recording data for playback in onTune */
+ boolean onTuneUsesRecording();
}
diff --git a/common/src/com/android/tv/common/flags/DvrFlags.java b/common/src/com/android/tv/common/flags/DvrFlags.java
deleted file mode 100755
index 9deae1f7..00000000
--- a/common/src/com/android/tv/common/flags/DvrFlags.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags;
-
-/** DVR flags */
-public interface DvrFlags {
-
- /**
- * Whether or not this feature is compiled into this build.
- *
- * <p>This returns true by default, unless the is_compiled_selector parameter was set during
- * code generation.
- */
- boolean compiled();
-
- /** Allow user to customize timings of program recordings. */
- boolean startEarlyEndLateEnabled();
-
- /** Store and use the video aspect ratio in recordings. */
- boolean storeVideoAspectRatio();
-}
diff --git a/common/src/com/android/tv/common/flags/LegacyFlags.java b/common/src/com/android/tv/common/flags/LegacyFlags.java
deleted file mode 100755
index d0cb1e44..00000000
--- a/common/src/com/android/tv/common/flags/LegacyFlags.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags;
-
-/** Legacy flags */
-public interface LegacyFlags {
-
- /**
- * Whether or not this feature is compiled into this build.
- *
- * <p>This returns true by default, unless the is_compiled_selector parameter was set during
- * code generation.
- */
- boolean compiled();
-
- /** Enable Developer Features */
- boolean enableDeveloperFeatures();
-
- /** Enable QA Features */
- boolean enableQaFeatures();
-
- /** Enable Unrated Content Settings */
- boolean enableUnratedContentSettings();
-}
diff --git a/common/src/com/android/tv/common/flags/SetupFlags.java b/common/src/com/android/tv/common/flags/SetupFlags.java
deleted file mode 100755
index 0a7f2002..00000000
--- a/common/src/com/android/tv/common/flags/SetupFlags.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags;
-
-/** Flags for changing setup behavior */
-public interface SetupFlags {
-
- /**
- * Whether or not this feature is compiled into this build.
- *
- * <p>This returns true by default, unless the is_compiled_selector parameter was set during
- * code generation.
- */
- boolean compiled();
-
- /** Packages allowed to send intents to SetupPassthroughActivity. */
- com.android.tv.common.flags.proto.TypedFeatures.StringListParam
- setupPassThroughPackageWhitelist();
-
- /** Use a whitelist for packages allowed to start SetupPassthroughActivity */
- boolean useWhitelistForSetupPassThrough();
-}
diff --git a/common/src/com/android/tv/common/flags/TunerFlags.java b/common/src/com/android/tv/common/flags/TunerFlags.java
index 5ecfb5bf..5f899b90 100755
--- a/common/src/com/android/tv/common/flags/TunerFlags.java
+++ b/common/src/com/android/tv/common/flags/TunerFlags.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
package com.android.tv.common.flags;
/** Flags for tuner */
@@ -27,6 +26,9 @@ public interface TunerFlags {
*/
boolean compiled();
+ /** Tune using current recording if available. */
+ boolean tuneUsingRecording();
+
/** Enable using exoplayer V2 */
boolean useExoplayerV2();
}
diff --git a/common/src/com/android/tv/common/flags/UiFlags.java b/common/src/com/android/tv/common/flags/UiFlags.java
index 2bd8a59d..4c88d08a 100755
--- a/common/src/com/android/tv/common/flags/UiFlags.java
+++ b/common/src/com/android/tv/common/flags/UiFlags.java
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
-
package com.android.tv.common.flags;
-/** Flags for TV app UI */
+/** Flags for Live TV UI */
public interface UiFlags {
/**
@@ -27,9 +26,6 @@ public interface UiFlags {
*/
boolean compiled();
- /** Critic Ratings */
- boolean enableCriticRatings();
-
/**
* Number of days to be shown by Recording History.
*
@@ -38,5 +34,8 @@ public interface UiFlags {
long maxHistoryDays();
/** Unhide the launcher all the time */
- boolean unhideLauncher();
+ boolean uhideLauncher();
+
+ /** Use the Leanback Pin Picker */
+ boolean useLeanbackPinPicker();
}
diff --git a/common/src/com/android/tv/common/flags/StartupFlags.java b/common/src/com/android/tv/common/flags/has/HasConcurrentDvrPlaybackFlags.java
index 2f64c9fe..b4710875 100755..100644
--- a/common/src/com/android/tv/common/flags/StartupFlags.java
+++ b/common/src/com/android/tv/common/flags/has/HasConcurrentDvrPlaybackFlags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,20 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
+package com.android.tv.common.flags.has;
-package com.android.tv.common.flags;
+import android.content.Context;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
-/** Flags for TV App startup */
-public interface StartupFlags {
+/** Has {@link ConcurrentDvrPlaybackFlags} */
+public interface HasConcurrentDvrPlaybackFlags {
- /**
- * Whether or not this feature is compiled into this build.
- *
- * <p>This returns true by default, unless the is_compiled_selector parameter was set during
- * code generation.
- */
- boolean compiled();
+ static ConcurrentDvrPlaybackFlags fromContext(Context context) {
+ return ((HasConcurrentDvrPlaybackFlags) HasUtils.getApplicationContext(context))
+ .getConcurrentDvrPlaybackFlags();
+ }
- /** InputId's that will not be warmed up on MainActivity creation. */
- com.android.tv.common.flags.proto.TypedFeatures.StringListParam warmupInputidBlacklist();
+ ConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags();
}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java
index 5302842b..a189e473 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java
@@ -25,8 +25,8 @@ public final class DefaultBackendKnobsFlags
}
@Override
- public long epgFetcherChannelsPerProgramFetch() {
- return 50;
+ public boolean enablePartialProgramFetch() {
+ return false;
}
@Override
@@ -35,8 +35,13 @@ public final class DefaultBackendKnobsFlags
}
@Override
+ public boolean fetchProgramsAsNeeded() {
+ return false;
+ }
+
+ @Override
public long programGuideInitialFetchHours() {
- return 4;
+ return 8;
}
@Override
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultDvrFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultConcurrentDvrPlaybackFlags.java
index 09f7b4f3..8d8c584a 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultDvrFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultConcurrentDvrPlaybackFlags.java
@@ -15,9 +15,10 @@
*/
package com.android.tv.common.flags.impl;
-/** Flags for tuning non ui behavior. */
-public final class DefaultDvrFlags
- implements com.android.tv.common.flags.DvrFlags {
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
+
+/** Default flags for Concurrent DVR Playback */
+public final class DefaultConcurrentDvrPlaybackFlags implements ConcurrentDvrPlaybackFlags {
@Override
public boolean compiled() {
@@ -25,12 +26,12 @@ public final class DefaultDvrFlags
}
@Override
- public boolean startEarlyEndLateEnabled() {
+ public boolean enabled() {
return false;
}
@Override
- public boolean storeVideoAspectRatio() {
+ public boolean onTuneUsesRecording() {
return false;
}
}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java b/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java
index 10be34b5..49352364 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java
@@ -18,12 +18,9 @@ package com.android.tv.common.flags.impl;
import dagger.Module;
import dagger.Provides;
import dagger.Reusable;
-
import com.android.tv.common.flags.BackendKnobsFlags;
import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.DvrFlags;
-import com.android.tv.common.flags.LegacyFlags;
-import com.android.tv.common.flags.StartupFlags;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import com.android.tv.common.flags.TunerFlags;
import com.android.tv.common.flags.UiFlags;
@@ -45,20 +42,8 @@ public class DefaultFlagsModule {
@Provides
@Reusable
- DvrFlags provideDvrFlags() {
- return new DefaultDvrFlags();
- }
-
- @Provides
- @Reusable
- LegacyFlags provideLegacyFlags() {
- return DefaultLegacyFlags.DEFAULT;
- }
-
- @Provides
- @Reusable
- StartupFlags provideStartupFlags() {
- return new DefaultStartupFlags();
+ ConcurrentDvrPlaybackFlags provideConcurrentDvrPlaybackFlags() {
+ return new DefaultConcurrentDvrPlaybackFlags();
}
@Provides
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultLegacyFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultLegacyFlags.java
deleted file mode 100644
index 52142416..00000000
--- a/common/src/com/android/tv/common/flags/impl/DefaultLegacyFlags.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags.impl;
-
-import com.google.auto.value.AutoValue;
-import com.android.tv.common.flags.LegacyFlags;
-
-/** Default {@link LegacyFlags}. */
-@AutoValue
-public abstract class DefaultLegacyFlags implements LegacyFlags {
- public static final DefaultLegacyFlags DEFAULT = DefaultLegacyFlags.builder().build();
-
- public static Builder builder() {
- return new AutoValue_DefaultLegacyFlags.Builder()
- .compiled(true)
- .enableDeveloperFeatures(false)
- .enableQaFeatures(false)
- .enableUnratedContentSettings(false);
- }
-
- /** Builder for {@link LegacyFlags} */
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder compiled(boolean value);
-
- public abstract Builder enableDeveloperFeatures(boolean value);
-
- public abstract Builder enableQaFeatures(boolean value);
-
- public abstract Builder enableUnratedContentSettings(boolean value);
-
- public abstract DefaultLegacyFlags build();
- }
-}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultStartupFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultStartupFlags.java
deleted file mode 100644
index 3eb6edc6..00000000
--- a/common/src/com/android/tv/common/flags/impl/DefaultStartupFlags.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags.impl;
-
-import com.android.tv.common.flags.proto.TypedFeatures.StringListParam;
-import com.android.tv.common.flags.StartupFlags;
-
-/** Default {@link StartupFlags} */
-public class DefaultStartupFlags implements StartupFlags {
- @Override
- public boolean compiled() {
- return true;
- }
-
- @Override
- public StringListParam warmupInputidBlacklist() {
- return StringListParam.getDefaultInstance();
- }
-}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java
index 2d12e368..195953bc 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java
@@ -26,6 +26,11 @@ public class DefaultTunerFlags implements TunerFlags {
}
@Override
+ public boolean tuneUsingRecording() {
+ return false;
+ }
+
+ @Override
public boolean useExoplayerV2() {
return false;
}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java
index 43f0dea0..fce45853 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java
@@ -17,7 +17,7 @@ package com.android.tv.common.flags.impl;
import com.android.tv.common.flags.UiFlags;
-/** Default Flags for TV app UI */
+/** Default Flags for Live TV UI */
public class DefaultUiFlags implements UiFlags {
@Override
@@ -26,17 +26,17 @@ public class DefaultUiFlags implements UiFlags {
}
@Override
- public boolean enableCriticRatings() {
+ public boolean uhideLauncher() {
return false;
}
@Override
- public boolean unhideLauncher() {
+ public boolean useLeanbackPinPicker() {
return false;
}
@Override
public long maxHistoryDays() {
- return 0;
+ return 7;
}
}
diff --git a/common/src/com/android/tv/common/flags/impl/SettableFlagsModule.java b/common/src/com/android/tv/common/flags/impl/SettableFlagsModule.java
deleted file mode 100644
index ab4ebd34..00000000
--- a/common/src/com/android/tv/common/flags/impl/SettableFlagsModule.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.flags.impl;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-
-import com.android.tv.common.flags.BackendKnobsFlags;
-import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.DvrFlags;
-import com.android.tv.common.flags.LegacyFlags;
-import com.android.tv.common.flags.SetupFlags;
-import com.android.tv.common.flags.StartupFlags;
-import com.android.tv.common.flags.TunerFlags;
-import com.android.tv.common.flags.UiFlags;
-
-/** Provides public fields for each flag so they can be changed before injection. */
-@Module
-public class SettableFlagsModule {
-
- public DefaultBackendKnobsFlags backendKnobsFlags = new DefaultBackendKnobsFlags();
- public DefaultCloudEpgFlags cloudEpgFlags = new DefaultCloudEpgFlags();
- public DefaultDvrFlags dvrFlags = new DefaultDvrFlags();
- public DefaultLegacyFlags legacyFlags = DefaultLegacyFlags.DEFAULT;
- public DefaultSetupFlags setupFlags = new DefaultSetupFlags();
- public DefaultStartupFlags startupFlags = new DefaultStartupFlags();
- public DefaultTunerFlags tunerFlags = new DefaultTunerFlags();
- public DefaultUiFlags uiFlags = new DefaultUiFlags();
-
- @Provides
- @Reusable
- BackendKnobsFlags provideBackendKnobsFlags() {
- return backendKnobsFlags;
- }
-
- @Provides
- @Reusable
- CloudEpgFlags provideCloudEpgFlags() {
- return cloudEpgFlags;
- }
-
- @Provides
- @Reusable
- DvrFlags provideDvrFlags() {
- return dvrFlags;
- }
-
- @Provides
- @Reusable
- LegacyFlags provideLegacyFlags() {
- return legacyFlags;
- }
-
- @Provides
- @Reusable
- SetupFlags provideSetupFlags() {
- return setupFlags;
- }
-
- @Provides
- @Reusable
- StartupFlags provideStartupFlags() {
- return startupFlags;
- }
-
- @Provides
- @Reusable
- TunerFlags provideTunerFlags() {
- return tunerFlags;
- }
-
- @Provides
- @Reusable
- UiFlags provideUiFlags() {
- return uiFlags;
- }
-}
diff --git a/common/src/com/android/tv/common/flags/proto/typed-features.proto b/common/src/com/android/tv/common/flags/proto/typed-features.proto
deleted file mode 100644
index 855d7311..00000000
--- a/common/src/com/android/tv/common/flags/proto/typed-features.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-syntax = "proto2";
-
-package android.tv.common.flags;
-
-option java_outer_classname = "TypedFeatures";
-option java_package = "com.android.tv.common.flags.proto";
-
-// These messages are to specify feature params that are a list of integers.
-message Int32ListParam {
- repeated int32 element = 1;
-}
-
-message Int64ListParam {
- repeated int64 element = 1;
-}
-
-// This message is to specify feature params that are a list of strings.
-message StringListParam {
- repeated string element = 1;
-}
diff --git a/common/src/com/android/tv/common/recording/RecordingStorageStatusManager.java b/common/src/com/android/tv/common/recording/RecordingStorageStatusManager.java
index 3552a66f..0fb864bd 100644
--- a/common/src/com/android/tv/common/recording/RecordingStorageStatusManager.java
+++ b/common/src/com/android/tv/common/recording/RecordingStorageStatusManager.java
@@ -28,11 +28,8 @@ import android.support.annotation.AnyThread;
import android.support.annotation.IntDef;
import android.support.annotation.WorkerThread;
import android.util.Log;
-
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.feature.CommonFeatures;
-
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
@@ -41,13 +38,10 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/** Signals DVR storage status change such as plugging/unplugging. */
-@Singleton
public class RecordingStorageStatusManager {
private static final String TAG = "RecordingStorageStatusManager";
+ private static final boolean DEBUG = false;
/** Minimum storage size to support DVR */
public static final long MIN_STORAGE_SIZE_FOR_DVR_IN_BYTES = 50 * 1024 * 1024 * 1024L; // 50GB
@@ -149,8 +143,7 @@ public class RecordingStorageStatusManager {
*
* @param context {@link Context}
*/
- @Inject
- public RecordingStorageStatusManager(@ApplicationContext Context context) {
+ public RecordingStorageStatusManager(final Context context) {
mContext = context;
mMountedStorageStatus = getStorageStatusInternal();
mStorageValid = mMountedStorageStatus.isValidForDvr();
diff --git a/common/src/com/android/tv/common/singletons/HasTvInputId.java b/common/src/com/android/tv/common/singletons/HasTvInputId.java
index 49cf3d2e..4bc0a21c 100644
--- a/common/src/com/android/tv/common/singletons/HasTvInputId.java
+++ b/common/src/com/android/tv/common/singletons/HasTvInputId.java
@@ -18,8 +18,8 @@ package com.android.tv.common.singletons;
/**
* Has TunerInputId.
*
- * <p>This is used buy both the tuner to get its input id and by the TV app to get the embedded
- * tuner input id.
+ * <p>This is used buy both the tuner to get its input id and by the Live TV to get the
+ * embedded tuner input id.
*/
public interface HasTvInputId {
diff --git a/common/src/com/android/tv/common/support/tvprovider/README.md b/common/src/com/android/tv/common/support/tvprovider/README.md
deleted file mode 100644
index a24dc288..00000000
--- a/common/src/com/android/tv/common/support/tvprovider/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## support provider
-
-This is preview code destined to be put in androidx.tvprovider.media.tv
-
-
-All classes here must have an associated bug to move to androidx
diff --git a/common/src/com/android/tv/common/support/tvprovider/TvContractCompatX.java b/common/src/com/android/tv/common/support/tvprovider/TvContractCompatX.java
deleted file mode 100644
index 353e3421..00000000
--- a/common/src/com/android/tv/common/support/tvprovider/TvContractCompatX.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.support.tvprovider;
-
-import android.net.Uri;
-import android.support.annotation.Nullable;
-import androidx.tvprovider.media.tv.TvContractCompat;
-
-/**
- * Extensions to the contract between the TV provider and applications. Contains definitions for the
- * supported URIs and columns.
- *
- * <p>TODO(b/126921088): move this to androidx.
- */
-public final class TvContractCompatX {
-
- /**
- * Builds a URI that points to a specific channel.
- *
- * @param inputPackage the package of the input.
- * @param internalProviderId the internal provider id
- */
- public static Uri buildChannelUri(
- @Nullable String inputPackage, @Nullable String internalProviderId) {
- Uri.Builder uri = TvContractCompat.Channels.CONTENT_URI.buildUpon();
- if (inputPackage != null) {
- uri.appendQueryParameter("package", inputPackage);
- }
- if (internalProviderId != null) {
- uri.appendQueryParameter(
- TvContractCompat.Channels.COLUMN_INTERNAL_PROVIDER_ID, internalProviderId);
- }
- return uri.build();
- }
-
- /**
- * Builds a URI that points to all programs on a given channel.
- *
- * @param inputPackage the package of the input.
- * @param internalProviderId the internal provider id
- */
- public static Uri buildProgramsUriForChannel(
- @Nullable String inputPackage, @Nullable String internalProviderId) {
- Uri.Builder uri = TvContractCompat.Programs.CONTENT_URI.buildUpon();
- if (inputPackage != null) {
- uri.appendQueryParameter("package", inputPackage);
- }
- if (internalProviderId != null) {
- uri.appendQueryParameter(
- TvContractCompat.Channels.COLUMN_INTERNAL_PROVIDER_ID, internalProviderId);
- }
- return uri.build();
- }
-
- /**
- * Builds a URI that points to programs on a specific channel whose schedules overlap with the
- * given time frame.
- *
- * @param inputPackage the package of the input.
- * @param internalProviderId the internal provider id
- * @param startTime The start time used to filter programs. The returned programs should have
- * {@link TvContractCompat.Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this
- * time.
- * @param endTime The end time used to filter programs. The returned programs should have {@link
- * TvContractCompat.Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
- */
- public static Uri buildProgramsUriForChannel(
- @Nullable String inputPackage,
- @Nullable String internalProviderId,
- long startTime,
- long endTime) {
- return buildProgramsUriForChannel(inputPackage, internalProviderId)
- .buildUpon()
- .appendQueryParameter(TvContractCompat.PARAM_START_TIME, String.valueOf(startTime))
- .appendQueryParameter(TvContractCompat.PARAM_END_TIME, String.valueOf(endTime))
- .build();
- }
-
- /**
- * Builds a URI that points to programs whose schedules overlap with the given time frame.
- *
- * @param startTime The start time used to filter programs. The returned programs should have
- * {@link TvContractCompat.Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this
- * time.
- * @param endTime The end time used to filter programs. The returned programs should have {@link
- * TvContractCompat.Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
- */
- public static Uri buildProgramsUri(long startTime, long endTime) {
- return TvContractCompat.Programs.CONTENT_URI
- .buildUpon()
- .appendQueryParameter(TvContractCompat.PARAM_START_TIME, String.valueOf(startTime))
- .appendQueryParameter(TvContractCompat.PARAM_END_TIME, String.valueOf(endTime))
- .build();
- }
-}
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 2a6ceec5..3c76c269 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
@@ -19,11 +19,11 @@ package com.android.tv.common.ui.setup;
import static android.content.Context.ACCESSIBILITY_SERVICE;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
-import androidx.leanback.widget.VerticalGridView;
+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.view.LayoutInflater;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -53,9 +53,9 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
Bundle arguments = getArguments();
- view.findViewById(androidx.leanback.R.id.action_fragment_root)
+ view.findViewById(android.support.v17.leanback.R.id.action_fragment_root)
.setPadding(0, 0, 0, 0);
- mContentFragment = view.findViewById(androidx.leanback.R.id.content_fragment);
+ mContentFragment = view.findViewById(android.support.v17.leanback.R.id.content_fragment);
LinearLayout.LayoutParams guidanceLayoutParams =
(LinearLayout.LayoutParams) mContentFragment.getLayoutParams();
guidanceLayoutParams.weight = 0;
@@ -69,7 +69,7 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
getResources()
.getDimensionPixelOffset(R.dimen.setup_done_button_container_width);
// Guided actions list
- View list = view.findViewById(androidx.leanback.R.id.guidedactions_list);
+ View list = view.findViewById(android.support.v17.leanback.R.id.guidedactions_list);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) list.getLayoutParams();
// Use content view to check layout direction while view is being created.
if (getResources().getConfiguration().getLayoutDirection()
@@ -93,12 +93,12 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
gridView.setWindowAlignmentOffset(offset);
gridView.setWindowAlignmentOffsetPercent(0);
gridView.setItemAlignmentOffsetPercent(0);
- ((ViewGroup) view.findViewById(androidx.leanback.R.id.guidedactions_list))
+ ((ViewGroup) view.findViewById(android.support.v17.leanback.R.id.guidedactions_list))
.setTransitionGroup(false);
// Needed for the shared element transition.
// content_frame is defined in leanback.
ViewGroup group =
- (ViewGroup) view.findViewById(androidx.leanback.R.id.content_frame);
+ (ViewGroup) view.findViewById(android.support.v17.leanback.R.id.content_frame);
group.setClipChildren(false);
group.setClipToPadding(false);
return view;
diff --git a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
index ee00e9fb..c02d3f56 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
@@ -112,15 +112,15 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
@Override
protected int[] getParentIdsForDelay() {
return new int[] {
- androidx.leanback.R.id.content_fragment,
- androidx.leanback.R.id.guidedactions_list
+ android.support.v17.leanback.R.id.content_fragment,
+ android.support.v17.leanback.R.id.guidedactions_list
};
}
@Override
public int[] getSharedElementIds() {
return new int[] {
- androidx.leanback.R.id.action_fragment_background, R.id.done_button_container
+ android.support.v17.leanback.R.id.action_fragment_background, R.id.done_button_container
};
}
}
diff --git a/common/src/com/android/tv/common/ui/setup/animation/TranslationAnimationCreator.java b/common/src/com/android/tv/common/ui/setup/animation/TranslationAnimationCreator.java
index 59706936..13b89ea1 100644
--- a/common/src/com/android/tv/common/ui/setup/animation/TranslationAnimationCreator.java
+++ b/common/src/com/android/tv/common/ui/setup/animation/TranslationAnimationCreator.java
@@ -20,7 +20,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.graphics.Path;
-import androidx.leanback.R;
+import android.support.v17.leanback.R;
import android.transition.Transition;
import android.transition.TransitionValues;
import android.view.View;
@@ -29,9 +29,9 @@ import android.view.View;
* This class is used by Slide and Explode to create an animator that goes from the start position
* to the end position. It takes into account the canceled position so that it will not blink out or
* shift suddenly when the transition is interrupted. The original class is
- * androidx.leanback.transition.TranslationAnimationCreator which is hidden.
+ * android.support.v17.leanback.transition.TranslationAnimationCreator which is hidden.
*/
-// Copied from androidx.leanback.transition.TransltaionAnimationCreator
+// Copied from android.support.v17.leanback.transition.TransltaionAnimationCreator
class TranslationAnimationCreator {
/**
* Creates an animator that can be used for x and/or y translations. When interrupted, it sets a
diff --git a/common/src/com/android/tv/common/util/CommonUtils.java b/common/src/com/android/tv/common/util/CommonUtils.java
index 662f819c..4513a879 100644
--- a/common/src/com/android/tv/common/util/CommonUtils.java
+++ b/common/src/com/android/tv/common/util/CommonUtils.java
@@ -22,8 +22,10 @@ import android.media.tv.TvInputInfo;
import android.os.Build;
import android.util.ArraySet;
import android.util.Log;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.actions.InputSetupActionUtils;
+import com.android.tv.common.experiments.Experiments;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -51,7 +53,6 @@ public final class CommonUtils {
static {
BUNDLED_PACKAGE_SET.add("com.android.tv");
-// AOSP_Comment_Out BUNDLED_PACKAGE_SET.add(CommonConstants.BASE_PACKAGE);
}
private static Boolean sRunningInTest;
@@ -122,11 +123,16 @@ public final class CommonUtils {
return false;
}
- /** Returns true if the application is packaged with TV app. */
+ /** Returns true if the application is packaged with Live TV. */
public static boolean isPackagedWithLiveChannels(Context context) {
return (CommonConstants.BASE_PACKAGE.equals(context.getPackageName()));
}
+ /** Returns true if the current user is a developer. */
+ public static boolean isDeveloper() {
+ return BuildConfig.ENG || Experiments.ENABLE_DEVELOPER_FEATURES.get();
+ }
+
/** Converts time in milliseconds to a ISO 8061 string. */
public static String toIsoDateTimeString(long timeMillis) {
return ISO_8601.get().format(new Date(timeMillis));
diff --git a/common/src/com/android/tv/common/util/Debug.java b/common/src/com/android/tv/common/util/Debug.java
index 8e826aef..ab908741 100644
--- a/common/src/com/android/tv/common/util/Debug.java
+++ b/common/src/com/android/tv/common/util/Debug.java
@@ -23,11 +23,11 @@ import java.util.concurrent.TimeUnit;
/** A class only for help developers. */
public class Debug {
/**
- * A threshold of start up time, when the start up time of TV app is more than it, a warning
- * will show to the developer.
+ * A threshold of start up time, when the start up time of Live TV is more than it, a
+ * warning will show to the developer.
*/
public static final long TIME_START_UP_DURATION_THRESHOLD = TimeUnit.SECONDS.toMillis(6);
- /** Tag for measuring start up time of TV app. */
+ /** Tag for measuring start up time of Live TV. */
public static final String TAG_START_UP_TIMER = "start_up_timer";
/** A global map for duration timers. */
diff --git a/common/src/com/android/tv/common/util/LocationUtils.java b/common/src/com/android/tv/common/util/LocationUtils.java
index 9d44cf21..ee5119eb 100644
--- a/common/src/com/android/tv/common/util/LocationUtils.java
+++ b/common/src/com/android/tv/common/util/LocationUtils.java
@@ -16,7 +16,9 @@
package com.android.tv.common.util;
+import android.Manifest;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
@@ -24,12 +26,13 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.common.BuildConfig;
+
+
+
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
@@ -62,41 +65,19 @@ public class LocationUtils {
if (sApplicationContext == null) {
sApplicationContext = context.getApplicationContext();
}
- /* Begin_AOSP_Comment_Out
- if (!BuildConfig.AOSP) {
- com.google.android.tv.livechannels.util.GoogleLocationUtilsHelper.startLocationUpdates(
- context, LocationUtils::updateAddress);
- return null;
- }
- End_AOSP_Comment_Out */
LocationUtilsHelper.startLocationUpdates();
return null;
}
- @Nullable
- static String getCurrentPostalCode(Context context) throws IOException {
- Address address = getCurrentAddress(context);
- if (address != null) {
- Log.i(
- TAG,
- "Current country and postal code is "
- + address.getCountryName()
- + ", "
- + address.getPostalCode());
- return address.getPostalCode();
- }
- return null;
- }
-
/** The listener used when address is updated. */
public interface OnUpdateAddressListener {
/**
* Called when address is updated.
*
- * <p>This listener is removed when this method returns true.
+ * This listener is removed when this method returns true.
*
* @return {@code true} if the job has been finished and the listener needs to be removed;
- * {@code false} otherwise.
+ * {@code false} otherwise.
*/
boolean onUpdateAddress(Address address);
}
@@ -104,8 +85,8 @@ public class LocationUtils {
/**
* Add an {@link OnUpdateAddressListener} instance.
*
- * <p>Note that the listener is removed automatically when {@link
- * OnUpdateAddressListener#onUpdateAddress(Address)} is called and returns {@code true}.
+ * Note that the listener is removed automatically when
+ * {@link OnUpdateAddressListener#onUpdateAddress(Address)} is called and returns {@code true}.
*/
public static void addOnUpdateAddressListener(OnUpdateAddressListener listener) {
sOnUpdateAddressListeners.add(listener);
@@ -114,8 +95,8 @@ public class LocationUtils {
/**
* Remove an {@link OnUpdateAddressListener} instance if it exists.
*
- * <p>Note that the listener will be removed automatically when {@link
- * OnUpdateAddressListener#onUpdateAddress(Address)} is called and returns {@code true}.
+ * Note that the listener will be removed automatically when
+ * {@link OnUpdateAddressListener#onUpdateAddress(Address)} is called and returns {@code true}.
*/
public static void removeOnUpdateAddressListener(OnUpdateAddressListener listener) {
sOnUpdateAddressListeners.remove(listener);
@@ -127,13 +108,6 @@ public class LocationUtils {
if (sCountry != null) {
return sCountry;
}
- /* Begin_AOSP_Comment_Out
- if (!BuildConfig.AOSP) {
- sCountry =
- com.google.android.tv.livechannels.util.GoogleLocationUtilsHelper
- .getDeviceCountry(context);
- }
- End_AOSP_Comment_Out */
if (TextUtils.isEmpty(sCountry)) {
sCountry = context.getResources().getConfiguration().locale.getCountry();
}
diff --git a/common/src/com/android/tv/common/util/NetworkTrafficTags.java b/common/src/com/android/tv/common/util/NetworkTrafficTags.java
index 51b6c4dc..3c94aed6 100644
--- a/common/src/com/android/tv/common/util/NetworkTrafficTags.java
+++ b/common/src/com/android/tv/common/util/NetworkTrafficTags.java
@@ -20,7 +20,7 @@ import android.net.TrafficStats;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
-/** Constants for tagging network traffic in the TV app. */
+/** Constants for tagging network traffic in the Live channels app. */
public final class NetworkTrafficTags {
public static final int DEFAULT_LIVE_CHANNELS = 1;
@@ -43,16 +43,16 @@ public final class NetworkTrafficTags {
@Override
public void execute(final @NonNull Runnable command) {
- // TODO(b/62038127): robolectric does not support lamdas in unbundled apps
- delegateExecutor.execute(
- () -> {
- TrafficStats.setThreadStatsTag(tag);
- try {
- command.run();
- } finally {
- TrafficStats.clearThreadStatsTag();
- }
- });
+ // TODO(b/62038127): robolectric does not support lamdas in unbundled apps
+ delegateExecutor.execute(
+ () -> {
+ TrafficStats.setThreadStatsTag(tag);
+ try {
+ command.run();
+ } finally {
+ TrafficStats.clearThreadStatsTag();
+ }
+ });
}
}
diff --git a/common/src/com/android/tv/common/util/PermissionUtils.java b/common/src/com/android/tv/common/util/PermissionUtils.java
index e241b91a..ca1abdc4 100644
--- a/common/src/com/android/tv/common/util/PermissionUtils.java
+++ b/common/src/com/android/tv/common/util/PermissionUtils.java
@@ -26,9 +26,6 @@ public class PermissionUtils {
private static Boolean sHasAccessAllEpgPermission;
private static Boolean sHasAccessWatchedHistoryPermission;
private static Boolean sHasModifyParentalControlsPermission;
- private static Boolean sHasChangeHdmiCecActiveSource;
- private static Boolean sHasReadContentRatingSystem;
-
public static boolean hasAccessAllEpg(Context context) {
if (sHasAccessAllEpgPermission == null) {
@@ -73,24 +70,4 @@ public class PermissionUtils {
return context.checkSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE")
== PackageManager.PERMISSION_GRANTED;
}
-
- public static boolean hasChangeHdmiCecActiveSource(Context context) {
- if (sHasChangeHdmiCecActiveSource == null) {
- sHasChangeHdmiCecActiveSource =
- context.checkSelfPermission(
- "android.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE")
- == PackageManager.PERMISSION_GRANTED;
- }
- return sHasChangeHdmiCecActiveSource;
- }
-
- public static boolean hasReadContetnRatingSystem(Context context) {
- if (sHasReadContentRatingSystem == null) {
- sHasReadContentRatingSystem =
- context.checkSelfPermission(
- "android.permission.READ_CONTENT_RATING_SYSTEMS")
- == PackageManager.PERMISSION_GRANTED;
- }
- return sHasReadContentRatingSystem;
- }
}
diff --git a/common/src/com/android/tv/common/util/PostalCodeUtils.java b/common/src/com/android/tv/common/util/PostalCodeUtils.java
index 6ca3d48c..c0917af2 100644
--- a/common/src/com/android/tv/common/util/PostalCodeUtils.java
+++ b/common/src/com/android/tv/common/util/PostalCodeUtils.java
@@ -17,12 +17,12 @@
package com.android.tv.common.util;
import android.content.Context;
+import android.location.Address;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.common.CommonPreferences;
-
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
@@ -62,7 +62,7 @@ public class PostalCodeUtils {
/** Returns {@code true} if postal code has been changed */
public static boolean updatePostalCode(Context context)
throws IOException, SecurityException, NoPostalCodeException {
- String postalCode = LocationUtils.getCurrentPostalCode(context);
+ String postalCode = getPostalCode(context);
String lastPostalCode = getLastPostalCode(context);
if (TextUtils.isEmpty(postalCode)) {
if (TextUtils.isEmpty(lastPostalCode)) {
@@ -92,6 +92,21 @@ public class PostalCodeUtils {
CommonPreferences.setLastPostalCode(context, postalCode);
}
+ @Nullable
+ private static String getPostalCode(Context context) throws IOException, SecurityException {
+ Address address = LocationUtils.getCurrentAddress(context);
+ if (address != null) {
+ Log.i(
+ TAG,
+ "Current country and postal code is "
+ + address.getCountryName()
+ + ", "
+ + address.getPostalCode());
+ return address.getPostalCode();
+ }
+ return null;
+ }
+
/** An {@link java.lang.Exception} class to notify no valid postal or zip code is available. */
public static class NoPostalCodeException extends Exception {
public NoPostalCodeException() {}
diff --git a/common/src/com/android/tv/common/util/SystemProperties.java b/common/src/com/android/tv/common/util/SystemProperties.java
index 72920b6b..6ac2907b 100644
--- a/common/src/com/android/tv/common/util/SystemProperties.java
+++ b/common/src/com/android/tv/common/util/SystemProperties.java
@@ -21,6 +21,25 @@ import com.android.tv.common.BooleanSystemProperty;
/** A convenience class for getting TV related system properties. */
public final class SystemProperties {
+ /** Allow Google Analytics for eng builds. */
+ public static final BooleanSystemProperty ALLOW_ANALYTICS_IN_ENG =
+ new BooleanSystemProperty("tv_allow_analytics_in_eng", false);
+
+ /** Allow Strict mode for debug builds. */
+ public static final BooleanSystemProperty ALLOW_STRICT_MODE =
+ new BooleanSystemProperty("tv_allow_strict_mode", true);
+
+ /** When true {@link android.view.KeyEvent}s are logged. Defaults to false. */
+ public static final BooleanSystemProperty LOG_KEYEVENT =
+ new BooleanSystemProperty("tv_log_keyevent", false);
+ /** When true debug keys are used. Defaults to false. */
+ public static final BooleanSystemProperty USE_DEBUG_KEYS =
+ new BooleanSystemProperty("tv_use_debug_keys", false);
+
+ /** Send {@link com.android.tv.analytics.Tracker} information. Defaults to {@code true}. */
+ public static final BooleanSystemProperty USE_TRACKER =
+ new BooleanSystemProperty("tv_use_tracker", true);
+
/** Allow third party inputs. */
public static final BooleanSystemProperty ALLOW_THIRD_PARTY_INPUTS =
new BooleanSystemProperty("ro.tv_allow_third_party_inputs", true);
diff --git a/common/tests/robotests/src/com/android/tv/common/TvContentRatingCacheTest.java b/common/tests/robotests/src/com/android/tv/common/TvContentRatingCacheTest.java
deleted file mode 100644
index 521b2205..00000000
--- a/common/tests/robotests/src/com/android/tv/common/TvContentRatingCacheTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.common;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.content.ComponentCallbacks2;
-import android.media.tv.TvContentRating;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.constants.TvContentRatingConstants;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Test for {@link TvContentRatingCache}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvContentRatingCacheTest {
- /** US_TV_MA and US_TV_Y7 in order */
- public static final String MA_AND_Y7 =
- TvContentRatingConstants.STRING_US_TV_MA
- + ","
- + TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV;
-
- /** US_TV_MA and US_TV_Y7 not in order */
- public static final String Y7_AND_MA =
- TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV
- + ","
- + TvContentRatingConstants.STRING_US_TV_MA;
-
- final TvContentRatingCache mCache = TvContentRatingCache.getInstance();
-
- @Before
- public void setUp() {
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- }
-
- @After
- public void tearDown() {
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- }
-
- @Test
- public void testGetRatings_US_TV_MA() {
- ImmutableList<TvContentRating> result =
- mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- assertThat(result).contains(TvContentRatingConstants.CONTENT_RATING_US_TV_MA);
- }
-
- @Test
- public void testGetRatings_US_TV_MA_same() {
- ImmutableList<TvContentRating> first =
- mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- ImmutableList<TvContentRating> second =
- mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- assertThat(first).isSameInstanceAs(second);
- }
-
- @Test
- public void testGetRatings_US_TV_MA_diffAfterClear() {
- ImmutableList<TvContentRating> first =
- mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- ImmutableList<TvContentRating> second =
- mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- assertThat(first).isNotSameInstanceAs(second);
- }
-
- @Test
- public void testGetRatings_TWO_orderDoesNotMatter() {
- ImmutableList<TvContentRating> first = mCache.getRatings(MA_AND_Y7);
- ImmutableList<TvContentRating> second = mCache.getRatings(Y7_AND_MA);
- assertThat(first).isSameInstanceAs(second);
- }
-
- @Test
- public void testContentRatingsToString_null() {
- String result = TvContentRatingCache.contentRatingsToString(null);
- assertWithMessage("ratings string").that(result).isNull();
- }
-
- @Test
- public void testContentRatingsToString_none() {
- String result = TvContentRatingCache.contentRatingsToString(ImmutableList.of());
- assertWithMessage("ratings string").that(result).isEmpty();
- }
-
- @Test
- public void testContentRatingsToString_one() {
- String result =
- TvContentRatingCache.contentRatingsToString(
- ImmutableList.of(TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertWithMessage("ratings string")
- .that(result)
- .isEqualTo(TvContentRatingConstants.STRING_US_TV_MA);
- }
-
- @Test
- public void testContentRatingsToString_twoInOrder() {
- String result =
- TvContentRatingCache.contentRatingsToString(
- ImmutableList.of(
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV));
- assertWithMessage("ratings string").that(result).isEqualTo(MA_AND_Y7);
- }
-
- @Test
- public void testContentRatingsToString_twoNotInOrder() {
- String result =
- TvContentRatingCache.contentRatingsToString(
- ImmutableList.of(
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV,
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertWithMessage("ratings string").that(result).isEqualTo(MA_AND_Y7);
- }
-
- @Test
- public void testContentRatingsToString_double() {
- String result =
- TvContentRatingCache.contentRatingsToString(
- ImmutableList.of(
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertWithMessage("ratings string")
- .that(result)
- .isEqualTo(TvContentRatingConstants.STRING_US_TV_MA);
- }
-
- @Test
- public void testStringToContentRatings_null() {
- assertThat(TvContentRatingCache.stringToContentRatings(null)).isEmpty();
- }
-
- @Test
- public void testStringToContentRatings_none() {
- assertThat(TvContentRatingCache.stringToContentRatings("")).isEmpty();
- }
-
- @Test
- public void testStringToContentRatings_bad() {
- assertThat(TvContentRatingCache.stringToContentRatings("bad")).isEmpty();
- }
-
- @Test
- public void testStringToContentRatings_oneGoodOneBad() {
- ImmutableList<TvContentRating> results =
- TvContentRatingCache.stringToContentRatings(
- TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV + ",bad");
- assertWithMessage("ratings")
- .that(results)
- .containsExactly(TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV);
- }
-
- @Test
- public void testStringToContentRatings_one() {
- ImmutableList<TvContentRating> results =
- TvContentRatingCache.stringToContentRatings(
- TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV);
- assertWithMessage("ratings")
- .that(results)
- .containsExactly(TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV);
- }
-
- @Test
- public void testStringToContentRatings_twoNotInOrder() {
- ImmutableList<TvContentRating> results =
- TvContentRatingCache.stringToContentRatings(Y7_AND_MA);
- assertWithMessage("ratings")
- .that(results)
- .containsExactly(
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV);
- }
-
- @Test
- public void testStringToContentRatings_twoInOrder() {
- ImmutableList<TvContentRating> results =
- TvContentRatingCache.stringToContentRatings(MA_AND_Y7);
- assertWithMessage("ratings")
- .that(results)
- .containsExactly(
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV);
- }
-
- @Test
- public void testStringToContentRatings_double() {
- ImmutableList<TvContentRating> results =
- TvContentRatingCache.stringToContentRatings(
- TvContentRatingConstants.STRING_US_TV_MA
- + ","
- + TvContentRatingConstants.STRING_US_TV_MA);
- assertWithMessage("ratings")
- .that(results)
- .containsExactly((TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
-
- assertThat(results).containsExactly(TvContentRatingConstants.CONTENT_RATING_US_TV_MA);
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/actions/InputSetupActionUtilsTest.java b/common/tests/robotests/src/com/android/tv/common/actions/InputSetupActionUtilsTest.java
deleted file mode 100644
index be586be5..00000000
--- a/common/tests/robotests/src/com/android/tv/common/actions/InputSetupActionUtilsTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.actions;
-
-import static com.google.android.libraries.testing.truth.BundleSubject.assertThat;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link InputSetupActionUtils} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class InputSetupActionUtilsTest {
-
- @Test
- public void hasInputSetupAction_launchInputSetup() {
- Intent intent = new Intent("com.android.tv.action.LAUNCH_INPUT_SETUP");
- assertThat(InputSetupActionUtils.hasInputSetupAction(intent)).isTrue();
- }
-
- @Test
- public void hasInputSetupAction_googleLaunchInputSetup() {
- Intent intent = new Intent("com.google.android.tv.action.LAUNCH_INPUT_SETUP");
- assertThat(InputSetupActionUtils.hasInputSetupAction(intent)).isTrue();
- }
-
- @Test
- public void hasInputSetupAction_bad() {
- Intent intent = new Intent("com.example.action.LAUNCH_INPUT_SETUP");
- assertThat(InputSetupActionUtils.hasInputSetupAction(intent)).isFalse();
- }
-
- @Test
- public void getExtraActivityAfter_null() {
- Intent intent = new Intent();
- assertThat(InputSetupActionUtils.getExtraActivityAfter(intent)).isNull();
- }
-
- @Test
- public void getExtraActivityAfter_activityAfter() {
- Intent intent = new Intent();
- Intent after = new Intent("after");
- intent.putExtra("com.android.tv.intent.extra.ACTIVITY_AFTER_COMPLETION", after);
- assertThat(InputSetupActionUtils.getExtraActivityAfter(intent)).isEqualTo(after);
- }
-
- @Test
- public void getExtraActivityAfter_googleActivityAfter() {
- Intent intent = new Intent();
- Intent after = new Intent("google_setup");
- intent.putExtra("com.google.android.tv.intent.extra.ACTIVITY_AFTER_COMPLETION", after);
- assertThat(InputSetupActionUtils.getExtraActivityAfter(intent)).isEqualTo(after);
- }
-
- @Test
- public void getExtraSetupIntent_null() {
- Intent intent = new Intent();
- assertThat(InputSetupActionUtils.getExtraSetupIntent(intent)).isNull();
- }
-
- @Test
- public void getExtraSetupIntent_setupIntent() {
- Intent intent = new Intent();
- Intent setup = new Intent("setup");
- intent.putExtra("com.android.tv.extra.SETUP_INTENT", setup);
- assertThat(InputSetupActionUtils.getExtraSetupIntent(intent)).isEqualTo(setup);
- }
-
- @Test
- public void getExtraSetupIntent_googleSetupIntent() {
- Intent intent = new Intent();
- Intent setup = new Intent("google_setup");
- intent.putExtra("com.google.android.tv.extra.SETUP_INTENT", setup);
- assertThat(InputSetupActionUtils.getExtraSetupIntent(intent)).isEqualTo(setup);
- }
-
- @Test
- public void removeSetupIntent_empty() {
- Bundle extras = new Bundle();
- InputSetupActionUtils.removeSetupIntent(extras);
- assertThat(extras).exactlyMatches(new Bundle());
- }
-
- @Test
- public void removeSetupIntent_other() {
- Bundle extras = createTestBundle();
- Bundle expected = createTestBundle();
- InputSetupActionUtils.removeSetupIntent(extras);
- assertThat(extras).exactlyMatches(expected);
- }
-
- @Test
- public void removeSetupIntent_setup() {
- Bundle extras = createTestBundle();
- Bundle expected = createTestBundle();
- Intent setup = new Intent("setup");
- extras.putParcelable("com.android.tv.extra.SETUP_INTENT", setup);
- InputSetupActionUtils.removeSetupIntent(extras);
- assertThat(extras).exactlyMatches(expected);
- }
-
- @Test
- public void removeSetupIntent_googleSetup() {
- Bundle extras = createTestBundle();
- Bundle expected = createTestBundle();
- Intent googleSetup = new Intent("googleSetup");
- extras.putParcelable("com.google.android.tv.extra.SETUP_INTENT", googleSetup);
- InputSetupActionUtils.removeSetupIntent(extras);
- assertThat(extras).exactlyMatches(expected);
- }
-
- @Test
- public void removeSetupIntent_bothSetups() {
- Bundle extras = createTestBundle();
- Bundle expected = createTestBundle();
- Intent setup = new Intent("setup");
- extras.putParcelable("com.android.tv.extra.SETUP_INTENT", setup);
- Intent googleSetup = new Intent("googleSetup");
- extras.putParcelable("com.google.android.tv.extra.SETUP_INTENT", googleSetup);
- InputSetupActionUtils.removeSetupIntent(extras);
- assertThat(extras).exactlyMatches(expected);
- }
-
- private static Bundle createTestBundle() {
- Bundle extras = new Bundle();
- extras.putInt("other", 1);
- return extras;
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/compat/TvInputInfoCompatTest.java b/common/tests/robotests/src/com/android/tv/common/compat/TvInputInfoCompatTest.java
deleted file mode 100644
index 5c10c00b..00000000
--- a/common/tests/robotests/src/com/android/tv/common/compat/TvInputInfoCompatTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.compat;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.fail;
-
-import android.content.pm.ResolveInfo;
-import android.content.res.XmlResourceParser;
-import android.media.tv.TvInputInfo;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.utils.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.StringReader;
-
-/** Tests for {@link TvInputInfoCompat}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvInputInfoCompatTest {
- private TvInputInfoCompat mTvInputInfoCompat;
- private String mInputXml;
-
- @Before
- public void setUp() throws Exception {
- ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
- TvInputInfo info =
- TestUtils.createTvInputInfo(
- resolveInfo, "test_input", "test1", TvInputInfo.TYPE_OTHER, false);
- mTvInputInfoCompat =
- new TvInputInfoCompat(InstrumentationRegistry.getTargetContext(), info) {
- @Override
- XmlPullParser getXmlResourceParser() {
- XmlPullParser xpp = null;
- try {
- xpp = XmlPullParserFactory.newInstance().newPullParser();
- xpp.setInput(new StringReader(mInputXml));
- xpp.setFeature(XmlResourceParser.FEATURE_PROCESS_NAMESPACES, true);
- } catch (XmlPullParserException e) {
- fail("failed in setUp() " + e.getMessage());
- }
- return xpp;
- }
- };
- }
-
- @Test
- public void testGetAttributeValue_notTvInputTag() {
- mInputXml =
- "<not-tv-input xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
- + " android:setupActivity=\"\"\n"
- + " android:settingsActivity=\"\"/>\n";
- assertThat(mTvInputInfoCompat.getExtras()).isEmpty();
- }
-
- @Test
- public void testGetAttributeValue_noExtra() {
- mInputXml =
- "<not-tv-input xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
- + " android:setupActivity=\"\"\n"
- + " android:settingsActivity=\"\"/>\n";
- assertThat(mTvInputInfoCompat.getExtras()).isEmpty();
- }
-
- @Test
- public void testGetAttributeValue() {
- mInputXml =
- "<tv-input xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
- + " android:setupActivity=\"\"\n"
- + " android:settingsActivity=\"\">\n"
- + " <extra android:name=\"otherAttr1\" android:value=\"false\" />\n"
- + " <extra android:name=\"otherAttr2\" android:value=\"false\" />\n"
- + " <extra android:name="
- + " \"com.android.tv.common.compat.tvinputinfocompat.audioOnly\""
- + " android:value=\"true\" />\n"
- + "</tv-input>";
- assertThat(mTvInputInfoCompat.getExtras())
- .containsExactly(
- "otherAttr1",
- "false",
- "otherAttr2",
- "false",
- "com.android.tv.common.compat.tvinputinfocompat.audioOnly",
- "true");
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateCommandTest.java b/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateCommandTest.java
deleted file mode 100644
index aa9221fa..00000000
--- a/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateCommandTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.compat.internal;
-
-import static org.mockito.Mockito.only;
-import static org.mockito.Mockito.verify;
-
-import com.android.tv.common.compat.api.SessionCompatCommands;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.testing.mockito.Mocks;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/**
- * Tests sending {@link Commands.PrivateCommand}s to a {@link SessionCompatCommands} from {@link
- * TvViewCompatProcessor} via {@link TifSessionCompatProcessor}.
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class PrivateCommandTest {
- @Rule public final Mocks mocks = new Mocks(this);
-
- @Mock SessionCompatCommands mCallback;
-
- private TvViewCompatProcessor mTvViewCompatProcessor;
-
- @Before
- public void setUp() {
- TifSessionCompatProcessor sessionCompatProcessor =
- new TifSessionCompatProcessor(null, mCallback);
- mTvViewCompatProcessor =
- new TvViewCompatProcessor(sessionCompatProcessor::handleAppPrivateCommand);
- }
-
- @Test
- public void notifyDevToast() throws InvalidProtocolBufferException {
- mTvViewCompatProcessor.devMessage("Hello Developers");
- verify(mCallback, only()).onDevMessage("Hello Developers");
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateRecordingCommandTest.java b/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateRecordingCommandTest.java
deleted file mode 100644
index 1a3c0916..00000000
--- a/common/tests/robotests/src/com/android/tv/common/compat/internal/PrivateRecordingCommandTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.compat.internal;
-
-import static org.mockito.Mockito.only;
-import static org.mockito.Mockito.verify;
-
-import com.android.tv.common.compat.api.RecordingSessionCompatCommands;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.testing.mockito.Mocks;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/**
- * Tests sending {@link RecordingCommands.PrivateRecordingCommand}s to a {@link
- * RecordingSessionCompatCommands} from {@link RecordingClientCompatProcessor} via {@link
- * RecordingSessionCompatProcessor}.
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class PrivateRecordingCommandTest {
- @Rule public final Mocks mocks = new Mocks(this);
-
- @Mock private RecordingSessionCompatCommands mCallback;
-
- private RecordingClientCompatProcessor mCompatProcessor;
-
- @Before
- public void setUp() {
- RecordingSessionCompatProcessor sessionCompatProcessor =
- new RecordingSessionCompatProcessor(null, mCallback);
- mCompatProcessor =
- new RecordingClientCompatProcessor(
- sessionCompatProcessor::handleAppPrivateCommand, null);
- }
-
- @Test
- public void notifyDevToast() throws InvalidProtocolBufferException {
- mCompatProcessor.devMessage("Hello Recorders");
- verify(mCallback, only()).onDevMessage("Hello Recorders");
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/compat/internal/RecordingSessionEventTest.java b/common/tests/robotests/src/com/android/tv/common/compat/internal/RecordingSessionEventTest.java
deleted file mode 100644
index 3de3a6df..00000000
--- a/common/tests/robotests/src/com/android/tv/common/compat/internal/RecordingSessionEventTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.compat.internal;
-
-import static org.mockito.Mockito.only;
-import static org.mockito.Mockito.verify;
-
-import com.android.tv.common.compat.api.RecordingClientCallbackCompatEvents;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.testing.mockito.Mocks;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/**
- * Tests sending {@link RecordingEvents.RecordingSessionEvent}s to a {@link
- * RecordingClientCallbackCompatEvents} from {@link RecordingSessionCompatProcessor} via {@link
- * RecordingClientCompatProcessor}.
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class RecordingSessionEventTest {
- @Rule public final Mocks mocks = new Mocks(this);
-
- @Mock RecordingClientCallbackCompatEvents mCallback;
-
- private RecordingSessionCompatProcessor mCompatProcess;
-
- @Before
- public void setUp() {
- RecordingClientCompatProcessor compatProcessor =
- new RecordingClientCompatProcessor(null, mCallback);
- mCompatProcess =
- new RecordingSessionCompatProcessor(
- (event, data) -> compatProcessor.handleEvent("testinput", event, data),
- null);
- }
-
- @Test
- public void notifyDevToast() throws InvalidProtocolBufferException {
- mCompatProcess.notifyDevToast("Recording");
- verify(mCallback, only()).onDevToast("testinput", "Recording");
- }
-
- @Test
- public void notifyRecordingStarted() throws InvalidProtocolBufferException {
- mCompatProcess.notifyRecordingStarted("file:example");
- verify(mCallback, only()).onRecordingStarted("testinput", "file:example");
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/compat/internal/SessionEventTest.java b/common/tests/robotests/src/com/android/tv/common/compat/internal/SessionEventTest.java
deleted file mode 100644
index e65297cc..00000000
--- a/common/tests/robotests/src/com/android/tv/common/compat/internal/SessionEventTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.compat.internal;
-
-import static org.mockito.Mockito.only;
-import static org.mockito.Mockito.verify;
-
-import com.android.tv.common.compat.api.TvInputCallbackCompatEvents;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.testing.mockito.Mocks;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/**
- * Tests sending {@link Events.SessionEvent}s to a {@link TvInputCallbackCompatEvents} from {@link
- * TifSessionCompatProcessor} via {@link TvViewCompatProcessor}.
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SessionEventTest {
- @Rule public final Mocks mocks = new Mocks(this);
-
- @Mock TvInputCallbackCompatEvents mCallback;
-
- private TifSessionCompatProcessor mCompatProcess;
-
- @Before
- public void setUp() {
- TvViewCompatProcessor tvViewCompatProcessor = new TvViewCompatProcessor(null);
- tvViewCompatProcessor.setCallback(mCallback);
- mCompatProcess =
- new TifSessionCompatProcessor(
- (event, data) ->
- tvViewCompatProcessor.handleEvent("testinput", event, data),
- null);
- }
-
- @Test
- public void notifyDevToast() throws InvalidProtocolBufferException {
- mCompatProcess.notifyDevToast("testing");
- verify(mCallback, only()).onDevToast("testinput", "testing");
- }
-
- @Test
- public void notifySignalStrength() throws InvalidProtocolBufferException {
- mCompatProcess.notifySignalStrength(3);
- verify(mCallback, only()).onSignalStrength("testinput", 3);
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/dev/DeveloperPreferenceTest.java b/common/tests/robotests/src/com/android/tv/common/dev/DeveloperPreferenceTest.java
deleted file mode 100644
index a9c15ada..00000000
--- a/common/tests/robotests/src/com/android/tv/common/dev/DeveloperPreferenceTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.dev;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/** Test for {@link DeveloperPreference}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class DeveloperPreferenceTest {
-
- @Test
- public void createBoolean_default_true() {
- DeveloperPreference<Boolean> devPref = DeveloperPreference.create("test", true);
- assertThat(devPref.get(RuntimeEnvironment.systemContext)).isTrue();
- DeveloperPreference.getPreferences(RuntimeEnvironment.systemContext)
- .edit()
- .putBoolean("test", false)
- .apply();
- assertThat(devPref.get(RuntimeEnvironment.systemContext)).isFalse();
- }
-
- @Test
- public void create_integer_default_one() {
- DeveloperPreference<Integer> devPref = DeveloperPreference.create("test", 1);
- assertThat(devPref.get(RuntimeEnvironment.systemContext)).isEqualTo(1);
- DeveloperPreference.getPreferences(RuntimeEnvironment.systemContext)
- .edit()
- .putInt("test", 2)
- .apply();
- assertThat(devPref.get(RuntimeEnvironment.systemContext)).isEqualTo(2);
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/support/tis/BaseTvInputServiceTest.java b/common/tests/robotests/src/com/android/tv/common/support/tis/BaseTvInputServiceTest.java
deleted file mode 100644
index 88b0215e..00000000
--- a/common/tests/robotests/src/com/android/tv/common/support/tis/BaseTvInputServiceTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.android.tv.common.support.tis;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Intent;
-import android.media.tv.TvContentRating;
-import android.media.tv.TvInputManager;
-import android.net.Uri;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.view.Surface;
-
-import com.android.tv.common.support.tis.TifSession.TifSessionCallbacks;
-import com.android.tv.common.support.tis.TifSession.TifSessionFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ServiceController;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link BaseTvInputService}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(minSdk = Build.VERSION_CODES.LOLLIPOP, maxSdk = Build.VERSION_CODES.P)
-public class BaseTvInputServiceTest {
-
- private static class TestTvInputService extends BaseTvInputService {
-
- private final SessionManager sessionManager = new SimpleSessionManager(1);
-
- private int parentalControlsChangedCount = 0;
- private final TifSessionFactory sessionFactory;
-
- private TestTvInputService() {
- super();
- this.sessionFactory =
- new TifSessionFactory() {
- @Override
- public TifSession create(TifSessionCallbacks callbacks, String inputId) {
- return new TifSession(callbacks) {
- @Override
- public boolean onSetSurface(@Nullable Surface surface) {
- return false;
- }
-
- @Override
- public void onSurfaceChanged(int format, int width, int height) {}
-
- @Override
- public void onSetStreamVolume(float volume) {}
-
- @Override
- public boolean onTune(Uri channelUri) {
- return false;
- }
-
- @Override
- public void onSetCaptionEnabled(boolean enabled) {}
-
- @Override
- public void onUnblockContent(TvContentRating unblockedRating) {}
-
- @Override
- public void onParentalControlsChanged() {
- parentalControlsChangedCount++;
- }
- };
- }
- };
- }
-
- @Override
- protected TifSessionFactory getTifSessionFactory() {
- return sessionFactory;
- }
-
- @Override
- protected SessionManager getSessionManager() {
- return sessionManager;
- }
-
- private int getParentalControlsChangedCount() {
- return parentalControlsChangedCount;
- }
- }
-
- TestTvInputService tvInputService;
- ServiceController<TestTvInputService> controller;
-
- @Before
- public void setUp() {
- controller = Robolectric.buildService(TestTvInputService.class);
- tvInputService = controller.create().get();
- }
-
- @Test
- public void createSession_once() {
- assertThat(tvInputService.onCreateSession("test")).isNotNull();
- }
-
- @Test
- public void createSession_twice() {
- WrappedSession first = tvInputService.onCreateSession("test");
- assertThat(first).isNotNull();
- WrappedSession second = tvInputService.onCreateSession("test");
- assertThat(second).isNull();
- }
-
- @Test
- public void createSession_release() {
- WrappedSession first = tvInputService.onCreateSession("test");
- assertThat(first).isNotNull();
- first.onRelease();
- WrappedSession second = tvInputService.onCreateSession("test");
- assertThat(second).isNotNull();
- assertThat(second).isNotSameInstanceAs(first);
- }
-
- @Test
- public void testReceiver_actionEnabledChanged() {
- tvInputService.getSessionManager().addSession(tvInputService.onCreateSession("test"));
- tvInputService.broadcastReceiver.onReceive(
- RuntimeEnvironment.application,
- new Intent(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED));
- assertThat(tvInputService.getParentalControlsChangedCount()).isEqualTo(1);
- }
-
- @Test
- public void testReceiver_actionBlockedChanged() {
- tvInputService.getSessionManager().addSession(tvInputService.onCreateSession("test"));
- tvInputService.broadcastReceiver.onReceive(
- RuntimeEnvironment.application,
- new Intent(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED));
- assertThat(tvInputService.getParentalControlsChangedCount()).isEqualTo(1);
- }
-
- @Test
- public void testReceiver_invalidAction() {
- tvInputService.getSessionManager().addSession(tvInputService.onCreateSession("test"));
- tvInputService.broadcastReceiver.onReceive(
- RuntimeEnvironment.application, new Intent("test"));
- assertThat(tvInputService.getParentalControlsChangedCount()).isEqualTo(0);
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/support/tis/SimpleSessionManagerTest.java b/common/tests/robotests/src/com/android/tv/common/support/tis/SimpleSessionManagerTest.java
deleted file mode 100644
index 3972559f..00000000
--- a/common/tests/robotests/src/com/android/tv/common/support/tis/SimpleSessionManagerTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.android.tv.common.support.tis;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvContentRating;
-import android.net.Uri;
-import android.os.Build;
-import android.support.annotation.FloatRange;
-import android.support.annotation.Nullable;
-import android.view.Surface;
-
-import com.android.tv.common.support.tis.TifSession.TifSessionCallbacks;
-import com.android.tv.common.support.tis.TifSession.TifSessionFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link SimpleSessionManager}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(minSdk = Build.VERSION_CODES.LOLLIPOP, maxSdk = Build.VERSION_CODES.P)
-public class SimpleSessionManagerTest {
-
- private SimpleSessionManager sessionManager;
-
- @Before
- public void setup() {
- sessionManager = new SimpleSessionManager(1);
- }
-
- @Test
- public void canCreateSession_none() {
- assertThat(sessionManager.canCreateNewSession()).isTrue();
- }
-
- @Test
- public void canCreateSession_one() {
- sessionManager.addSession(createTestSession());
- assertThat(sessionManager.canCreateNewSession()).isFalse();
- }
-
- @Test
- public void addSession() {
- assertThat(sessionManager.getSessionCount()).isEqualTo(0);
- sessionManager.addSession(createTestSession());
- assertThat(sessionManager.getSessionCount()).isEqualTo(1);
- }
-
- @Test
- public void onRelease() {
- WrappedSession testSession = createTestSession();
- sessionManager.addSession(testSession);
- assertThat(sessionManager.getSessionCount()).isEqualTo(1);
- testSession.onRelease();
- assertThat(sessionManager.getSessionCount()).isEqualTo(0);
- }
-
- @Test
- public void onRelease_withUnRegisteredSession() {
- WrappedSession testSession = createTestSession();
- sessionManager.addSession(createTestSession());
- assertThat(sessionManager.getSessionCount()).isEqualTo(1);
- testSession.onRelease();
- assertThat(sessionManager.getSessionCount()).isEqualTo(1);
- }
-
- @Test
- public void getSessions() {
- WrappedSession testSession = createTestSession();
- sessionManager.addSession(testSession);
- assertThat(sessionManager.getSessions()).containsExactly(testSession);
- }
-
- private WrappedSession createTestSession() {
- return new WrappedSession(
- RuntimeEnvironment.application,
- sessionManager,
- new TestTifSessionFactory(),
- "testInputId");
- }
-
- private static final class TestTifSessionFactory implements TifSessionFactory {
-
- @Override
- public TifSession create(TifSessionCallbacks callbacks, String inputId) {
- return new TestTifSession(callbacks);
- }
- }
-
- private static final class TestTifSession extends TifSession {
-
- private TestTifSession(TifSessionCallbacks callbacks) {
- super(callbacks);
- }
-
- @Override
- public void onRelease() {}
-
- @Override
- public boolean onSetSurface(@Nullable Surface surface) {
- return false;
- }
-
- @Override
- public void onSurfaceChanged(int format, int width, int height) {}
-
- @Override
- public void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume) {}
-
- @Override
- public boolean onTune(Uri channelUri) {
- return false;
- }
-
- @Override
- public void onSetCaptionEnabled(boolean enabled) {}
-
- @Override
- public void onUnblockContent(TvContentRating unblockedRating) {}
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/support/tis/TisSessionTest.java b/common/tests/robotests/src/com/android/tv/common/support/tis/TisSessionTest.java
deleted file mode 100644
index e2f849ee..00000000
--- a/common/tests/robotests/src/com/android/tv/common/support/tis/TisSessionTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package com.android.tv.common.support.tis;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvContentRating;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvTrackInfo;
-import android.net.Uri;
-import android.os.Build;
-import android.support.annotation.FloatRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Pair;
-import android.view.Surface;
-import android.view.View;
-
-import com.android.tv.common.support.tis.TifSession.TifSessionCallbacks;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-
-/** Tests for {@link TifSession}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(minSdk = Build.VERSION_CODES.LOLLIPOP, maxSdk = Build.VERSION_CODES.P)
-public class TisSessionTest {
-
- private TestSession testSession;
- private TestCallback testCallback;
-
- @Before
- public void setup() {
- testCallback = new TestCallback();
- testSession = new TestSession(testCallback);
- }
-
- @Test
- public void notifyChannelReturned() {
- Uri uri = Uri.parse("http://example.com");
- testSession.notifyChannelRetuned(uri);
- assertThat(testCallback.channelUri).isEqualTo(uri);
- }
-
- @Test
- public void notifyTracksChanged() {
- List<TvTrackInfo> tracks =
- ImmutableList.of(new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "test").build());
- testSession.notifyTracksChanged(tracks);
- assertThat(testCallback.tracks).isEqualTo(tracks);
- }
-
- @Test
- public void notifyTrackSelected() {
- testSession.notifyTrackSelected(TvTrackInfo.TYPE_AUDIO, "audio_test");
- assertThat(testCallback.trackSelected)
- .isEqualTo(Pair.create(TvTrackInfo.TYPE_AUDIO, "audio_test"));
- }
-
- @Test
- public void notifyVideoAvailable() {
- testSession.notifyVideoAvailable();
- assertThat(testCallback.videoAvailable).isTrue();
- }
-
- @Test
- public void notifyVideoUnavailable() {
- testSession.notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
- assertThat(testCallback.notifyVideoUnavailableReason)
- .isEqualTo(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
- }
-
- @Test
- public void notifyContentAllowed() {
- testSession.notifyContentAllowed();
- assertThat(testCallback.contentAllowed).isTrue();
- }
-
- @Test
- public void notifyContentBlocked() {
- TvContentRating rating = TvContentRating.createRating("1", "2", "3");
- testSession.notifyContentBlocked(rating);
- assertThat(testCallback.blockedContentRating).isEqualTo(rating);
- }
-
- @Test
- public void notifyTimeShiftStatusChanged() {
- testSession.notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
- assertThat(testCallback.timeShiftStatus)
- .isEqualTo(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
- }
-
- @Test
- public void testSetOverlayViewEnabled() {
- testSession.helpTestSetOverlayViewEnabled(true);
- assertThat(testCallback.overlayViewEnabled).isTrue();
-
- testSession.helpTestSetOverlayViewEnabled(false);
- assertThat(testCallback.overlayViewEnabled).isFalse();
- }
-
- @Test
- public void testOnCreateOverlayView() {
- View actualView = testSession.onCreateOverlayView();
- assertThat(actualView).isNull(); // Default implementation returns a null.
- }
-
- @Test
- public void testOnOverlayViewSizeChanged() {
- testSession.onOverlayViewSizeChanged(5 /* width */, 7 /* height */);
- // Just verifing that the call completes.
- }
-
- private static final class TestCallback implements TifSessionCallbacks {
-
- private Uri channelUri;
- private List<TvTrackInfo> tracks;
- private Pair<Integer, String> trackSelected;
- private boolean videoAvailable;
- private int notifyVideoUnavailableReason;
- private boolean contentAllowed;
- private TvContentRating blockedContentRating;
- private int timeShiftStatus;
- private boolean overlayViewEnabled;
-
- @Override
- public void notifyChannelRetuned(Uri channelUri) {
- this.channelUri = channelUri;
- }
-
- @Override
- public void notifyTracksChanged(List<TvTrackInfo> tracks) {
- this.tracks = tracks;
- }
-
- @Override
- public void notifyTrackSelected(int type, String trackId) {
- this.trackSelected = Pair.create(type, trackId);
- }
-
- @Override
- public void notifyVideoAvailable() {
- this.videoAvailable = true;
- }
-
- @Override
- public void notifyVideoUnavailable(int reason) {
- this.notifyVideoUnavailableReason = reason;
- }
-
- @Override
- public void notifyContentAllowed() {
- this.contentAllowed = true;
- }
-
- @Override
- public void notifyContentBlocked(@NonNull TvContentRating rating) {
- this.blockedContentRating = rating;
- }
-
- @Override
- public void notifyTimeShiftStatusChanged(int status) {
- this.timeShiftStatus = status;
- }
-
- @Override
- public void setOverlayViewEnabled(boolean enabled) {
- this.overlayViewEnabled = enabled;
- }
- }
-
- private static final class TestSession extends TifSession {
-
- private TestSession(TifSessionCallbacks callbacks) {
- super(callbacks);
- }
-
- @Override
- public boolean onSetSurface(@Nullable Surface surface) {
- return false;
- }
-
- @Override
- public void onSurfaceChanged(int format, int width, int height) {}
-
- @Override
- public void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume) {}
-
- @Override
- public boolean onTune(Uri channelUri) {
- return false;
- }
-
- @Override
- public void onSetCaptionEnabled(boolean enabled) {}
-
- @Override
- public void onUnblockContent(TvContentRating unblockedRating) {}
-
- public void helpTestSetOverlayViewEnabled(boolean enabled) {
- super.setOverlayViewEnabled(enabled);
- }
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/support/tis/WrappedSessionTest.java b/common/tests/robotests/src/com/android/tv/common/support/tis/WrappedSessionTest.java
deleted file mode 100644
index f5b6146f..00000000
--- a/common/tests/robotests/src/com/android/tv/common/support/tis/WrappedSessionTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-package com.android.tv.common.support.tis;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.PlaybackParams;
-import android.media.tv.TvContentRating;
-import android.net.Uri;
-import android.os.Build;
-import android.view.View;
-
-import com.android.tv.common.support.tis.TifSession.TifSessionCallbacks;
-import com.android.tv.common.support.tis.TifSession.TifSessionFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link WrappedSession}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(minSdk = Build.VERSION_CODES.M, maxSdk = Build.VERSION_CODES.P)
-public class WrappedSessionTest {
-
- @Mock TifSession mockDelegate;
- private TifSessionFactory sessionFactory =
- new TifSessionFactory() {
- @Override
- public TifSession create(TifSessionCallbacks callbacks, String inputId) {
- return mockDelegate;
- }
- };
- private WrappedSession wrappedSession;
- private SimpleSessionManager sessionManager = new SimpleSessionManager(1);
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- wrappedSession =
- new WrappedSession(
- RuntimeEnvironment.application,
- sessionManager,
- sessionFactory,
- "testInputId");
- }
-
- @Test
- public void onRelease() {
- sessionManager.addSession(wrappedSession);
- assertThat(sessionManager.getSessionCount()).isEqualTo(1);
- wrappedSession.onRelease();
- assertThat(sessionManager.getSessionCount()).isEqualTo(0);
- Mockito.verify(mockDelegate).onRelease();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onSetSurface() {
- wrappedSession.onSetSurface(null);
- Mockito.verify(mockDelegate).onSetSurface(null);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onSurfaceChanged() {
- wrappedSession.onSurfaceChanged(1, 2, 3);
- Mockito.verify(mockDelegate).onSurfaceChanged(1, 2, 3);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onSetStreamVolume() {
- wrappedSession.onSetStreamVolume(.8f);
- Mockito.verify(mockDelegate).onSetStreamVolume(.8f);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onTune() {
- Uri uri = Uri.EMPTY;
- wrappedSession.onTune(uri);
- Mockito.verify(mockDelegate).onTune(uri);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onSetCaptionEnabled() {
- wrappedSession.onSetCaptionEnabled(true);
- Mockito.verify(mockDelegate).onSetCaptionEnabled(true);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftGetCurrentPosition() {
- Mockito.when(mockDelegate.onTimeShiftGetCurrentPosition()).thenReturn(7L);
- assertThat(wrappedSession.onTimeShiftGetCurrentPosition()).isEqualTo(7L);
- Mockito.verify(mockDelegate).onTimeShiftGetCurrentPosition();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftGetStartPosition() {
- Mockito.when(mockDelegate.onTimeShiftGetStartPosition()).thenReturn(8L);
- assertThat(wrappedSession.onTimeShiftGetStartPosition()).isEqualTo(8L);
- Mockito.verify(mockDelegate).onTimeShiftGetStartPosition();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftPause() {
- wrappedSession.onTimeShiftPause();
- Mockito.verify(mockDelegate).onTimeShiftPause();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftResume() {
- wrappedSession.onTimeShiftResume();
- Mockito.verify(mockDelegate).onTimeShiftResume();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftSeekTo() {
- wrappedSession.onTimeShiftSeekTo(9L);
- Mockito.verify(mockDelegate).onTimeShiftSeekTo(9L);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onTimeShiftSetPlaybackParams() {
- PlaybackParams paras = new PlaybackParams();
- wrappedSession.onTimeShiftSetPlaybackParams(paras);
- Mockito.verify(mockDelegate).onTimeShiftSetPlaybackParams(paras);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- @Config(minSdk = Build.VERSION_CODES.M)
- public void onUnblockContent() {
- TvContentRating rating =
- TvContentRating.createRating(
- "domain", "rating_system", "rating", "subrating1", "subrating2");
- wrappedSession.onUnblockContent(rating);
- Mockito.verify(mockDelegate).onUnblockContent(rating);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void onParentalControlsChanged() {
- wrappedSession.onParentalControlsChanged();
- Mockito.verify(mockDelegate).onParentalControlsChanged();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void testSetOverlayViewEnabled() {
- wrappedSession.setOverlayViewEnabled(true);
- // Just verifying that the call completes.
- }
-
- @Test
- public void testOnCreateOverlayView() {
- View v = new View(RuntimeEnvironment.application);
- Mockito.when(mockDelegate.onCreateOverlayView()).thenReturn(v);
-
- View actualView = wrappedSession.onCreateOverlayView();
-
- assertThat(actualView).isEqualTo(v);
- Mockito.verify(mockDelegate).onCreateOverlayView();
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-
- @Test
- public void testOnOverlayViewSizeChanged() {
- wrappedSession.onOverlayViewSizeChanged(5 /* width */, 13 /* height */);
- Mockito.verify(mockDelegate).onOverlayViewSizeChanged(5, 13);
- Mockito.verifyNoMoreInteractions(mockDelegate);
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/support/tvprovider/TvContractCompatXTest.java b/common/tests/robotests/src/com/android/tv/common/support/tvprovider/TvContractCompatXTest.java
deleted file mode 100644
index 51cc19dd..00000000
--- a/common/tests/robotests/src/com/android/tv/common/support/tvprovider/TvContractCompatXTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.support.tvprovider;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.Uri;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Test for {@link TvContractCompatX}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvContractCompatXTest {
-
- @Test
- public void buildChannelUri() {
- assertThat(TvContractCompatX.buildChannelUri("com.example", "foo"))
- .isEqualTo(
- Uri.parse(
- "content://android.media.tv/channel?"
- + "package=com.example&internal_provider_id=foo"));
- }
-
- @Test
- public void buildProgramsUriForChannel() {
- assertThat(TvContractCompatX.buildProgramsUriForChannel("com.example", "foo"))
- .isEqualTo(
- Uri.parse(
- "content://android.media.tv/program?"
- + "package=com.example&internal_provider_id=foo"));
- }
-
- @Test
- public void buildProgramsUriForChannel_period() {
- assertThat(TvContractCompatX.buildProgramsUriForChannel("com.example", "foo", 1234L, 5467L))
- .isEqualTo(
- Uri.parse(
- "content://android.media.tv/program?"
- + "package=com.example&internal_provider_id=foo"
- + "&start_time=1234&end_time=5467"));
- }
-
- @Test
- public void buildProgramsUri_period() {
- assertThat(TvContractCompatX.buildProgramsUri(1234L, 5467L))
- .isEqualTo(
- Uri.parse(
- "content://android.media.tv/program?"
- + "start_time=1234&end_time=5467"));
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/util/CommonUtilsTest.java b/common/tests/robotests/src/com/android/tv/common/util/CommonUtilsTest.java
deleted file mode 100644
index 3930ff69..00000000
--- a/common/tests/robotests/src/com/android/tv/common/util/CommonUtilsTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.io.File;
-import java.io.IOException;
-
-/** Tests for {@link CommonUtils}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class CommonUtilsTest {
-
- @Test
- public void deleteDirOrFile_file() throws IOException {
- File file = new File(RuntimeEnvironment.application.getExternalFilesDir(null), "file");
- assertThat(file.createNewFile()).isTrue();
- assertThat(CommonUtils.deleteDirOrFile(file)).isTrue();
- assertThat(file.exists()).isFalse();
- }
-
- @Test
- public void deleteDirOrFile_Dir() throws IOException {
- File dir = new File(RuntimeEnvironment.application.getExternalFilesDir(null), "dir");
- assertThat(dir.mkdirs()).isTrue();
- assertThat(new File(dir, "file").createNewFile()).isTrue();
- assertThat(CommonUtils.deleteDirOrFile(dir)).isTrue();
- assertThat(dir.exists()).isFalse();
- }
-
- @Test
- public void deleteDirOrFile_unreadableDir() throws IOException {
- File dir = new File(RuntimeEnvironment.application.getExternalFilesDir(null), "dir");
- assertThat(dir.mkdirs()).isTrue();
- assertThat(new File(dir, "file").createNewFile()).isTrue();
- dir.setReadable(false);
- // Since dir is unreadable dir.listFiles() returns null and file is not deleted thus
- // dir is not actually deleted.
- assertThat(CommonUtils.deleteDirOrFile(dir)).isFalse();
- assertThat(dir.exists()).isTrue();
- }
-
- @Test
- public void deleteDirOrFile_unreadableSubDir() throws IOException {
- File dir = new File(RuntimeEnvironment.application.getExternalFilesDir(null), "dir");
- File subDir = new File(dir, "sub");
- assertThat(subDir.mkdirs()).isTrue();
- File file = new File(subDir, "file");
- assertThat(file.createNewFile()).isTrue();
- subDir.setReadable(false);
- // Since subDir is unreadable subDir.listFiles() returns null and file is not deleted thus
- // dir is not actually deleted.
- assertThat(CommonUtils.deleteDirOrFile(dir)).isFalse();
- assertThat(dir.exists()).isTrue();
- }
-}
diff --git a/common/tests/robotests/src/com/android/tv/common/util/ContentUriUtilsTest.java b/common/tests/robotests/src/com/android/tv/common/util/ContentUriUtilsTest.java
deleted file mode 100644
index 58286724..00000000
--- a/common/tests/robotests/src/com/android/tv/common/util/ContentUriUtilsTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.Uri;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link ContentUriUtils}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class ContentUriUtilsTest {
-
- @Test
- public void safeParseId_empty() {
- assertThat(ContentUriUtils.safeParseId(Uri.EMPTY)).isEqualTo(-1);
- }
-
- @Test
- public void safeParseId_bad() {
- assertThat(ContentUriUtils.safeParseId(Uri.parse("foo/bad"))).isEqualTo(-1);
- }
-
- @Test
- public void safeParseId_123() {
- assertThat(ContentUriUtils.safeParseId(Uri.parse("foo/123"))).isEqualTo(123);
- }
-}
diff --git a/gradle.properties b/gradle.properties
index 9d027fe0..62082346 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -21,5 +21,4 @@ org.gradle.jvmargs=-Xmx6144m -XX:MaxPermSize=6144m -XX:+HeapDumpOnOutOfMemoryErr
org.gradle.daemon=true
org.gradle.parallel=true
-android.useAndroidX=true
-android.enableJetifier=true \ No newline at end of file
+org.gradle.configureondemand=true \ No newline at end of file
diff --git a/jni/DvbManager.cpp b/jni/DvbManager.cpp
index 33209594..f9dff59b 100644
--- a/jni/DvbManager.cpp
+++ b/jni/DvbManager.cpp
@@ -42,6 +42,7 @@ DvbManager::DvbManager(JNIEnv *env, jobject)
mDvrFd(-1),
mPatFilterFd(-1),
mDvbApiVersion(DVB_API_VERSION_UNDEFINED),
+ mDeliverySystemType(-1),
mFeHasLock(false),
mHasPendingTune(false) {
jclass clazz = env->FindClass("com/android/tv/tuner/TunerHal");
@@ -49,8 +50,6 @@ DvbManager::DvbManager(JNIEnv *env, jobject)
env->GetMethodID(clazz, "openDvbFrontEndFd", "()I");
mOpenDvbDemuxMethodID = env->GetMethodID(clazz, "openDvbDemuxFd", "()I");
mOpenDvbDvrMethodID = env->GetMethodID(clazz, "openDvbDvrFd", "()I");
- memset(&mDeliverySystemTypes, DELIVERY_SYSTEM_UNDEFINED,
- sizeof(mDeliverySystemTypes));
}
DvbManager::~DvbManager() {
@@ -116,20 +115,6 @@ int DvbManager::getSignalStrength() {
int DvbManager::tune(JNIEnv *env, jobject thiz,
const int frequency, const char *modulationStr, int timeout_ms) {
- return tuneInternal(env, thiz, DELIVERY_SYSTEM_UNDEFINED, frequency,
- modulationStr, timeout_ms);
-}
-
-int DvbManager::tune(JNIEnv *env, jobject thiz,
- const int deliverySystemType, const int frequency,
- const char *modulationStr, int timeout_ms) {
- return tuneInternal(env, thiz, deliverySystemType, frequency,
- modulationStr, timeout_ms);
-}
-
-int DvbManager::tuneInternal(JNIEnv *env, jobject thiz,
- const int deliverySystemType, const int frequency,
- const char *modulationStr, int timeout_ms) {
resetExceptFe();
if (openDvbFe(env, thiz) != 0) {
@@ -161,36 +146,10 @@ int DvbManager::tuneInternal(JNIEnv *env, jobject thiz,
struct dtv_property deliverySystemProperty = {
.cmd = DTV_DELIVERY_SYSTEM
};
- switch (deliverySystemType) {
- case DELIVERY_SYSTEM_DVBT:
- deliverySystemProperty.u.data = SYS_DVBT;
- break;
- case DELIVERY_SYSTEM_DVBT2:
- deliverySystemProperty.u.data = SYS_DVBT2;
- break;
- case DELIVERY_SYSTEM_DVBS:
- deliverySystemProperty.u.data = SYS_DVBS;
- break;
- case DELIVERY_SYSTEM_DVBS2:
- deliverySystemProperty.u.data = SYS_DVBS2;
- break;
- case DELIVERY_SYSTEM_DVBC:
- deliverySystemProperty.u.data = SYS_DVBC_ANNEX_A;
- break;
- case DELIVERY_SYSTEM_ATSC:
- case DELIVERY_SYSTEM_UNDEFINED:
- deliverySystemProperty.u.data = SYS_ATSC;
- break;
- default:
- ALOGE("Unrecognized delivery system type");
- return -1;
- }
+ deliverySystemProperty.u.data = SYS_ATSC;
struct dtv_property frequencyProperty = {
.cmd = DTV_FREQUENCY
};
- struct dtv_property bandwidthProperty = {
- .cmd = DTV_BANDWIDTH_HZ, .u.data = 8000000
- };
frequencyProperty.u.data = static_cast<__u32>(frequency);
struct dtv_property modulationProperty = { .cmd = DTV_MODULATION };
if (strncmp(modulationStr, "QAM", 3) == 0) {
@@ -204,11 +163,10 @@ int DvbManager::tuneInternal(JNIEnv *env, jobject thiz,
struct dtv_property tuneProperty = { .cmd = DTV_TUNE };
struct dtv_property props[] = {
- deliverySystemProperty, frequencyProperty, modulationProperty,
- bandwidthProperty, tuneProperty
+ deliverySystemProperty, frequencyProperty, modulationProperty, tuneProperty
};
struct dtv_properties dtvProperty = {
- .num = sizeof(props)/sizeof(dtv_property), .props = props
+ .num = 4, .props = props
};
if (mHasPendingTune) {
@@ -257,9 +215,6 @@ int DvbManager::tuneInternal(JNIEnv *env, jobject thiz,
ALOGE("Unrecognized modulation mode : %s", modulationStr);
return -1;
}
- feParams.u.ofdm.code_rate_HP = FEC_AUTO;
- feParams.u.ofdm.code_rate_LP = FEC_AUTO;
- feParams.u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
break;
default:
ALOGE("Unsupported delivery system.");
@@ -507,27 +462,22 @@ void DvbManager::setHasPendingTune(bool hasPendingTune) {
}
int DvbManager::getDeliverySystemType(JNIEnv *env, jobject thiz) {
- getDeliverySystemTypes(env, thiz);
- return mDeliverySystemTypes[0];
-}
-
-int* DvbManager::getDeliverySystemTypes(JNIEnv *env, jobject thiz) {
- ALOGE("getDeliverySystemTypes");
- if (mDeliverySystemTypes[0] != DELIVERY_SYSTEM_UNDEFINED) {
- return mDeliverySystemTypes;
+ if (mDeliverySystemType != -1) {
+ return mDeliverySystemType;
}
if (mFeFd == -1) {
if ((mFeFd = openDvbFeFromSystemApi(env, thiz)) < 0) {
ALOGD("Can't open FE file : %s", strerror(errno));
- return mDeliverySystemTypes;
+ return DELIVERY_SYSTEM_UNDEFINED;
}
}
struct dtv_property testProps[1] = {
- { .cmd = DTV_ENUM_DELSYS }
+ { .cmd = DTV_DELIVERY_SYSTEM }
};
struct dtv_properties feProp = {
.num = 1, .props = testProps
};
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
if (ioctl(mFeFd, FE_GET_PROPERTY, &feProp) == -1) {
mDvbApiVersion = DVB_API_VERSION3;
if (openDvbFe(env, thiz) == 0) {
@@ -535,52 +485,50 @@ int* DvbManager::getDeliverySystemTypes(JNIEnv *env, jobject thiz) {
if (ioctl(mFeFd, FE_GET_INFO, &info) == 0) {
switch (info.type) {
case FE_QPSK:
- mDeliverySystemTypes[0] = DELIVERY_SYSTEM_DVBS;
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS;
break;
case FE_QAM:
- mDeliverySystemTypes[0] = DELIVERY_SYSTEM_DVBC;
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBC;
break;
case FE_OFDM:
- mDeliverySystemTypes[0] = DELIVERY_SYSTEM_DVBT;
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT;
break;
case FE_ATSC:
- mDeliverySystemTypes[0] = DELIVERY_SYSTEM_ATSC;
+ mDeliverySystemType = DELIVERY_SYSTEM_ATSC;
break;
default:
- mDeliverySystemTypes[0] = DELIVERY_SYSTEM_UNDEFINED;
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
break;
}
}
}
} else {
mDvbApiVersion = DVB_API_VERSION5;
- for (unsigned int i = 0; i < feProp.props[0].u.buffer.len; i++) {
- switch (feProp.props[0].u.buffer.data[i]) {
- case SYS_DVBT:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_DVBT;
- break;
- case SYS_DVBT2:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_DVBT2;
- break;
- case SYS_DVBS:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_DVBS;
- break;
- case SYS_DVBS2:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_DVBS2;
- break;
- case SYS_DVBC_ANNEX_A:
- case SYS_DVBC_ANNEX_B:
- case SYS_DVBC_ANNEX_C:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_DVBC;
- break;
- case SYS_ATSC:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_ATSC;
- break;
- default:
- mDeliverySystemTypes[i] = DELIVERY_SYSTEM_UNDEFINED;
- break;
- }
+ switch (feProp.props[0].u.data) {
+ case SYS_DVBT:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT;
+ break;
+ case SYS_DVBT2:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT2;
+ break;
+ case SYS_DVBS:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS;
+ break;
+ case SYS_DVBS2:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS2;
+ break;
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_B:
+ case SYS_DVBC_ANNEX_C:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBC;
+ break;
+ case SYS_ATSC:
+ mDeliverySystemType = DELIVERY_SYSTEM_ATSC;
+ break;
+ default:
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
+ break;
}
}
- return mDeliverySystemTypes;
-}
+ return mDeliverySystemType;
+} \ No newline at end of file
diff --git a/jni/DvbManager.h b/jni/DvbManager.h
index aaa345e7..b01113e1 100644
--- a/jni/DvbManager.h
+++ b/jni/DvbManager.h
@@ -63,7 +63,7 @@ class DvbManager {
int mDvrFd;
int mPatFilterFd;
int mDvbApiVersion;
- int mDeliverySystemTypes[8];
+ int mDeliverySystemType;
bool mFeHasLock;
// Flag for pending tune request. Used for canceling the current tune operation.
bool volatile mHasPendingTune;
@@ -78,9 +78,6 @@ public:
~DvbManager();
int tune(JNIEnv *env, jobject thiz,
const int frequency, const char *modulationStr, int timeout_ms);
- int tune(JNIEnv *env, jobject thiz,
- const int deliverySystemType, const int frequency,
- const char *modulationStr, int timeout_ms);
int stopTune();
int readTsStream(JNIEnv *env, jobject thiz,
uint8_t *tsBuffer, int tsBufferSize, int timeout_ms);
@@ -88,13 +85,9 @@ public:
void closeAllDvbPidFilter();
void setHasPendingTune(bool hasPendingTune);
int getDeliverySystemType(JNIEnv *env, jobject thiz);
- int *getDeliverySystemTypes(JNIEnv *env, jobject thiz);
int getSignalStrength();
private:
- int tuneInternal(JNIEnv *env, jobject thiz,
- const int deliverySystemType, const int frequency,
- const char *modulationStr, int timeout_ms);
int openDvbFe(JNIEnv *env, jobject thiz);
int openDvbDvr(JNIEnv *env, jobject thiz);
void closePatFilter();
diff --git a/jni/tunertvinput_jni.cpp b/jni/tunertvinput_jni.cpp
index 579b92e2..030f9617 100644
--- a/jni/tunertvinput_jni.cpp
+++ b/jni/tunertvinput_jni.cpp
@@ -49,12 +49,11 @@ JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeFinalize(
/*
* Class: com_android_tv_tuner_TunerHal
* Method: nativeTune
- * Signature: (JILjava/lang/String;I)Z
+ * Signature: (JILjava/lang/String;)Z
*/
-JNIEXPORT jboolean JNICALL
- Java_com_android_tv_tuner_TunerHal_nativeTune__JILjava_lang_String_2I(
- JNIEnv *env, jobject thiz, jlong deviceId, jint frequency,
- jstring modulation, jint timeout_ms) {
+JNIEXPORT jboolean JNICALL Java_com_android_tv_tuner_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;
if (it == sDvbManagers.end()) {
@@ -70,29 +69,6 @@ JNIEXPORT jboolean JNICALL
/*
* Class: com_android_tv_tuner_TunerHal
- * Method: nativeTune
- * Signature: (JIILjava/lang/String;I)Z
- */
-JNIEXPORT jboolean JNICALL
- Java_com_android_tv_tuner_TunerHal_nativeTune__JIILjava_lang_String_2I(
- JNIEnv *env, jobject thiz, jlong deviceId, jint deliverySystemType,
- jint frequency, jstring modulation, jint timeout_ms) {
- std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
- DvbManager *dvbManager;
- if (it == sDvbManagers.end()) {
- dvbManager = new DvbManager(env, thiz);
- sDvbManagers.insert(
- std::pair<jlong, DvbManager *>(deviceId, dvbManager));
- } else {
- dvbManager = it->second;
- }
- int res = dvbManager->tune(env, thiz, deliverySystemType, frequency,
- env->GetStringUTFChars(modulation, 0), timeout_ms);
- return (res == 0);
-}
-
-/*
- * Class: com_android_tv_tuner_TunerHal
* Method: nativeCloseAllPidFilters
* Signature: (J)V
*/
@@ -214,32 +190,4 @@ Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType(JNIEnv *env,
sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager));
return dvbManager->getDeliverySystemType(env, thiz);
}
-}
-
-/*
- * Class: com_android_tv_tuner_TunerHal
- * Method: nativeGetDeliverySystemTypes
- * Signature: (J)I
- */
-JNIEXPORT jintArray JNICALL
-Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemTypes(JNIEnv *env,
- jobject thiz,
- jlong deviceId) {
- jintArray deliverySystemTypes = env->NewIntArray(8);
- if (deliverySystemTypes == NULL) {
- ALOGE("Out of memory!");
- return NULL;
- }
- std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
- if (it != sDvbManagers.end()) {
- env->SetIntArrayRegion(deliverySystemTypes, 0, 8,
- it->second->getDeliverySystemTypes(env, thiz));
- } else {
- DvbManager *dvbManager = new DvbManager(env, thiz);
- sDvbManagers.insert(
- std::pair<jlong, DvbManager *>(deviceId, dvbManager));
- env->SetIntArrayRegion(deliverySystemTypes, 0, 8,
- dvbManager->getDeliverySystemTypes(env, thiz));
- }
- return deliverySystemTypes;
-}
+} \ No newline at end of file
diff --git a/jni/tunertvinput_jni.h b/jni/tunertvinput_jni.h
index 02c242ba..36e631f5 100755
--- a/jni/tunertvinput_jni.h
+++ b/jni/tunertvinput_jni.h
@@ -66,18 +66,8 @@ JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeFinalize
* Method: nativeTune
* Signature: (JILjava/lang/String;I)Z
*/
-JNIEXPORT jboolean JNICALL
- Java_com_android_tv_tuner_TunerHal_nativeTune__JILjava_lang_String_2I
- (JNIEnv *, jobject, jlong, jint, jstring, jint);
-
-/*
- * Class: com_android_tv_tuner_TunerHal
- * Method: nativeTune
- * Signature: Signature: (JIILjava/lang/String;I)Z
- */
-JNIEXPORT jboolean JNICALL
- Java_com_android_tv_tuner_TunerHal_nativeTune__JIILjava_lang_String_2I
- (JNIEnv *, jobject, jlong, jint, jint, jstring, jint);
+JNIEXPORT jboolean JNICALL Java_com_android_tv_tuner_TunerHal_nativeTune
+ (JNIEnv *, jobject, jlong, jint, jstring, jint);
/*
* Class: com_android_tv_tuner_TunerHal
@@ -116,15 +106,6 @@ Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType
/*
* Class: com_android_tv_tuner_TunerHal
- * Method: nativeGetDeliverySystemTypes
- * Signature: (J)I
- */
-JNIEXPORT jintArray JNICALL
-Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemTypes
- (JNIEnv *, jobject, jlong);
-
-/*
- * Class: com_android_tv_tuner_TunerHal
* Method: nativeGetSignalStrength
* Signature: (J)I
*/
diff --git a/libs/Android.bp b/libs/Android.bp
index 7c41f4ea..fea94875 100644
--- a/libs/Android.bp
+++ b/libs/Android.bp
@@ -13,15 +13,8 @@
// limitations under the License.
java_import {
- name: "tv-auto-common-jar",
- jars: ["m2/auto-common-0.10.jar"],
- host_supported: true,
- sdk_version: "current",
-}
-
-java_import {
name: "tv-auto-factory-jar",
- jars: ["m2/auto-factory-1.0-beta6.jar"],
+ jars: ["auto-factory-1.0-beta2.jar"],
host_supported: true,
sdk_version: "current",
}
@@ -29,22 +22,20 @@ java_import {
java_plugin {
name: "tv-auto-factory",
static_libs: [
- "jsr330",
- "tv-auto-common-jar",
+ "jsr330",
"tv-auto-factory-jar",
- "tv-auto-value-jar",
- "tv-google-java-format-jar",
"tv-guava-jre-jar",
- "tv-javapoet-jar",
- "tv-javax-annotations-jar",
+ "tv-javawriter-jar",
+ "tv-javax-annotations-jar",
],
processor_class: "com.google.auto.factory.processor.AutoFactoryProcessor",
generates_api: true,
}
+
java_import {
name: "tv-auto-value-jar",
- jars: ["m2/auto-value-1.5.3.jar"],
+ jars: ["auto-value-1.5.2.jar"],
host_supported: true,
sdk_version: "current",
}
@@ -60,40 +51,26 @@ java_plugin {
java_import {
name: "tv-error-prone-annotations-jar",
- jars: ["m2/error_prone_annotations-2.3.2.jar"],
- sdk_version: "current",
-}
-
-java_import {
- name: "tv-google-java-format-jar",
- jars: ["google-java-format-1.7-all-deps.jar"],
- host_supported: true,
- sdk_version: "current",
-}
-
-java_import {
- name: "tv-guava-android-jar",
- jars: ["m2/guava-28.0-android.jar"],
+ jars: ["error_prone_annotations-2.3.1.jar"],
sdk_version: "current",
}
java_import {
name: "tv-guava-jre-jar",
- jars: ["m2/guava-28.0-jre.jar"],
+ jars: ["guava-23.3-jre.jar"],
host_supported: true,
sdk_version: "current",
}
java_import {
- name: "tv-guava-failureaccess-jar",
- jars: ["m2/failureaccess-1.0.1.jar"],
- host_supported: true,
+ name: "tv-guava-android-jar",
+ jars: ["guava-23.6-android.jar"],
sdk_version: "current",
}
-java_import_host {
- name: "tv-javapoet-jar",
- jars: ["m2/javapoet-1.11.1.jar"],
+java_import_host{
+ name: "tv-javawriter-jar",
+ jars: ["javawriter-2.5.1.jar"],
}
java_import {
@@ -103,6 +80,7 @@ java_import {
sdk_version: "current",
}
+
android_library_import {
name: "tv-lib-exoplayer",
aars: ["exoplayer-r1.5.16.aar"],
@@ -111,22 +89,31 @@ android_library_import {
android_library_import {
name: "tv-lib-exoplayer-v2-core",
- aars: ["exoplayer-core-2.10.1.aar"],
+ aars: ["exoplayer-core-2.9.0.aar"],
sdk_version: "current",
}
java_import_host {
+ name: "tv-lib-dagger-compiler-deps",
+ jars: [
+ "google-java-format-1.4-all-deps.jar",
+ "guava-23.3-jre.jar",
+ "javapoet-1.8.0.jar",
+ ],
+}
+
+java_import_host {
name: "tv-lib-dagger-compiler-import",
jars: [
- "m2/dagger-compiler-2.23.jar",
- "m2/dagger-producers-2.23.jar",
- "m2/dagger-spi-2.23.jar",
+ "dagger-compiler-2.15.jar",
+ "dagger-producers-2.15.jar",
+ "dagger-spi-2.15.jar",
],
}
java_import {
name: "tv-lib-dagger",
- jars: ["m2/dagger-2.23.jar"],
+ jars: ["dagger-2.15.jar"],
host_supported: true,
sdk_version: "current",
}
@@ -135,30 +122,26 @@ java_plugin {
name: "tv-lib-dagger-compiler",
static_libs: [
"tv-lib-dagger-compiler-import",
- "tv-guava-jre-jar",
- "tv-javapoet-jar",
+ "tv-lib-dagger-compiler-deps",
"jsr330",
"tv-lib-dagger",
],
processor_class: "dagger.internal.codegen.ComponentProcessor",
generates_api: true,
- // shade guava to avoid conflicts with guava embedded in Error Prone.
- jarjar_rules: "m2/dagger-jarjar-rules.txt",
}
android_library_import {
name: "tv-lib-dagger-android",
- aars: ["m2/dagger-android-2.23.aar"],
+ aars: ["dagger-android-2.15.aar"],
sdk_version: "current",
}
java_import_host {
name: "tv-lib-dagger-android-processor-import",
jars: [
- "m2/dagger-android-jarimpl-2.23.jar",
- "m2/dagger-android-processor-2.23.jar",
- "m2/dagger-spi-2.23.jar",
- "m2/protobuf-java-3.7.0.jar",
+ "dagger-android-jarimpl-2.15.jar",
+ "dagger-android-processor-2.15.jar",
+ "dagger-android-support-jarimpl-2.15.jar",
],
}
@@ -166,22 +149,17 @@ java_plugin {
name: "tv-lib-dagger-android-processor",
static_libs: [
"tv-lib-dagger-android-processor-import",
- "tv-guava-jre-jar",
- "tv-guava-failureaccess-jar",
- "tv-javapoet-jar",
- "tv-google-java-format-jar",
+ "tv-lib-dagger-compiler-deps",
"jsr330",
"tv-lib-dagger",
],
processor_class: "dagger.android.processor.AndroidProcessor",
generates_api: true,
- // shade guava to avoid conflicts with guava embedded in Error Prone.
- jarjar_rules: "m2/dagger-jarjar-rules.txt",
}
java_import {
name: "tv-lib-truth",
- jars: ["truth-0.45.jar"],
+ jars: ["truth-0.36.jar"],
host_supported: true,
sdk_version: "current",
}
diff --git a/libs/auto-factory-1.0-beta2.jar b/libs/auto-factory-1.0-beta2.jar
new file mode 100644
index 00000000..ceaddac7
--- /dev/null
+++ b/libs/auto-factory-1.0-beta2.jar
Binary files differ
diff --git a/libs/auto-value-1.5.2.jar b/libs/auto-value-1.5.2.jar
new file mode 100644
index 00000000..8ac05679
--- /dev/null
+++ b/libs/auto-value-1.5.2.jar
Binary files differ
diff --git a/libs/dagger-2.15.jar b/libs/dagger-2.15.jar
new file mode 100644
index 00000000..6d766885
--- /dev/null
+++ b/libs/dagger-2.15.jar
Binary files differ
diff --git a/libs/dagger-android-2.15.aar b/libs/dagger-android-2.15.aar
new file mode 100644
index 00000000..430294a2
--- /dev/null
+++ b/libs/dagger-android-2.15.aar
Binary files differ
diff --git a/libs/dagger-android-jarimpl-2.15.jar b/libs/dagger-android-jarimpl-2.15.jar
new file mode 100644
index 00000000..7f7cd459
--- /dev/null
+++ b/libs/dagger-android-jarimpl-2.15.jar
Binary files differ
diff --git a/libs/dagger-android-processor-2.15.jar b/libs/dagger-android-processor-2.15.jar
new file mode 100644
index 00000000..3c7ac054
--- /dev/null
+++ b/libs/dagger-android-processor-2.15.jar
Binary files differ
diff --git a/libs/dagger-android-support-2.15.aar b/libs/dagger-android-support-2.15.aar
new file mode 100644
index 00000000..89a71a91
--- /dev/null
+++ b/libs/dagger-android-support-2.15.aar
Binary files differ
diff --git a/libs/dagger-android-support-jarimpl-2.15.jar b/libs/dagger-android-support-jarimpl-2.15.jar
new file mode 100644
index 00000000..d0ea01a7
--- /dev/null
+++ b/libs/dagger-android-support-jarimpl-2.15.jar
Binary files differ
diff --git a/libs/dagger-compiler-2.15.jar b/libs/dagger-compiler-2.15.jar
new file mode 100644
index 00000000..e73110f6
--- /dev/null
+++ b/libs/dagger-compiler-2.15.jar
Binary files differ
diff --git a/libs/dagger-producers-2.15.jar b/libs/dagger-producers-2.15.jar
new file mode 100644
index 00000000..f1dbb07a
--- /dev/null
+++ b/libs/dagger-producers-2.15.jar
Binary files differ
diff --git a/libs/dagger-spi-2.15.jar b/libs/dagger-spi-2.15.jar
new file mode 100644
index 00000000..6e3156a9
--- /dev/null
+++ b/libs/dagger-spi-2.15.jar
Binary files differ
diff --git a/libs/error_prone_annotations-2.3.1.jar b/libs/error_prone_annotations-2.3.1.jar
new file mode 100644
index 00000000..8a0efa37
--- /dev/null
+++ b/libs/error_prone_annotations-2.3.1.jar
Binary files differ
diff --git a/libs/exoplayer-core-2.10.1.aar b/libs/exoplayer-core-2.10.1.aar
deleted file mode 100644
index 2342feda..00000000
--- a/libs/exoplayer-core-2.10.1.aar
+++ /dev/null
Binary files differ
diff --git a/libs/exoplayer-core-2.9.0.aar b/libs/exoplayer-core-2.9.0.aar
new file mode 100644
index 00000000..64c4f37f
--- /dev/null
+++ b/libs/exoplayer-core-2.9.0.aar
Binary files differ
diff --git a/libs/google-java-format-1.7-all-deps.jar b/libs/google-java-format-1.4-all-deps.jar
index e2d40de4..b10bfbd6 100644
--- a/libs/google-java-format-1.7-all-deps.jar
+++ b/libs/google-java-format-1.4-all-deps.jar
Binary files differ
diff --git a/libs/guava-23.3-jre.jar b/libs/guava-23.3-jre.jar
new file mode 100644
index 00000000..b13e275f
--- /dev/null
+++ b/libs/guava-23.3-jre.jar
Binary files differ
diff --git a/libs/guava-23.5-jre.jar b/libs/guava-23.5-jre.jar
new file mode 100644
index 00000000..7e5f13a8
--- /dev/null
+++ b/libs/guava-23.5-jre.jar
Binary files differ
diff --git a/libs/guava-23.6-android.jar b/libs/guava-23.6-android.jar
new file mode 100644
index 00000000..01180d23
--- /dev/null
+++ b/libs/guava-23.6-android.jar
Binary files differ
diff --git a/libs/javapoet-1.8.0.jar b/libs/javapoet-1.8.0.jar
new file mode 100644
index 00000000..6758b6d7
--- /dev/null
+++ b/libs/javapoet-1.8.0.jar
Binary files differ
diff --git a/libs/javawriter-2.5.1.jar b/libs/javawriter-2.5.1.jar
new file mode 100644
index 00000000..4ec579e7
--- /dev/null
+++ b/libs/javawriter-2.5.1.jar
Binary files differ
diff --git a/libs/m2/animal-sniffer-annotations-1.17.jar b/libs/m2/animal-sniffer-annotations-1.17.jar
deleted file mode 100644
index 6ec7a603..00000000
--- a/libs/m2/animal-sniffer-annotations-1.17.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/auto-common-0.10.jar b/libs/m2/auto-common-0.10.jar
deleted file mode 100644
index 8cbfa729..00000000
--- a/libs/m2/auto-common-0.10.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/auto-factory-1.0-beta6.jar b/libs/m2/auto-factory-1.0-beta6.jar
deleted file mode 100644
index e47130f2..00000000
--- a/libs/m2/auto-factory-1.0-beta6.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/auto-value-1.5.3.jar b/libs/m2/auto-value-1.5.3.jar
deleted file mode 100644
index 99eeb0b3..00000000
--- a/libs/m2/auto-value-1.5.3.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/checker-qual-2.8.1.jar b/libs/m2/checker-qual-2.8.1.jar
deleted file mode 100644
index 09269be6..00000000
--- a/libs/m2/checker-qual-2.8.1.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-2.23.jar b/libs/m2/dagger-2.23.jar
deleted file mode 100644
index 544ee3d6..00000000
--- a/libs/m2/dagger-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-android-2.23.aar b/libs/m2/dagger-android-2.23.aar
deleted file mode 100644
index 9578dcde..00000000
--- a/libs/m2/dagger-android-2.23.aar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-android-jarimpl-2.23.jar b/libs/m2/dagger-android-jarimpl-2.23.jar
deleted file mode 100644
index 94a2bbef..00000000
--- a/libs/m2/dagger-android-jarimpl-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-android-processor-2.23.jar b/libs/m2/dagger-android-processor-2.23.jar
deleted file mode 100644
index 500149c6..00000000
--- a/libs/m2/dagger-android-processor-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-compiler-2.23.jar b/libs/m2/dagger-compiler-2.23.jar
deleted file mode 100644
index b7cb1624..00000000
--- a/libs/m2/dagger-compiler-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-jarjar-rules.txt b/libs/m2/dagger-jarjar-rules.txt
deleted file mode 100644
index 618c2434..00000000
--- a/libs/m2/dagger-jarjar-rules.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# shade guava to avoid conflicts with guava embedded in Error Prone.
-rule com.google.common.** com.google.dagger.common.@1
-rule com.google.auto.** com.google.dagger.auto.@1
-
diff --git a/libs/m2/dagger-producers-2.23.jar b/libs/m2/dagger-producers-2.23.jar
deleted file mode 100644
index cb1cef95..00000000
--- a/libs/m2/dagger-producers-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/dagger-spi-2.23.jar b/libs/m2/dagger-spi-2.23.jar
deleted file mode 100644
index 6af1494d..00000000
--- a/libs/m2/dagger-spi-2.23.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/error_prone_annotations-2.3.2.jar b/libs/m2/error_prone_annotations-2.3.2.jar
deleted file mode 100644
index bc2584db..00000000
--- a/libs/m2/error_prone_annotations-2.3.2.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/failureaccess-1.0.1.jar b/libs/m2/failureaccess-1.0.1.jar
deleted file mode 100644
index 9b56dc75..00000000
--- a/libs/m2/failureaccess-1.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/guava-28.0-android.jar b/libs/m2/guava-28.0-android.jar
deleted file mode 100644
index 516fc5fa..00000000
--- a/libs/m2/guava-28.0-android.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/guava-28.0-jre.jar b/libs/m2/guava-28.0-jre.jar
deleted file mode 100644
index f254aae7..00000000
--- a/libs/m2/guava-28.0-jre.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/j2objc-annotations-1.3.jar b/libs/m2/j2objc-annotations-1.3.jar
deleted file mode 100644
index a429c721..00000000
--- a/libs/m2/j2objc-annotations-1.3.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/javac-shaded-9-dev-r4023-3.jar b/libs/m2/javac-shaded-9-dev-r4023-3.jar
deleted file mode 100644
index d7b3fd8c..00000000
--- a/libs/m2/javac-shaded-9-dev-r4023-3.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/javapoet-1.11.1.jar b/libs/m2/javapoet-1.11.1.jar
deleted file mode 100644
index 27a18e8b..00000000
--- a/libs/m2/javapoet-1.11.1.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/jsr305-3.0.2.jar b/libs/m2/jsr305-3.0.2.jar
deleted file mode 100644
index 59222d9c..00000000
--- a/libs/m2/jsr305-3.0.2.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar b/libs/m2/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
deleted file mode 100644
index 45832c05..00000000
--- a/libs/m2/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/pom-jre.xml b/libs/m2/pom-jre.xml
deleted file mode 100644
index 2d834c33..00000000
--- a/libs/m2/pom-jre.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<!-- JRE version of libs, in particular guava -->
-<project>
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.android.tv</groupId>
- <artifactId>jre-libs</artifactId>
- <version>1</version>
-
- <repositories>
- <repository>
- <id>google</id>
- <name>Google Maven Repository</name>
- <url>https://maven.google.com</url>
- <layout>default</layout>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
- <dependencies>
-
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>28.0-jre</version>
- </dependency>
-
- </dependencies>
-</project> \ No newline at end of file
diff --git a/libs/m2/pom.xml b/libs/m2/pom.xml
deleted file mode 100644
index 5a232d56..00000000
--- a/libs/m2/pom.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<project>
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.android.tv</groupId>
- <artifactId>libs</artifactId>
- <version>1</version>
-
- <repositories>
- <repository>
- <id>google</id>
- <name>Google Maven Repository</name>
- <url>https://maven.google.com</url>
- <layout>default</layout>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
- <dependencies>
- <dependency>
- <groupId>com.google.auto</groupId>
- <artifactId>auto-common</artifactId>
- <version>0.10</version>
- </dependency>
- <dependency>
- <groupId>com.google.auto.factory</groupId>
- <artifactId>auto-factory</artifactId>
- <version>1.0-beta6</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger</artifactId>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-android</artifactId>
- <type>aar</type>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-android-jarimpl</artifactId>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-android-processor</artifactId>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-compiler</artifactId>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-producers</artifactId>
- <version>2.23</version>
- </dependency>
- <dependency>
- <groupId>com.google.dagger</groupId>
- <artifactId>dagger-spi</artifactId>
- <version>2.23</version>
- </dependency>
-
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>28.0-android</version>
- </dependency>
-
- <!-- The host version of guava is listed in pom-jre.xml -->
-
- <dependency>
- <groupId>com.squareup</groupId>
- <artifactId>javapoet</artifactId>
- <version>1.11.1</version>
- </dependency>
- </dependencies>
-</project> \ No newline at end of file
diff --git a/libs/m2/protobuf-java-3.7.0.jar b/libs/m2/protobuf-java-3.7.0.jar
deleted file mode 100644
index eebaefeb..00000000
--- a/libs/m2/protobuf-java-3.7.0.jar
+++ /dev/null
Binary files differ
diff --git a/libs/m2/update.sh b/libs/m2/update.sh
deleted file mode 100755
index ee455c7b..00000000
--- a/libs/m2/update.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-git rm *.jar *.aar
-
-EXCLUDES=google-java-format,javax.inject,support-annotations,jsr250-api,checker-compat-qual
-
-mvn \
- -DoutputDirectory=${pwd} \
- dependency:copy-dependencies \
- -DincludeScope=runtime \
- -DexcludeArtifactIds=${EXCLUDES}
-
-mvn \
- -DoutputDirectory=${pwd} \
- -f pom-jre.xml \
- dependency:copy-dependencies \
- -DincludeScope=runtime \
- -DexcludeArtifactIds=${EXCLUDES}
-
-git add *.jar *.aar
-
-
diff --git a/libs/truth-0.36.jar b/libs/truth-0.36.jar
new file mode 100644
index 00000000..8174e4a9
--- /dev/null
+++ b/libs/truth-0.36.jar
Binary files differ
diff --git a/libs/truth-0.45.jar b/libs/truth-0.45.jar
deleted file mode 100644
index 76e4da8a..00000000
--- a/libs/truth-0.45.jar
+++ /dev/null
Binary files differ
diff --git a/partner_support/AndroidManifest.xml b/partner_support/AndroidManifest.xml
index 8f807084..45a693fc 100644
--- a/partner_support/AndroidManifest.xml
+++ b/partner_support/AndroidManifest.xml
@@ -17,6 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.tv.partner.support"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application />
</manifest>
diff --git a/partner_support/g3doc/CloudEpgForPartners.md b/partner_support/g3doc/CloudEpgForPartners.md
new file mode 100644
index 00000000..bec6b504
--- /dev/null
+++ b/partner_support/g3doc/CloudEpgForPartners.md
@@ -0,0 +1,112 @@
+# 3rd party instructions for using Cloud EPG feature of Live Channels
+
+Partners can ask Live Channels to retrieve EPG data for their TV Input Service
+using live channels
+
+## Prerequisites
+
+* Updated agreement with Google
+* Oreo or patched Nougat
+
+## Nougat
+
+To use cloud epg with Nougat you will need the following changes.
+
+### Patch TVProvider
+
+To run in Nougat you must cherry pick [change
+455319](https://android-review.googlesource.com/c/platform/packages/providers/TvProvider/+/455319)
+to TV Provider.
+
+### Customisation
+
+Indicate TvProvider is patched by including the following in their TV
+customization resource
+
+```
+<bool name="tvprovider_allows_system_inserts_to_program_table">true</bool>
+```
+
+See https://source.android.com/devices/tv/customize-tv-app
+
+## **Input Setup**
+
+During the input setup activity, the TIS will query the content provider for
+lineups in a given postal code. The TIS then inserts a row to the inputs table
+with input_id and lineup_id
+
+On completion of the activity the TIS sets the extra data in the result to
+
+* `com.android.tv.extra.USE_CLOUD_EPG = true`
+* `TvInputInfo.EXTRA_INPUT_ID` with their input_id
+
+This is used to tell Live Channels to immediately start the EPG fetch for that
+input.
+
+### Sample Input Setup code.
+
+A complete sample is at
+../third_party/samples/src/com/example/partnersupportsampletvinput
+
+#### query lineup
+
+```java
+ private AsyncTask<Void, Void, List<Lineup>> createFetchLineupsTask() {
+ return new AsyncTask<Void, Void, List<Lineup>>() {
+ @Override
+ protected List<Lineup> doInBackground(Void... params) {
+ ContentResolver cr = getActivity().getContentResolver();
+
+ List<Lineup> results = new ArrayList<>();
+ Cursor cursor =
+ cr.query(
+ Uri.parse(
+ "content://com.android.tv.data.epg/lineups/postal_code/"
+ + ZIP),
+ null,
+ null,
+ null,
+ null);
+
+ while (cursor.moveToNext()) {
+ String id = cursor.getString(0);
+ String name = cursor.getString(1);
+ String channels = cursor.getString(2);
+ results.add(new Lineup(id, name, channels));
+ }
+
+ return results;
+ }
+
+ @Override
+ protected void onPostExecute(List<Lineup> lineups) {
+ showLineups(lineups);
+ }
+ };
+ }
+```
+
+#### Insert cloud_epg_input
+
+```java
+ContentValues values = new ContentValues();
+values.put(EpgContract.EpgInputs.COLUMN_INPUT_ID, SampleTvInputService.INPUT_ID);
+values.put(EpgContract.EpgInputs.COLUMN_LINEUP_ID, lineup.getId());
+ContentResolver contentResolver = getActivity().getContentResolver();
+EpgInput epgInput = EpgInputs.queryEpgInput(contentResolver, SampleTvInputService.INPUT_ID);
+if (epgInput == null) {
+ contentResolver.insert(EpgContract.EpgInputs.CONTENT_URI, values);
+} else {
+ values.put(EpgContract.EpgInputs.COLUMN_ID, epgInput.getId());
+ EpgInputs.update(contentResolver, EpgInput.createEpgChannel(values));
+}
+```
+
+#### Return use_cloud_epg
+
+```java
+Intent data = new Intent();
+data.putExtra(TvInputInfo.EXTRA_INPUT_ID, inputId);
+data.putExtra(com.android.tv.extra.USE_CLOUD_EPG, true);
+setResult(Activity.RESULT_OK, data);
+```
diff --git a/partner_support/g3doc/SeriesIdColumnForPartners.md b/partner_support/g3doc/SeriesIdColumnForPartners.md
new file mode 100644
index 00000000..cd44db03
--- /dev/null
+++ b/partner_support/g3doc/SeriesIdColumnForPartners.md
@@ -0,0 +1,30 @@
+# 3rd party instructions for using series recording feature of Live Channels
+
+## Prerequisites
+
+* Updated agreement with Google
+* Oreo or patched Nougat
+
+## Nougat
+
+To enable series recording with Nougat you will need the following changes.
+
+### Patch TVProvider
+
+To run in Nougat you must backport the following changes
+
+* [Filter out non-existing customized columns in
+ DB](https://partner-android.googlesource.com/platform/packages/providers/TvProvider/+/142162af889b2c124bb012eea608c6a65eed54bb)
+* [Add TvProvider methods to get and add
+ columns](https://partner-android.googlesource.com/platform/packages/providers/TvProvider/+/cda6788ae903513a555fd3e07a5a1c14218c40a2)
+
+### Customisation
+
+Indicate TvProvider is patched by including the following in their TV
+customization resource
+
+```
+<bool name="tvprovider_allows_column_creation">true</bool>
+```
+
+See https://source.android.com/devices/tv/customize-tv-app
diff --git a/partner_support/g3doc/TurnOffEmbeddedTuner.md b/partner_support/g3doc/TurnOffEmbeddedTuner.md
new file mode 100644
index 00000000..0ba7cff2
--- /dev/null
+++ b/partner_support/g3doc/TurnOffEmbeddedTuner.md
@@ -0,0 +1,15 @@
+# 3rd party instructions turning off the embedded tuner in Live Channels
+
+Partners that have a built in tuner should provide a TV Input like
+SampleDvbTuner. When partners provide their own tuner they MUST turn of the
+embedded tuner in Live Channels.
+
+### Customisation
+
+Indicate Live Channels should not use it's embedded tuner implementation.
+
+```
+<bool name="turn_off_embedded_tuner">true</bool>
+```
+
+See https://source.android.com/devices/tv/customize-tv-app
diff --git a/partner_support/sample_customization/AndroidManifest.xml b/partner_support/sample_customization/AndroidManifest.xml
index 5e4c2c7c..804691a6 100644
--- a/partner_support/sample_customization/AndroidManifest.xml
+++ b/partner_support/sample_customization/AndroidManifest.xml
@@ -24,7 +24,7 @@
<uses-feature android:name="android.software.leanback" android:required="true" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application android:label="Partner Customization"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
diff --git a/partner_support/samples/Android.bp b/partner_support/samples/Android.bp
deleted file mode 100644
index 9c1d2db8..00000000
--- a/partner_support/samples/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-android_app {
- name: "PartnerSupportSampleTvInput",
-
- // Include all java files.
- srcs: ["src/**/*.java"],
-
- static_libs: [
- "androidx.leanback_leanback",
- "androidx.tvprovider_tvprovider",
- "live-channels-partner-support",
- ],
-
- optimize: {
- enabled: false,
- },
- // Overlay view related functionality requires system APIs.
- sdk_version: "system_current",
- min_sdk_version: "23", // M
-
- // Required for com.android.tv.permission.RECEIVE_INPUT_EVENT
- privileged: true,
-
- resource_dirs: ["res"],
-
-}
diff --git a/partner_support/samples/Android.mk b/partner_support/samples/Android.mk
new file mode 100644
index 00000000..2e771a5b
--- /dev/null
+++ b/partner_support/samples/Android.mk
@@ -0,0 +1,33 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Include all java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PartnerSupportSampleTvInput
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-annotations \
+ live-channels-partner-support
+
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ android-support-compat \
+ android-support-core-ui \
+ android-support-v7-recyclerview \
+ android-support-v17-leanback \
+ androidx.tvprovider_tvprovider
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_PROGUARD_ENABLED := disabled
+# Overlay view related functionality requires system APIs.
+LOCAL_SDK_VERSION := system_current
+LOCAL_MIN_SDK_VERSION := 23 # M
+
+# Required for com.android.tv.permission.RECEIVE_INPUT_EVENT
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+include $(BUILD_PACKAGE)
diff --git a/partner_support/samples/AndroidManifest.xml b/partner_support/samples/AndroidManifest.xml
index 65b2a3ba..d91c603a 100644
--- a/partner_support/samples/AndroidManifest.xml
+++ b/partner_support/samples/AndroidManifest.xml
@@ -29,7 +29,7 @@
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="com.android.tv.permission.RECEIVE_INPUT_EVENT" />
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<!--TODO(b/68949299): remove tool hint when we have smaller dependency targets-->
<application android:label="@string/partner_support_sample_tv_input"
tools:replace="android:label,icon,theme,appComponentFactory"
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/ChannelScanFragment.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/ChannelScanFragment.java
index d449bb5f..ec7589cb 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/ChannelScanFragment.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/ChannelScanFragment.java
@@ -23,10 +23,10 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+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;
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/LineupSelectionFragment.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/LineupSelectionFragment.java
index 7486a981..8c3ca77a 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/LineupSelectionFragment.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/LineupSelectionFragment.java
@@ -24,24 +24,21 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.google.android.tv.partner.support.EpgContract;
import com.google.android.tv.partner.support.EpgInput;
import com.google.android.tv.partner.support.EpgInputs;
import com.google.android.tv.partner.support.Lineup;
import com.google.android.tv.partner.support.Lineups;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -179,7 +176,7 @@ public class LineupSelectionFragment extends GuidedStepFragment {
List<Lineup> lineups, List<String> localChannels) {
List<Pair<Lineup, Integer>> result = new ArrayList<>();
for (Lineup lineup : lineups) {
- result.add(Pair.create(lineup, getMatchCount(lineup.getChannels(), localChannels)));
+ result.add(new Pair<>(lineup, getMatchCount(lineup.getChannels(), localChannels)));
}
// sort in decreasing order
Collections.sort(
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/LocationFragment.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/LocationFragment.java
index 532ff9bd..9492e7e5 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/LocationFragment.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/LocationFragment.java
@@ -19,10 +19,10 @@ package com.example.partnersupportsampletvinput;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import java.util.List;
/** Location Fragment for users to enter postal code */
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/ResultFragment.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/ResultFragment.java
index 0c893182..a1c17acd 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/ResultFragment.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/ResultFragment.java
@@ -21,10 +21,10 @@ import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.google.android.tv.partner.support.EpgContract;
import java.util.List;
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/SampleTvInputSetupActivity.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/SampleTvInputSetupActivity.java
index e11ebdfc..a0a75881 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/SampleTvInputSetupActivity.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/SampleTvInputSetupActivity.java
@@ -18,7 +18,7 @@ package com.example.partnersupportsampletvinput;
import android.app.Activity;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
/** The setup activity for partner support sample TV input. */
public class SampleTvInputSetupActivity extends Activity {
diff --git a/partner_support/samples/src/com/example/partnersupportsampletvinput/WelcomeFragment.java b/partner_support/samples/src/com/example/partnersupportsampletvinput/WelcomeFragment.java
index 96632d36..286f34f2 100644
--- a/partner_support/samples/src/com/example/partnersupportsampletvinput/WelcomeFragment.java
+++ b/partner_support/samples/src/com/example/partnersupportsampletvinput/WelcomeFragment.java
@@ -19,10 +19,10 @@ package com.example.partnersupportsampletvinput;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import java.util.List;
/** Welcome Fragment shows welcome information for users */
diff --git a/partner_support/src/com/google/android/tv/partner/support/EpgInput.java b/partner_support/src/com/google/android/tv/partner/support/EpgInput.java
index c591c9fe..20b3542a 100644
--- a/partner_support/src/com/google/android/tv/partner/support/EpgInput.java
+++ b/partner_support/src/com/google/android/tv/partner/support/EpgInput.java
@@ -20,7 +20,7 @@ import android.content.ContentValues;
import com.google.auto.value.AutoValue;
/**
- * Value class representing a TV Input that uses TV app EPG.
+ * Value class representing a TV Input that uses Live TV EPG.
*
* @see {@link EpgContract.EpgInputs}
*/
diff --git a/partner_support/src/com/google/android/tv/partner/support/TunerSetupUtils.java b/partner_support/src/com/google/android/tv/partner/support/TunerSetupUtils.java
index d50db7d8..e25d5836 100644
--- a/partner_support/src/com/google/android/tv/partner/support/TunerSetupUtils.java
+++ b/partner_support/src/com/google/android/tv/partner/support/TunerSetupUtils.java
@@ -20,7 +20,6 @@ import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -40,7 +39,7 @@ public class TunerSetupUtils {
List<List<String>> parsedLocalChannels = parseChannelNumbers(localChannels);
for (Lineup lineup : lineups) {
result.add(
- Pair.create(lineup, getMatchCount(lineup.getChannels(), parsedLocalChannels)));
+ new Pair<>(lineup, getMatchCount(lineup.getChannels(), parsedLocalChannels)));
}
// sort in decreasing order
Collections.sort(
diff --git a/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/BaseCustomizationTest.java b/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/BaseCustomizationTest.java
index 03d68e4e..e2170589 100644
--- a/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/BaseCustomizationTest.java
+++ b/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/BaseCustomizationTest.java
@@ -17,17 +17,16 @@
package com.google.android.tv.partner.support;
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-
import com.android.tv.testing.TestSingletonApp;
import com.android.tv.testing.constants.ConfigConstants;
-
+import java.util.ArrayList;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,9 +34,6 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import java.util.ArrayList;
-import java.util.List;
-
/** Tests for {@link BaseCustomization}. */
// TODO: move to partner-support
diff --git a/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/TunerSetupUtilsTest.java b/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/TunerSetupUtilsTest.java
index 8d089e55..d9b48cfd 100644
--- a/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/TunerSetupUtilsTest.java
+++ b/partner_support/tests/robotests/javatests/com/google/android/tv/partner/support/TunerSetupUtilsTest.java
@@ -19,18 +19,16 @@ package com.google.android.tv.partner.support;
import static com.google.common.truth.Truth.assertThat;
import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
+import com.google.thirdparty.robolectric.GoogleRobolectricTestRunner;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
/** Tests for {@link TunerSetupUtils} */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(GoogleRobolectricTestRunner.class)
@Config(sdk = ConfigConstants.SDK)
public class TunerSetupUtilsTest {
diff --git a/res/layout/details_overview.xml b/res/layout/details_overview.xml
index 541f3fb1..dbcf2055 100644
--- a/res/layout/details_overview.xml
+++ b/res/layout/details_overview.xml
@@ -55,7 +55,7 @@
android:orientation="vertical" >
<!-- layout_marginStart and layout_marginEnd are overridden -->
- <androidx.leanback.widget.NonOverlappingFrameLayout
+ <android.support.v17.leanback.widget.NonOverlappingFrameLayout
android:id="@+id/details_overview_description"
android:layout_width="match_parent"
android:layout_height="0dp"
@@ -69,7 +69,7 @@
<!-- horizontalSpacing is defined as @dimen/lb_details_overview_action_items_spacing
in newer versions of Leanback Library than LC uses. -->
- <androidx.leanback.widget.HorizontalGridView
+ <android.support.v17.leanback.widget.HorizontalGridView
android:id="@+id/details_overview_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/dvr_details_description.xml b/res/layout/dvr_details_description.xml
index e37d8b0a..ee749526 100644
--- a/res/layout/dvr_details_description.xml
+++ b/res/layout/dvr_details_description.xml
@@ -21,7 +21,7 @@
android:layout_height="wrap_content">
<!-- Top margins are set programatically -->
- <androidx.leanback.widget.ResizingTextView
+ <android.support.v17.leanback.widget.ResizingTextView
android:id="@+id/dvr_details_description_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/item_list.xml b/res/layout/item_list.xml
index 233aa416..c06b29a0 100644
--- a/res/layout/item_list.xml
+++ b/res/layout/item_list.xml
@@ -33,7 +33,7 @@
and compensate the same space with padding.
The accurate layout height is set in MenuRowView.onBind(). -->
- <androidx.leanback.widget.HorizontalGridView
+ <android.support.v17.leanback.widget.HorizontalGridView
android:id="@+id/list_view"
style="@style/menu_row_contents_view"
android:clipChildren="false"
diff --git a/res/layout/option_fragment.xml b/res/layout/option_fragment.xml
index 50bf991d..4a4cbbdf 100644
--- a/res/layout/option_fragment.xml
+++ b/res/layout/option_fragment.xml
@@ -34,7 +34,7 @@
android:textColor="@color/option_item_text_color"
android:singleLine="true" />
- <androidx.leanback.widget.VerticalGridView
+ <android.support.v17.leanback.widget.VerticalGridView
android:id="@+id/side_panel_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/res/layout/pin_dialog.xml b/res/layout/pin_dialog.xml
index 84807f27..d40d70ec 100644
--- a/res/layout/pin_dialog.xml
+++ b/res/layout/pin_dialog.xml
@@ -55,8 +55,8 @@
android:fontFamily="@string/font"
android:singleLine="false" />
- <com.android.tv.dialog.picker.TvPinPicker
- android:id="@+id/tv_pin_picker"
+ <com.android.tv.dialog.picker.PinPicker
+ android:id="@+id/pin_picker"
android:importantForAccessibility="yes"
android:layout_width="match_parent"
android:layout_height="154dp"
diff --git a/res/layout/priority_settings_action_item.xml b/res/layout/priority_settings_action_item.xml
index fc882d97..0f517319 100644
--- a/res/layout/priority_settings_action_item.xml
+++ b/res/layout/priority_settings_action_item.xml
@@ -15,13 +15,13 @@
limitations under the License.
-->
-<androidx.leanback.widget.GuidedActionItemContainer
+<android.support.v17.leanback.widget.GuidedActionItemContainer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="?attr/guidedActionItemContainerStyle"
android:foreground="@null"
android:outlineProvider="background">
- <androidx.leanback.widget.CheckableImageView
+ <android.support.v17.leanback.widget.CheckableImageView
android:id="@+id/guidedactions_item_checkmark"
style="?attr/guidedActionItemCheckmarkStyle"
tools:ignore="ContentDescription" />
@@ -30,16 +30,16 @@
style="?attr/guidedActionItemIconStyle"
tools:ignore="ContentDescription" />
- <androidx.leanback.widget.NonOverlappingLinearLayout
+ <android.support.v17.leanback.widget.NonOverlappingLinearLayout
android:id="@+id/guidedactions_item_content"
style="?attr/guidedActionItemContentStyle" >
- <androidx.leanback.widget.GuidedActionEditText
+ <android.support.v17.leanback.widget.GuidedActionEditText
android:id="@+id/guidedactions_item_title"
style="?attr/guidedActionItemTitleStyle" />
- <androidx.leanback.widget.GuidedActionEditText
+ <android.support.v17.leanback.widget.GuidedActionEditText
android:id="@+id/guidedactions_item_description"
style="?attr/guidedActionItemDescriptionStyle" />
- </androidx.leanback.widget.NonOverlappingLinearLayout>
+ </android.support.v17.leanback.widget.NonOverlappingLinearLayout>
<ImageView
android:id="@+id/guidedactions_item_chevron"
@@ -53,4 +53,4 @@
android:adjustViewBounds="true"
android:src="@drawable/ic_draggable_white"
tools:ignore="ContentDescription" />
-</androidx.leanback.widget.GuidedActionItemContainer> \ No newline at end of file
+</android.support.v17.leanback.widget.GuidedActionItemContainer> \ No newline at end of file
diff --git a/res/layout/program_guide_side_panel.xml b/res/layout/program_guide_side_panel.xml
index 9c04feb2..466b7fa8 100644
--- a/res/layout/program_guide_side_panel.xml
+++ b/res/layout/program_guide_side_panel.xml
@@ -32,7 +32,7 @@
android:elevation="@dimen/program_guide_side_panel_elevation"
android:background="@color/program_guide_side_panel_background">
- <androidx.leanback.widget.SearchOrbView
+ <android.support.v17.leanback.widget.SearchOrbView
android:id="@+id/program_guide_side_panel_search_orb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -41,7 +41,7 @@
android:nextFocusDown="@+id/program_guide_side_panel_grid_view"
android:visibility="gone" />
- <androidx.leanback.widget.VerticalGridView
+ <android.support.v17.leanback.widget.VerticalGridView
android:id="@id/program_guide_side_panel_grid_view"
android:layout_width="@dimen/program_guide_side_panel_item_width"
android:layout_height="match_parent"
diff --git a/res/values/arrays-custom.xml b/res/values/arrays-custom.xml
deleted file mode 100644
index 252d6f4f..00000000
--- a/res/values/arrays-custom.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<!-- These are resources that are expected to be different for OEM apps -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
- <!-- Keep the title and description arrays in sync -->
-
- <!-- Titles in the onboarding page. [CHAR LIMIT=100]-->
- <string-array name="welcome_page_titles">
- <item><xliff:g id="app_name">Live TV</xliff:g> </item>
- <item>A simple way to discover content</item>
- <item>Download apps, get more channels</item>
- <item>Customize your channel line-up</item>
- </string-array>
-
-
- <!-- Descriptions in the onboarding page. [CHAR LIMIT=NONE] -->
- <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/arrays.xml b/res/values/arrays.xml
index 9ef028ae..0604dd2b 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -150,4 +150,24 @@
<item>Tech/Science</item>
</string-array>
+ <!-- Titles in the onboarding page. -->
+ <string-array name="welcome_page_titles">
+ <item><xliff:g id="app_name">Live TV</xliff:g> </item>
+ <item>A simple way to discover content</item>
+ <item>Download apps, get more channels</item>
+ <item>Customize your channel line-up</item>
+ </string-array>
+
+ <!-- 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 the online 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/rating_system_strings.xml b/res/values/rating_system_strings.xml
index 9922cb1c..45c48d87 100644
--- a/res/values/rating_system_strings.xml
+++ b/res/values/rating_system_strings.xml
@@ -16,10 +16,9 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Age based TV content rating strings used in DVB, ISDB and DTMB.
- For more info, please see STD-B10 in http://www.dibeg.org/techp/aribstd/aribstd.html (ISDB),
- Table 81 of DVB SI (EN 300 468 V1.14.1) in https://www.dvb.org/standards (DVB)
- and http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=59E83CA701AEB4248E115BC043688FEC (DTMB).-->
+ <!-- Age based TV content rating strings used in DVB and ISDB.
+ For more info, please see STD-B10 in http://www.dibeg.org/techp/aribstd/aribstd.html (ISDB)
+ and Table 81 of DVB SI (EN 300 468 V1.14.1) in https://www.dvb.org/standards (DVB).-->
<string name="description_age_4">Recommended for ages 4 and over.</string>
<string name="description_age_5">Recommended for ages 5 and over.</string>
<string name="description_age_6">Recommended for ages 6 and over.</string>
@@ -110,7 +109,6 @@
<!-- A TV content rating of DVB for adult [CHAR LIMIT=NONE] -->
<string name="description_es_dvb_x">Recommended for adults.</string>
-
<!-- TV content rating system strings for KR TV. These strings are from
http://www.law.go.kr/admRulLsInfoP.do?admRulSeq=2000000118507 but they are translated
from Korean to English. -->
@@ -161,19 +159,4 @@
<string name="description_us_mv_pg13">Parents strongly cautioned. Some material may be inappropriate for pre-teenagers.</string>
<string name="description_us_mv_r">Restricted, Contains some adult material. Parents are urged to learn more about the film before taking their young children with them.</string>
<string name="description_us_mv_nc17">No one 17 and under admitted. Clearly adult. Children are not admitted.</string>
-
- <!-- TV content rating system strings for NZ TV. These strings are from
- https://bsa.govt.nz/images/03_BSA_FREE-TO-AIR-TV_CLASSIFICATIONS_DRAFT.pdf -->
- <string name="description_nz_fta_tv_g" translatable="false">Programmes which exclude material likely to be unsuitable for children. Programmes may not necessarily be designed for child viewers but should not contain material likely to alarm or distress them.</string>
- <string name="description_nz_fta_tv_pgr" translatable="false">Programmes containing material more suited for mature audiences but not necessarily unsuitable for child viewers when subject to the guidance of a parent or an adult.</string>
- <string name="description_nz_fta_tv_ao" translatable="false">Programmes containing adult themes and directed primarily at mature audiences.</string>
-
- <!-- TV content rating system strings for TH TV. These strings are from
- https://broadcast.nbtc.go.th/home/ -->
- <string name="description_th_tv_4" translatable="false">Suitable for audiences 3 to 5 years of age.</string>
- <string name="description_th_tv_6" translatable="false">Suitable for audiences 6 to 12 years of age.</string>
- <string name="description_th_tv_10" translatable="false">Suitable for all audiences.</string>
- <string name="description_th_tv_13" translatable="false">Parental guidance suggested for viewers age below 13.</string>
- <string name="description_th_tv_18" translatable="false">Parental guidance suggested for viewers age below 18.</string>
- <string name="description_th_tv_19" translatable="false">Not suitable for children and teenagers.</string>
</resources>
diff --git a/res/values/strings-custom.xml b/res/values/strings-custom.xml
index 5ecb8592..22f73318 100644
--- a/res/values/strings-custom.xml
+++ b/res/values/strings-custom.xml
@@ -14,18 +14,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-
-
-<!-- These are resources that are expected to be different for OEM apps -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources>
<!-- Name of application [CHAR LIMIT=NONE] -->
<string name="app_name" translatable="false">Live TV</string>
- <!-- Description for channel sources screen in onboarding. [CHAR LIMIT=NONE] -->
- <string name="setup_sources_description2"
- meaning="Live TV version of setup_sources_description2"
- ><xliff:g id="app_name">Live TV</xliff:g> 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>
+</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 06694a9d..36824759 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -28,16 +28,16 @@
<!-- 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 <xliff:g id="app_name">Live TV</xliff:g> app</string>
+ <string name="permlab_receiveInputEvent" translatable="false">receive input events from <xliff:g id="app_name">Live TV</xliff:g> app</string>
<!-- Description of an application permission, listed so the user can choose
whether they want to allow the application to do this. -->
- <string name="permdesc_receiveInputEvent" translatable="false">Allows the app to receive input events from <xliff:g id="app_name">Live TV</xliff:g> app</string>
+ <string name="permdesc_receiveInputEvent" translatable="false">Allows the app to receive input events from <xliff:g id="app_name">Live TV</xliff:g> app</string>
<!-- Title of an application permission, listed so the user can choose
whether they want to allow the application to do this. -->
- <string name="permlab_customizeTvApp" translatable="false">customize <xliff:g id="app_name">Live TV</xliff:g> app</string>
+ <string name="permlab_customizeTvApp" translatable="false">customize <xliff:g id="app_name">Live TV</xliff:g> app</string>
<!-- Description of an application permission, listed so the user can choose
whether they want to allow the application to do this. -->
- <string name="permdesc_customizeTvApp" translatable="false">Allows the app to customize <xliff:g id="app_name">Live TV</xliff:g> app</string>
+ <string name="permdesc_customizeTvApp" translatable="false">Allows the app to customize <xliff:g id="app_name">Live TV</xliff:g> app</string>
<!-- Program information, mainly used for channel banner and program guide. -->
<eat-comment />
@@ -388,13 +388,13 @@
<!-- Description on the locked screen with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_content_locked_format">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>.\nTo watch this program, press Right and enter your PIN.</string>
<!-- Description on the locked screen when current channel is locked by parental control. [CHAR LIMIT=NONE] -->
- <string name="tvview_channel_locked_no_permission">To watch this channel, use the default TV app.</string>
+ <string name="tvview_channel_locked_no_permission">To watch this channel, use the default Live TV app.</string>
<!-- Description on the locked screen when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
- <string name="tvview_content_locked_no_permission">To watch this program, use the default TV app.</string>
+ <string name="tvview_content_locked_no_permission">To watch this program, use the default Live TV app.</string>
<!-- Description on the locked screen when the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
- <string name="tvview_content_locked_unrated_no_permission">This program is unrated.\nTo watch this program, use the default TV app.</string>
+ <string name="tvview_content_locked_unrated_no_permission">This program is unrated.\nTo watch this program, use the default Live TV app.</string>
<!-- Description on the locked screen with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
- <string name="tvview_content_locked_format_no_permission">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>.\nTo watch this program, use the default TV app.</string>
+ <string name="tvview_content_locked_format_no_permission">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>.\nTo watch this program, use the default Live TV app.</string>
<!-- Description on the locked screen when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="shrunken_tvview_content_locked">Program is blocked</string>
@@ -479,7 +479,7 @@
the source video through to the display and don't provide ability to tune to a specific
channel unless the user directly controls the external source device (e.g. game console,
DVD player, settop box, etc) that is connected to the TV. [CHAR LIMIT=NONE] -->
- <string name="msg_not_passthrough_input">Tuner type not suitable. Please launch <xliff:g id="app_name">Live TV</xliff:g> app for tuner type TV input.</string>
+ <string name="msg_not_passthrough_input">Tuner type not suitable. Please launch <xliff:g id="app_name">Live TV</xliff:g> app for tuner type TV input.</string>
<!-- Error message when tune is failed. [CHAR LIMIT=NONE] -->
<string name="msg_tune_failed">Tune failed</string>
<!-- Error message when the user attempts an action (select TIS setup-activity, app-link,
@@ -496,7 +496,7 @@
(commands for external device) [CHAR LIMIT=NONE] -->
<string name="msg_back_key_guide">BACK key is for connected device. Press HOME button to exit.</string>
<!-- Error message when a user denied to grant READ_TV_LISTING permission. [CHAR LIMIT=NONE] -->
- <string name="msg_read_tv_listing_permission_denied"><xliff:g id="app_name">Live TV</xliff:g> needs permission to read the TV listings.</string>
+ <string name="msg_read_tv_listing_permission_denied"><xliff:g id="app_name">Live TV</xliff:g> needs permission to read the TV listings.</string>
<!-- Strings for debug or not to be shown to users -->
<eat-comment />
@@ -518,17 +518,17 @@
<!-- Title of Recently watched dialog. It is used for debug purpose. -->
<string name="recently_watched" translatable="false">Recently watched</string>
- <!-- Title of DVR history dialog. [CHAR LIMIT=50] -->
+ <!-- Title of DVR history dialog. -->
<string name="dvr_history_dialog_title" translatable="false">DVR history</string>
- <!-- Display name of DVR recording service's notification channel. [CHAR LIMIT=50] -->
- <string name="dvr_notification_channel_name" ><xliff:g id="app_name">Live TV</xliff:g> DVR</string>
- <!-- Content title of DVR recording service's notification. [CHAR LIMIT=50] -->
- <string name="dvr_notification_content_title" ><xliff:g id="app_name">Live TV</xliff:g> DVR</string>
- <!-- Content text of DVR recording service's notification during recording. [CHAR LIMIT=NONE] -->
- <string name="dvr_notification_content_text_recording" ><xliff:g id="app_name">Live TV</xliff:g> are recording.</string>
- <!-- Content text of DVR recording service's notification during updating schedules. [CHAR LIMIT=NONE] -->
- <string name="dvr_notification_content_text_loading" ><xliff:g id="app_name">Live TV</xliff:g> are updating recording schedules.</string>
+ <!-- Display name of DVR recording service's notification channel. -->
+ <string name="dvr_notification_channel_name" translatable="false"><xliff:g id="app_name">Live TV</xliff:g> DVR</string>
+ <!-- Content title of DVR recording service's notification. -->
+ <string name="dvr_notification_content_title" translatable="false"><xliff:g id="app_name">Live TV</xliff:g> DVR</string>
+ <!-- Content text of DVR recording service's notification during recording. -->
+ <string name="dvr_notification_content_text_recording" translatable="false"><xliff:g id="app_name">Live TV</xliff:g> are recording.</string>
+ <!-- Content text of DVR recording service's notification during updating schedules. -->
+ <string name="dvr_notification_content_text_loading" translatable="false"><xliff:g id="app_name">Live TV</xliff:g> are updating recording schedules.</string>
<!-- Default content title of tuner installing notifications. -->
<string name="tuner_install_notification_content_title" translatable="false">Install <xliff:g id="tuner_package" example="Tuner package">%s</xliff:g></string>
@@ -546,6 +546,9 @@
<eat-comment />
<!-- Text for the channel sources screen in onboarding. -->
<string name="setup_sources_text">Set up your sources</string>
+ <!-- Description for channel sources screen in onboarding. -->
+ <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 the online store for more apps that offer live channels.</string>
<!-- Menu item label to start DVR manager UI. -->
<string name="channels_item_dvr">Recordings &amp; schedules</string>
@@ -690,8 +693,8 @@
<item quantity="one">%1$d of %2$d episode is deleted</item>
<item quantity="other">%1$d of %2$d episodes are deleted</item>
</plurals>
- <!-- Title of screen with settings for the recording of a TV Program or Series. [CHAR LIMIT=50] -->
- <string name="dvr_series_settings_title">Recording settings</string>
+ <!-- Title of DVR series settings -->
+ <string name="dvr_series_settings_title" translatable="false">Recording settings</string>
<!-- Item label to change priority of TV series for DVR -->
<string name="dvr_series_settings_priority">Priority</string>
<!-- Item description when the current series has the height proirty among scheduled
@@ -719,13 +722,10 @@
<!-- DVR epg strings -->
<eat-comment />
- <!-- Button text that deletes scheduled future recordings of a TV Program or Series. [CHAR LIMIT=50] -->
- <string name="dvr_action_delete_schedule">Delete schedule</string>
- <!-- Button text that records the selected program. [CHAR LIMIT=50] -->
- <string name="dvr_action_record_program">Record program</string>
- <!-- Button text that invokes android internal storage settings activity.
- [CHAR LIMIT=50] -->
- <string name="dvr_action_error_storage_settings">Open storage settings</string>
+ <string name="dvr_action_delete_schedule" translatable="false">Delete schedule</string>
+ <string name="dvr_action_record_program" translatable="false">Record program</string>
+ <!-- The action to forget DVR storage which is missing currently. invoke android internal storage settings activity. -->
+ <string name="dvr_action_error_storage_settings" translatable="false">Open storage settings</string>
<!-- The action to stop recording. [CHAR LIMIT=10] -->
<string name="dvr_action_stop">Stop</string>
<!-- The action to open the activity which shows all the schedules.[CHAR LIMIT=32] -->
@@ -767,10 +767,8 @@
<!-- Dvr label in epg to indicate the recording of the program has been failed. [CHAR LIMIT=30] -->
<string name="dvr_epg_program_recording_failed">Recording failed</string>
<string name="dvr_epg_program_icon_text" translatable="false">DVR</string>
- <!-- Title of a dialog box displayed when a previously scheduled recording requires an action.[CHAR LIMIT=50] -->
- <string name="dvr_epg_channel_watch_conflict_dialog_title">Upcoming schedules</string>
- <!-- Description in a dialog box displayed when a previously scheduled recording requires an action. [CHAR LIMIT=NONE] -->
- <string name="dvr_epg_channel_watch_conflict_dialog_description">The program will not be recorded if you keep watching this channel. Cancel the recording, or the current channel will be blocked when the recording starts.</string>
+ <string name="dvr_epg_channel_watch_conflict_dialog_title" translatable="false">Upcoming schedules</string>
+ <string name="dvr_epg_channel_watch_conflict_dialog_description" translatable="false">The programs will not be recorded if you keep watching this channel. Cancel the recordings, or current channel will be blocked when the recording starts.</string>
<!-- A popup message which informs that Live TV is reading program information. -->
<string name="dvr_series_progress_message_reading_programs">Reading programs</string>
<!-- Dialog action which let user view the recent recordings. -->
@@ -800,10 +798,10 @@
<string name="dvr_error_no_free_space_description">This program will not be recorded because there is not enough storage. Try deleting some existing recordings.</string>
<!-- Dialog title which will be shown when the current DVR storage is not accessible. -->
<string name="dvr_error_missing_storage_title">Missing storage</string>
- <!-- Dialog description which will be shown when the current DVR storage is not accessible. [CHAR LIMIT=NONE] -->
- <string name="dvr_error_missing_storage_description">Some of the storage used for recording is missing. Please connect the external drive you used before to re-enable recording. Alternately, you can forget the storage in the storage settings, if it\'s no longer available.</string>
- <!-- A toast message displad to the user when the recording being requested to play is not found in storage. [CHAR LIMIT=NONE] -->
- <string name="dvr_toast_recording_deleted">Recording not found.</string>
+ <!-- Dialog description which will be shown when the current DVR storage is not accessible. -->
+ <string name="dvr_error_missing_storage_description" translatable="false">Some of the storage used for recording is missing. Please connect the external drive you used before to re-enable recording. Alternately, you can forget the storage in the storage settings, if it\'s no longer available.</string>
+ <!-- The recording being requested to play is not existent in storage. It may be deleted. -->
+ <string name="dvr_toast_recording_deleted" translatable="false">The recording seems to be deleted.</string>
<!-- DVR half sized dialogs -->
<eat-comment />
@@ -910,8 +908,7 @@
<!-- DVR channel banner strings -->
<eat-comment />
- <!-- Text desplayed on screen to show that the current program is being recorded until the time listed. [CHAR LIMIT=30] -->
- <string name="dvr_recording_till_format">Recording till <xliff:g id="recordingEndTime" example="9:00pm">%1$s</xliff:g></string>
+ <string name="dvr_recording_till_format" translatable="false">Recording till <xliff:g id="recordingEndTime" example="9:00pm">%1$s</xliff:g></string>
<!-- DVR schedule list strings -->
<eat-comment/>
diff --git a/res/xml/tv_content_rating_systems.xml b/res/xml/tv_content_rating_systems.xml
index 361393f5..aad9d610 100644
--- a/res/xml/tv_content_rating_systems.xml
+++ b/res/xml/tv_content_rating_systems.xml
@@ -286,170 +286,6 @@
</rating-order>
</rating-system-definition>
- <!-- TV content rating system for DTMB. See http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=59E83CA701AEB4248E115BC043688FEC -->
- <rating-system-definition android:name="DTMB"
- android:country="CN">
- <rating-definition android:name="DTMB_4"
- android:title="4"
- android:description="@string/description_age_4"
- android:contentAgeHint="4" />
- <rating-definition android:name="DTMB_5"
- android:title="5"
- android:description="@string/description_age_5"
- android:contentAgeHint="5" />
- <rating-definition android:name="DTMB_6"
- android:title="6"
- android:description="@string/description_age_6"
- android:contentAgeHint="6" />
- <rating-definition android:name="DTMB_7"
- android:title="7"
- android:description="@string/description_age_7"
- android:contentAgeHint="7" />
- <rating-definition android:name="DTMB_8"
- android:title="8"
- android:description="@string/description_age_8"
- android:contentAgeHint="8" />
- <rating-definition android:name="DTMB_9"
- android:title="9"
- android:description="@string/description_age_9"
- android:contentAgeHint="9" />
- <rating-definition android:name="DTMB_10"
- android:title="10"
- android:description="@string/description_age_10"
- android:contentAgeHint="10" />
- <rating-definition android:name="DTMB_11"
- android:title="11"
- android:description="@string/description_age_11"
- android:contentAgeHint="11" />
- <rating-definition android:name="DTMB_12"
- android:title="12"
- android:description="@string/description_age_12"
- android:contentAgeHint="12" />
- <rating-definition android:name="DTMB_13"
- android:title="13"
- android:description="@string/description_age_13"
- android:contentAgeHint="13" />
- <rating-definition android:name="DTMB_14"
- android:title="14"
- android:description="@string/description_age_14"
- android:contentAgeHint="14" />
- <rating-definition android:name="DTMB_15"
- android:title="15"
- android:description="@string/description_age_15"
- android:contentAgeHint="15" />
- <rating-definition android:name="DTMB_16"
- android:title="16"
- android:description="@string/description_age_16"
- android:contentAgeHint="16" />
- <rating-definition android:name="DTMB_17"
- android:title="17"
- android:description="@string/description_age_17"
- android:contentAgeHint="17" />
- <rating-definition android:name="DTMB_18"
- android:title="18"
- android:description="@string/description_age_18"
- android:contentAgeHint="18" />
- <rating-order>
- <rating android:name="DTMB_4" />
- <rating android:name="DTMB_5" />
- <rating android:name="DTMB_6" />
- <rating android:name="DTMB_7" />
- <rating android:name="DTMB_8" />
- <rating android:name="DTMB_9" />
- <rating android:name="DTMB_10" />
- <rating android:name="DTMB_11" />
- <rating android:name="DTMB_12" />
- <rating android:name="DTMB_13" />
- <rating android:name="DTMB_14" />
- <rating android:name="DTMB_15" />
- <rating android:name="DTMB_16" />
- <rating android:name="DTMB_17" />
- <rating android:name="DTMB_18" />
- </rating-order>
- </rating-system-definition>
-
- <!-- TV content rating system for DTMB. See http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=59E83CA701AEB4248E115BC043688FEC -->
- <rating-system-definition android:name="DTMB"
- android:country="CN">
- <rating-definition android:name="DTMB_4"
- android:title="4"
- android:description="@string/description_age_4"
- android:contentAgeHint="4" />
- <rating-definition android:name="DTMB_5"
- android:title="5"
- android:description="@string/description_age_5"
- android:contentAgeHint="5" />
- <rating-definition android:name="DTMB_6"
- android:title="6"
- android:description="@string/description_age_6"
- android:contentAgeHint="6" />
- <rating-definition android:name="DTMB_7"
- android:title="7"
- android:description="@string/description_age_7"
- android:contentAgeHint="7" />
- <rating-definition android:name="DTMB_8"
- android:title="8"
- android:description="@string/description_age_8"
- android:contentAgeHint="8" />
- <rating-definition android:name="DTMB_9"
- android:title="9"
- android:description="@string/description_age_9"
- android:contentAgeHint="9" />
- <rating-definition android:name="DTMB_10"
- android:title="10"
- android:description="@string/description_age_10"
- android:contentAgeHint="10" />
- <rating-definition android:name="DTMB_11"
- android:title="11"
- android:description="@string/description_age_11"
- android:contentAgeHint="11" />
- <rating-definition android:name="DTMB_12"
- android:title="12"
- android:description="@string/description_age_12"
- android:contentAgeHint="12" />
- <rating-definition android:name="DTMB_13"
- android:title="13"
- android:description="@string/description_age_13"
- android:contentAgeHint="13" />
- <rating-definition android:name="DTMB_14"
- android:title="14"
- android:description="@string/description_age_14"
- android:contentAgeHint="14" />
- <rating-definition android:name="DTMB_15"
- android:title="15"
- android:description="@string/description_age_15"
- android:contentAgeHint="15" />
- <rating-definition android:name="DTMB_16"
- android:title="16"
- android:description="@string/description_age_16"
- android:contentAgeHint="16" />
- <rating-definition android:name="DTMB_17"
- android:title="17"
- android:description="@string/description_age_17"
- android:contentAgeHint="17" />
- <rating-definition android:name="DTMB_18"
- android:title="18"
- android:description="@string/description_age_18"
- android:contentAgeHint="18" />
- <rating-order>
- <rating android:name="DTMB_4" />
- <rating android:name="DTMB_5" />
- <rating android:name="DTMB_6" />
- <rating android:name="DTMB_7" />
- <rating android:name="DTMB_8" />
- <rating android:name="DTMB_9" />
- <rating android:name="DTMB_10" />
- <rating android:name="DTMB_11" />
- <rating android:name="DTMB_12" />
- <rating android:name="DTMB_13" />
- <rating android:name="DTMB_14" />
- <rating android:name="DTMB_15" />
- <rating android:name="DTMB_16" />
- <rating android:name="DTMB_17" />
- <rating android:name="DTMB_18" />
- </rating-order>
- </rating-system-definition>
-
<!-- TV content rating system for DVB. See Table 81 of DVB SI (EN 300 468 V1.14.1) in https://www.dvb.org/standards -->
<rating-system-definition android:name="DVB"
android:country="AM, BG, CH, DE, DK, FI, GR, HU, ID, IE, IL, IS, MY, NL, NZ, PL, PT, RO, RU, RS, SI, TH, TR, TW, UA">
@@ -840,28 +676,6 @@
</rating-order>
</rating-system-definition>
- <!-- TV content rating system for NZ. See http://www.freeviewnz.tv/ -->
- <rating-system-definition android:name="NZ_TV"
- android:country="NZ">
- <rating-definition android:name="NZ_TV_G"
- android:title="G"
- android:description="@string/description_nz_fta_tv_g"
- android:contentAgeHint="0" />
- <rating-definition android:name="NZ_TV_PGR"
- android:title="PGR"
- android:description="@string/description_nz_fta_tv_pgr"
- android:contentAgeHint="0" />
- <rating-definition android:name="NZ_TV_AO"
- android:title="AO"
- android:description="@string/description_nz_fta_tv_ao"
- android:contentAgeHint="0" />
- <rating-order>
- <rating android:name="NZ_TV_G" />
- <rating android:name="NZ_TV_PGR" />
- <rating android:name="NZ_TV_AO" />
- </rating-order>
- </rating-system-definition>
-
<!-- TV content rating system for SG. See http://www.mda.gov.sg/RegulationsAndLicensing/ContentStandardsAndClassification/FilmsAndVideos/Pages/default.aspx -->
<rating-system-definition android:name="SG_TV"
android:country="SG">
@@ -899,43 +713,6 @@
</rating-order>
</rating-system-definition>
- <!-- TV content rating system for TH. See https://broadcast.nbtc.go.th/home/ -->
- <rating-system-definition android:name="TH_TV"
- android:country="TH">
- <rating-definition android:name="TH_TV_4"
- android:title="4"
- android:description="@string/description_th_tv_4"
- android:contentAgeHint="4" />
- <rating-definition android:name="TH_TV_6"
- android:title="6"
- android:description="@string/description_th_tv_6"
- android:contentAgeHint="6" />
- <rating-definition android:name="TH_TV_10"
- android:title="10"
- android:description="@string/description_th_tv_10"
- android:contentAgeHint="10" />
- <rating-definition android:name="TH_TV_13"
- android:title="13"
- android:description="@string/description_th_tv_13"
- android:contentAgeHint="13" />
- <rating-definition android:name="TH_TV_18"
- android:title="18"
- android:description="@string/description_th_tv_18"
- android:contentAgeHint="18" />
- <rating-definition android:name="TH_TV_19"
- android:title="19"
- android:description="@string/description_th_tv_19"
- android:contentAgeHint="19" />
- <rating-order>
- <rating android:name="TH_TV_4" />
- <rating android:name="TH_TV_6" />
- <rating android:name="TH_TV_10" />
- <rating android:name="TH_TV_13" />
- <rating android:name="TH_TV_18" />
- <rating android:name="TH_TV_19" />
- </rating-order>
- </rating-system-definition>
-
<!-- TV content rating system for US. See http://www.tvguidelines.org/ratings.htm -->
<rating-system-definition android:name="US_TV"
android:country="US">
diff --git a/settings.gradle b/settings.gradle
index 5916cb4a..6d5cb547 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -23,5 +23,3 @@ include ':common'
include ':tuner'
include ':SampleDvbTuner'
project(":SampleDvbTuner").projectDir = file("tuner/SampleDvbTuner")
-include ':SampleNetworkTuner'
-project(":SampleNetworkTuner").projectDir = file("tuner/SampleNetworkTuner")
diff --git a/src/com/android/tv/LauncherActivity.java b/src/com/android/tv/LauncherActivity.java
index ccc5600a..679d612d 100644
--- a/src/com/android/tv/LauncherActivity.java
+++ b/src/com/android/tv/LauncherActivity.java
@@ -27,10 +27,10 @@ import android.util.Log;
* An activity to launch a new activity.
*
* <p>In the case when {@link MainActivity} starts a new activity using {@link
- * Activity#startActivity} or {@link Activity#startActivityForResult}, TV app is terminated if the
- * new activity crashes. That's because the {@link android.app.ActivityManager} terminates the
- * activity which is just below the crashed activity in the activity stack. To avoid this, we need
- * to locate an additional activity between these activities in the activity stack.
+ * Activity#startActivity} or {@link Activity#startActivityForResult}, Live TV app is
+ * terminated if the new activity crashes. That's because the {@link android.app.ActivityManager}
+ * terminates the activity which is just below the crashed activity in the activity stack. To avoid
+ * this, we need to locate an additional activity between these activities in the activity stack.
*/
public class LauncherActivity extends Activity {
private static final String TAG = "LauncherActivity";
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index 7a591500..b4cf71db 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -16,8 +16,6 @@
package com.android.tv;
-import static com.android.tv.common.feature.SystemAppFeature.SYSTEM_APP_FEATURE;
-
import android.app.Activity;
import android.app.PendingIntent;
import android.app.SearchManager;
@@ -46,7 +44,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
-import android.provider.BaseColumns;
import android.provider.Settings;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
@@ -68,7 +65,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.Toast;
-
import com.android.tv.MainActivity.MySingletons;
import com.android.tv.analytics.SendChannelStatusRunnable;
import com.android.tv.analytics.SendConfigInfoRunnable;
@@ -82,7 +78,6 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.compat.TvInputInfoCompat;
-import com.android.tv.common.dev.DeveloperPreferences;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.memory.MemoryManageable;
import com.android.tv.common.singletons.HasSingletons;
@@ -96,13 +91,11 @@ import com.android.tv.common.util.SystemProperties;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
@@ -113,12 +106,11 @@ import com.android.tv.dvr.recorder.ConflictChecker;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.features.TvFeatures;
-import com.android.tv.guide.ProgramItemView;
import com.android.tv.menu.Menu;
import com.android.tv.onboarding.OnboardingActivity;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.receiver.AudioCapabilitiesReceiver;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
@@ -134,7 +126,6 @@ import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.BlockScreenType;
import com.android.tv.ui.TunableTvView.OnTuneListener;
import com.android.tv.ui.TvOverlayManager;
-import com.android.tv.ui.TvOverlayManagerFactory;
import com.android.tv.ui.TvViewUiManager;
import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.CustomizeChannelListFragment;
@@ -144,7 +135,6 @@ 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.ui.sidepanel.parentalcontrols.RatingsFragment;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.CaptionSettings;
@@ -160,17 +150,9 @@ import com.android.tv.util.account.AccountHelper;
import com.android.tv.util.images.ImageCache;
import com.google.common.base.Optional;
-
import dagger.android.AndroidInjection;
-import dagger.android.AndroidInjector;
import dagger.android.ContributesAndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-import com.android.tv.common.flags.LegacyFlags;
-import com.android.tv.common.flags.StartupFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
@@ -181,17 +163,15 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-
import javax.inject.Inject;
import javax.inject.Provider;
-/** The main activity for the TV app. */
+/** The main activity for the Live TV app. */
public class MainActivity extends Activity
implements OnActionClickListener,
OnPinCheckedListener,
ChannelChanger,
- HasSingletons<MySingletons>,
- HasAndroidInjector {
+ HasSingletons<MySingletons> {
private static final String TAG = "MainActivity";
private static final boolean DEBUG = false;
private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
@@ -278,11 +258,10 @@ public class MainActivity extends Activity
private static final long START_UP_TIMER_RESET_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(3);
{
- StartupMeasureFactory.create().onActivityInit();
+ PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
}
private final MySingletonsImpl mMySingletons = new MySingletonsImpl();
- @Inject DispatchingAndroidInjector<Object> mAndroidInjector;
@Inject @DbExecutor Executor mDbExecutor;
private AccessibilityManager mAccessibilityManager;
@@ -299,12 +278,8 @@ public class MainActivity extends Activity
private DvrManager mDvrManager;
private ConflictChecker mDvrConflictChecker;
@Inject BackendKnobsFlags mBackendKnobs;
- @Inject LegacyFlags mLegacyFlags;
- @Inject StartupFlags mStartupFlags;
@Inject SetupUtils mSetupUtils;
@Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
- @Inject AccountHelper mAccountHelper;
- @Inject EpgFetcher mEpgFetcher;
@VisibleForTesting protected TunableTvView mTvView;
private View mContentView;
@@ -339,7 +314,6 @@ public class MainActivity extends Activity
private boolean mIsFilmModeSet;
private float mDefaultRefreshRate;
- @Inject TvOverlayManagerFactory mOverlayFactory;
private TvOverlayManager mOverlayManager;
// mIsCurrentChannelUnblockedByUser and mWasChannelUnblockedBeforeShrunkenByUser are used for
@@ -503,6 +477,7 @@ public class MainActivity extends Activity
AndroidInjection.inject(this);
mAccessibilityManager =
(AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(this);
DurationTimer startUpDebugTimer = Debug.getTimer(Debug.TAG_START_UP_TIMER);
if (!startUpDebugTimer.isStarted()
|| startUpDebugTimer.getDuration() > START_UP_TIMER_RESET_THRESHOLD_MS) {
@@ -521,7 +496,6 @@ public class MainActivity extends Activity
finishAndRemoveTask();
return;
}
- mAccountHelper.init();
TvSingletons tvApplication = (TvSingletons) getApplication();
// In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
@@ -540,8 +514,8 @@ public class MainActivity extends Activity
return;
}
setContentView(R.layout.activity_tv);
- mTvView = findViewById(R.id.main_tunable_tv_view);
- mTvView.initialize(mProgramDataManager, mTvInputManagerHelper, mLegacyFlags);
+ mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
+ mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
mTvView.setOnUnhandledInputEventListener(
new OnUnhandledInputEventListener() {
@Override
@@ -571,13 +545,12 @@ public class MainActivity extends Activity
String inputId = Utils.getLastWatchedTunerInputId(this);
if (!isPassthroughInput
&& inputId != null
- && !mStartupFlags.warmupInputidBlacklist().getElementList().contains(inputId)
&& channelId != Channel.INVALID_ID) {
mTvView.warmUpInput(inputId, TvContract.buildChannelUri(channelId));
}
tvApplication.getMainActivityWrapper().onMainActivityCreated(this);
- if (BuildConfig.ENG && DeveloperPreferences.ALLOW_STRICT_MODE.get(this)) {
+ if (BuildConfig.ENG && SystemProperties.ALLOW_STRICT_MODE.getValue()) {
Toast.makeText(this, "Using Strict Mode for eng builds", Toast.LENGTH_SHORT).show();
}
mTracker = tvApplication.getTracker();
@@ -639,10 +612,13 @@ public class MainActivity extends Activity
}
mTvViewUiManager =
new TvViewUiManager(
- this, mTvView, findViewById(android.R.id.content), mTvOptionsManager);
+ this,
+ mTvView,
+ (FrameLayout) findViewById(android.R.id.content),
+ mTvOptionsManager);
mContentView = findViewById(android.R.id.content);
- ViewGroup sceneContainer = findViewById(R.id.scene_container);
+ ViewGroup sceneContainer = (ViewGroup) findViewById(R.id.scene_container);
ChannelBannerView channelBannerView =
(ChannelBannerView)
getLayoutInflater().inflate(R.layout.channel_banner, sceneContainer, false);
@@ -695,7 +671,7 @@ public class MainActivity extends Activity
});
mSearchFragment = new ProgramGuideSearchFragment();
mOverlayManager =
- mOverlayFactory.create(
+ new TvOverlayManager(
this,
mChannelTuner,
mTvView,
@@ -733,6 +709,8 @@ public class MainActivity extends Activity
SendChannelStatusRunnable.startChannelStatusRecurringRunner(
this, mTracker, mChannelDataManager);
+ // To avoid not updating Rating systems when changing language.
+ mTvInputManagerHelper.getContentRatingsManager().update();
if (CommonFeatures.DVR.isEnabled(this)
&& TvFeatures.SHOW_UPCOMING_CONFLICT_DIALOG.isEnabled(this)) {
mDvrConflictChecker = new ConflictChecker(this);
@@ -764,7 +742,7 @@ public class MainActivity extends Activity
mChannelDataManager.reload();
mProgramDataManager.reload();
- // Restart TV app.
+ // Restart live channels.
Intent intent = getIntent();
finish();
startActivity(intent);
@@ -852,7 +830,7 @@ public class MainActivity extends Activity
.getTunerInputController()
.executeNetworkTunerDiscoveryAsyncTask(this);
}
- mEpgFetcher.fetchImmediatelyIfNeeded();
+ TvSingletons.getSingletons(this).getEpgFetcher().fetchImmediatelyIfNeeded();
}
@Override
@@ -1149,8 +1127,8 @@ public class MainActivity extends Activity
Toast.makeText(this, R.string.msg_no_setup_activity, Toast.LENGTH_SHORT).show();
return;
}
- // Even though other app can handle the intent, the setup launched by TV app
- // should go through TV app SetupPassthroughActivity.
+ // Even though other app can handle the intent, the setup launched by Live channels
+ // should go through Live channels SetupPassthroughActivity.
intent.setComponent(new ComponentName(this, SetupPassthroughActivity.class));
try {
// Now we know that the user intends to set up this input. Grant permission for writing
@@ -1420,9 +1398,7 @@ public class MainActivity extends Activity
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
- Log.d(TAG, "dispatchKeyEvent(" + event + ")");
- }
+ if (SystemProperties.LOG_KEYEVENT.getValue()) Log.d(TAG, "dispatchKeyEvent(" + event + ")");
// If an activity is closed on a back key down event, back key down events with none zero
// repeat count or a back key up event can be happened without the first back key down
// event which should be ignored in this activity.
@@ -1527,7 +1503,7 @@ public class MainActivity extends Activity
new AsyncQueryProgramTask(
mDbExecutor,
programUriFromIntent,
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
null,
@@ -1558,7 +1534,7 @@ public class MainActivity extends Activity
String inputId = mInitChannelUri.getQueryParameter("input");
long channelId = Utils.getLastWatchedChannelIdForInput(this, inputId);
if (channelId == Channel.INVALID_ID) {
- String[] projection = {BaseColumns._ID};
+ String[] projection = {Channels._ID};
long time = System.currentTimeMillis();
try (Cursor cursor =
getContentResolver().query(uri, projection, null, null, null)) {
@@ -1606,7 +1582,7 @@ public class MainActivity extends Activity
protected Program onQuery(Cursor c) {
Program program = null;
if (c != null && c.moveToNext()) {
- program = ProgramImpl.fromCursor(c);
+ program = Program.fromCursor(c);
}
return program;
}
@@ -1622,7 +1598,7 @@ public class MainActivity extends Activity
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra(DetailsActivity.CHANNEL_ID, mChannelIdFromIntent);
intent.putExtra(DetailsActivity.DETAILS_VIEW_TYPE, DetailsActivity.PROGRAM_VIEW);
- intent.putExtra(DetailsActivity.PROGRAM, program.toParcelable());
+ intent.putExtra(DetailsActivity.PROGRAM, program);
intent.putExtra(DetailsActivity.INPUT_ID, channel.getInputId());
startActivity(intent);
}
@@ -2101,7 +2077,7 @@ public class MainActivity extends Activity
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "onKeyDown(" + keyCode + ", " + event + ")");
}
switch (mOverlayManager.onKeyDown(keyCode, event)) {
@@ -2191,7 +2167,7 @@ public class MainActivity extends Activity
* W debug: toggle screen size
* V KEYCODE_MEDIA_RECORD debug: record the current channel for 30 sec
*/
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "onKeyUp(" + keyCode + ", " + event + ")");
}
// If we are in the middle of channel change, finish it before showing overlays.
@@ -2289,7 +2265,7 @@ public class MainActivity extends Activity
// Channel change is already done in the head of this method.
return true;
case KeyEvent.KEYCODE_S:
- if (!DeveloperPreferences.USE_DEBUG_KEYS.get(this)) {
+ if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
// fall through.
@@ -2297,7 +2273,7 @@ public class MainActivity extends Activity
mOverlayManager.getSideFragmentManager().show(new ClosedCaptionFragment());
return true;
case KeyEvent.KEYCODE_A:
- if (!DeveloperPreferences.USE_DEBUG_KEYS.get(this)) {
+ if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
// fall through.
@@ -2363,7 +2339,7 @@ public class MainActivity extends Activity
// in case that TV isn't showing properly (e.g. no browsable channel)
return true;
}
- if (DeveloperPreferences.USE_DEBUG_KEYS.get(this) || BuildConfig.ENG) {
+ if (SystemProperties.USE_DEBUG_KEYS.getValue() || BuildConfig.ENG) {
switch (keyCode) {
case KeyEvent.KEYCODE_W:
mDebugNonFullSizeScreen = !mDebugNonFullSizeScreen;
@@ -2419,7 +2395,7 @@ public class MainActivity extends Activity
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) Log.d(TAG, "onKeyLongPress(" + event);
+ if (SystemProperties.LOG_KEYEVENT.getValue()) Log.d(TAG, "onKeyLongPress(" + event);
if (USE_BACK_KEY_LONG_PRESS) {
// Treat the BACK key long press as the normal press since we changed the behavior in
// onBackPressed().
@@ -2489,7 +2465,7 @@ public class MainActivity extends Activity
}
private boolean dispatchKeyEventToSession(final KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "dispatchKeyEventToSession(" + event + ")");
}
boolean handled = false;
@@ -2742,10 +2718,7 @@ public class MainActivity extends Activity
return;
}
- // Only try to set the channels browseable if we are a system app.
- if (SYSTEM_APP_FEATURE.isEnabled(getApplicationContext())) {
- Utils.enableAllChannels(this);
- }
+ Utils.enableAllChannels(this);
}
// Lazy initialization
@@ -2805,11 +2778,6 @@ public class MainActivity extends Activity
}
}
- @Override
- public AndroidInjector<Object> androidInjector() {
- return mAndroidInjector;
- }
-
private static class MainActivityHandler extends WeakHandler<MainActivity> {
MainActivityHandler(MainActivity mainActivity) {
super(mainActivity);
@@ -2855,8 +2823,11 @@ public class MainActivity extends Activity
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.MyOnTuneListener.onTune");
mChannel = channel;
mWasUnderShrunkenTvView = wasUnderShrunkenTvView;
- // Fetch complete projection of tuned channel.
- mProgramDataManager.onChannelTuned(channel.getId());
+
+ if (mBackendKnobs.enablePartialProgramFetch()) {
+ // Fetch complete projection of tuned channel.
+ mProgramDataManager.prefetchChannel(channel.getId());
+ }
}
@Override
@@ -3011,14 +2982,5 @@ public class MainActivity extends Activity
public abstract static class Module {
@ContributesAndroidInjector
abstract MainActivity contributesMainActivityActivityInjector();
-
- @ContributesAndroidInjector
- abstract DeveloperOptionFragment contributesDeveloperOptionFragment();
-
- @ContributesAndroidInjector
- abstract RatingsFragment contributesRatingsFragment();
-
- @ContributesAndroidInjector
- abstract ProgramItemView contributesProgramItemView();
}
}
diff --git a/src/com/android/tv/MediaSessionWrapper.java b/src/com/android/tv/MediaSessionWrapper.java
index df886391..a647a06f 100644
--- a/src/com/android/tv/MediaSessionWrapper.java
+++ b/src/com/android/tv/MediaSessionWrapper.java
@@ -34,9 +34,8 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
-
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 25049f1d..5185b122 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -18,7 +18,7 @@ package com.android.tv;
import android.app.Activity;
import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
@@ -26,8 +26,6 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.MainThread;
import android.util.Log;
-
-import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.actions.InputSetupActionUtils;
import com.android.tv.data.ChannelDataManager;
@@ -38,16 +36,9 @@ import com.android.tv.features.TvFeatures;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
import com.google.android.tv.partner.support.EpgContract;
-
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
/**
* An activity to launch a TV input setup activity.
*
@@ -64,20 +55,18 @@ public class SetupPassthroughActivity extends Activity {
private TvInputInfo mTvInputInfo;
private Intent mActivityAfterCompletion;
private boolean mEpgFetcherDuringScan;
- @Inject EpgInputWhiteList mEpgInputWhiteList;
- @Inject TvInputManagerHelper mInputManager;
- @Inject SetupUtils mSetupUtils;
- @Inject ChannelDataManager mChannelDataManager;
- @Inject EpgFetcher mEpgFetcher;
+ private EpgInputWhiteList mEpgInputWhiteList;
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate");
- AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(this);
+ TvInputManagerHelper inputManager = tvSingletons.getTvInputManagerHelper();
Intent intent = getIntent();
String inputId = intent.getStringExtra(InputSetupActionUtils.EXTRA_INPUT_ID);
- mTvInputInfo = mInputManager.getTvInputInfo(inputId);
+ mTvInputInfo = inputManager.getTvInputInfo(inputId);
+ mEpgInputWhiteList = new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
mActivityAfterCompletion = InputSetupActionUtils.getExtraActivityAfter(intent);
boolean needToFetchEpg =
mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId());
@@ -117,17 +106,6 @@ public class SetupPassthroughActivity extends Activity {
InputSetupActionUtils.removeSetupIntent(extras);
setupIntent.putExtras(extras);
try {
- ComponentName callingActivity = getCallingActivity();
- if (callingActivity != null
- && !callingActivity.getPackageName().equals(CommonConstants.BASE_PACKAGE)) {
- Log.w(
- TAG,
- "Calling activity "
- + callingActivity.getPackageName()
- + " is not trusted. Not forwarding intent.");
- finish();
- return;
- }
startActivityForResult(setupIntent, REQUEST_START_SETUP_ACTIVITY);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Can't find activity: " + setupIntent.getComponent());
@@ -136,10 +114,10 @@ public class SetupPassthroughActivity extends Activity {
}
if (needToFetchEpg) {
if (sScanTimeoutMonitor == null) {
- sScanTimeoutMonitor = new ScanTimeoutMonitor(mEpgFetcher, mChannelDataManager);
+ sScanTimeoutMonitor = new ScanTimeoutMonitor(this);
}
sScanTimeoutMonitor.startMonitoring();
- mEpgFetcher.onChannelScanStarted();
+ TvSingletons.getSingletons(this).getEpgFetcher().onChannelScanStarted();
}
}
}
@@ -155,25 +133,15 @@ public class SetupPassthroughActivity extends Activity {
boolean setupComplete =
requestCode == REQUEST_START_SETUP_ACTIVITY && resultCode == Activity.RESULT_OK;
// Tells EpgFetcher that channel source setup is finished.
-
+ EpgFetcher epgFetcher = TvSingletons.getSingletons(this).getEpgFetcher();
if (mEpgFetcherDuringScan) {
- mEpgFetcher.onChannelScanFinished();
+ epgFetcher.onChannelScanFinished();
}
if (!setupComplete) {
setResult(resultCode, data);
finish();
return;
}
- if (TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.isEnabled(this)
- && data != null
- && data.getBooleanExtra(EpgContract.EXTRA_USE_CLOUD_EPG, false)) {
- if (DEBUG) Log.d(TAG, "extra " + data.getExtras());
- String inputId = data.getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
- if (mEpgInputWhiteList.isInputWhiteListed(inputId)) {
- mEpgFetcher.fetchImmediately();
- }
- }
-
if (mTvInputInfo == null) {
Log.w(
TAG,
@@ -184,19 +152,21 @@ public class SetupPassthroughActivity extends Activity {
finish();
return;
}
- mSetupUtils.onTvInputSetupFinished(
- mTvInputInfo.getId(),
- () -> {
- if (mActivityAfterCompletion != null) {
- try {
- startActivity(mActivityAfterCompletion);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Activity launch failed", e);
- }
- }
- setResult(resultCode, data);
- finish();
- });
+ TvSingletons.getSingletons(this)
+ .getSetupUtils()
+ .onTvInputSetupFinished(
+ mTvInputInfo.getId(),
+ () -> {
+ if (mActivityAfterCompletion != null) {
+ try {
+ startActivity(mActivityAfterCompletion);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity launch failed", e);
+ }
+ }
+ setResult(resultCode, data);
+ finish();
+ });
}
/**
@@ -209,7 +179,7 @@ public class SetupPassthroughActivity extends Activity {
// Set timeout long enough. The message in Sony TV says the scanning takes about 30 minutes.
private static final long SCAN_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(30);
- private final EpgFetcher mEpgFetcher;
+ private final Context mContext;
private final ChannelDataManager mChannelDataManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Runnable mScanTimeoutRunnable =
@@ -237,9 +207,9 @@ public class SetupPassthroughActivity extends Activity {
};
private boolean mStarted;
- private ScanTimeoutMonitor(EpgFetcher epgFetcher, ChannelDataManager mChannelDataManager) {
- mEpgFetcher = epgFetcher;
- this.mChannelDataManager = mChannelDataManager;
+ private ScanTimeoutMonitor(Context context) {
+ mContext = context.getApplicationContext();
+ mChannelDataManager = TvSingletons.getSingletons(context).getChannelDataManager();
}
private void startMonitoring() {
@@ -267,14 +237,7 @@ public class SetupPassthroughActivity extends Activity {
private void onScanTimedOut() {
stopMonitoring();
- mEpgFetcher.onChannelScanFinished();
+ TvSingletons.getSingletons(mContext).getEpgFetcher().onChannelScanFinished();
}
}
-
- /** Exports {@link MainActivity} for Dagger codegen to create the appropriate injector. */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract SetupPassthroughActivity contributesSetupPassthroughActivity();
- }
}
diff --git a/src/com/android/tv/TimeShiftManager.java b/src/com/android/tv/TimeShiftManager.java
index f08b5e85..779e8df6 100644
--- a/src/com/android/tv/TimeShiftManager.java
+++ b/src/com/android/tv/TimeShiftManager.java
@@ -26,21 +26,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.analytics.Tracker;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.api.TunableTvViewPlayingApi.TimeShiftListener;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TimeShiftUtils;
import com.android.tv.util.Utils;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -53,7 +50,7 @@ import java.util.Queue;
import java.util.concurrent.TimeUnit;
/**
- * A class which manages the time shift feature in TV app. It consists of two parts. {@link
+ * A class which manages the time shift feature in Live TV. It consists of two parts. {@link
* PlayController} controls the playback such as play/pause, rewind and fast-forward using {@link
* TunableTvView} which communicates with TvInputService through {@link
* android.media.tv.TvInputService.Session}. {@link ProgramManager} loads programs of the current
@@ -147,8 +144,8 @@ public class TimeShiftManager {
DISABLE_ACTION_THRESHOLD + 3 * REQUEST_CURRENT_POSITION_INTERVAL;
/**
* The current position sent from TIS can not be exactly the same as the current system time due
- * to the elapsed time to pass the message from TIS to TV app. So the boundary threshold is
- * necessary. The same goes for the recording start time. It's the same {@link
+ * to the elapsed time to pass the message from TIS to Live TV. So the boundary threshold
+ * is necessary. The same goes for the recording start time. It's the same {@link
* #REQUEST_CURRENT_POSITION_INTERVAL}.
*/
private static final long RECORDING_BOUNDARY_THRESHOLD = REQUEST_CURRENT_POSITION_INTERVAL;
@@ -622,8 +619,8 @@ public class TimeShiftManager {
< mAvailablityChangedTimeMs - ALLOWED_START_TIME_OFFSET) {
Log.e(
TAG,
- "The start time is too earlier than the time of"
- + " availability: {startTime: "
+ "The start time is too earlier than the time of availability: {"
+ + "startTime: "
+ recordStartTimeMs
+ ", availability: "
+ mAvailablityChangedTimeMs);
@@ -635,9 +632,9 @@ public class TimeShiftManager {
// clock,, use system's current time instead.
Log.e(
TAG,
- "The start time should not be earlier than the current"
- + " time, reset the start time to the system's current"
- + " time: {startTime: "
+ "The start time should not be earlier than the current time, "
+ + "reset the start time to the system's current time: {"
+ + "startTime: "
+ recordStartTimeMs
+ ", current time: "
+ System.currentTimeMillis());
@@ -1106,7 +1103,7 @@ public class TimeShiftManager {
long end = Utils.ceilTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
while (end < endTimeMs) {
programs.add(
- new ProgramImpl.Builder()
+ new Program.Builder()
.setStartTimeUtcMillis(start)
.setEndTimeUtcMillis(end)
.build());
@@ -1114,7 +1111,7 @@ public class TimeShiftManager {
end += MAX_DUMMY_PROGRAM_DURATION;
}
programs.add(
- new ProgramImpl.Builder()
+ new Program.Builder()
.setStartTimeUtcMillis(start)
.setEndTimeUtcMillis(endTimeMs)
.build());
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index bc8226cf..5f25a24b 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -35,19 +35,20 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;
-
import com.android.tv.common.BaseApplication;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
+import com.android.tv.common.util.Clock;
import com.android.tv.common.util.Debug;
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.data.epg.EpgReader;
+import com.android.tv.data.epg.EpgFetcherImpl;
import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrStorageStatusManager;
@@ -55,9 +56,8 @@ import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.recorder.RecordingScheduler;
import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
import com.android.tv.features.TvFeatures;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.StartupMeasure;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManager;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.RecordedProgramPreviewUpdater;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
@@ -66,30 +66,27 @@ import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
import com.google.common.base.Optional;
-
import dagger.Lazy;
-
-import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.List;
import java.util.concurrent.Executor;
-
import javax.inject.Inject;
/**
- * TV application.
+ * Live TV application.
*
* <p>This includes all the Google specific hooks.
*/
public abstract class TvApplication extends BaseApplication implements TvSingletons, Starter {
- protected static final StartupMeasure STARTUP_MEASURE = StartupMeasureFactory.create();
+ protected static final PerformanceMonitorManager PERFORMANCE_MONITOR_MANAGER =
+ PerformanceMonitorManagerFactory.create();
private static final String TAG = "TvApplication";
private static final boolean DEBUG = false;
+ /** Namespace for LiveChannels configs. LiveChannels configs are kept in piper. */
+ public static final String CONFIGNS_P4 = "configns:p4";
+
/**
* Broadcast Action: The user has updated LC to a new version that supports tuner input. {@link
* TunerInputController} will receive this intent to check the existence of tuner input when the
@@ -105,12 +102,12 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
private SelectInputActivity mSelectInputActivity;
- @Inject Lazy<ChannelDataManager> mChannelDataManager;
+ private ChannelDataManager mChannelDataManager;
private volatile ProgramDataManager mProgramDataManager;
private PreviewDataManager mPreviewDataManager;
private DvrManager mDvrManager;
private DvrScheduleManager mDvrScheduleManager;
- @Inject Lazy<DvrDataManager> mDvrDataManager;
+ private DvrDataManager mDvrDataManager;
private DvrWatchedPositionManager mDvrWatchedPositionManager;
private RecordingScheduler mRecordingScheduler;
private RecordingStorageStatusManager mDvrStorageStatusManager;
@@ -120,16 +117,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
private Boolean mRunningInMainProcess;
@Inject Lazy<TvInputManagerHelper> mLazyTvInputManagerHelper;
private boolean mStarted;
- @Inject EpgFetcher mEpgFetcher;
+ private EpgFetcher mEpgFetcher;
@Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
@Inject SetupUtils mSetupUtils;
@Inject @DbExecutor Executor mDbExecutor;
- @Inject Lazy<EpgReader> mEpgReader;
- @Inject BuildType mBuildType;
- @Inject CloudEpgFlags mCloudEpgFlags;
- @Inject LegacyFlags mLegacyFlags;
- @Inject PerformanceMonitor mPerformanceMonitor;
@Override
public void onCreate() {
@@ -140,8 +132,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
throw new IllegalStateException(msg);
}
super.onCreate();
- mPerformanceMonitor.startMemoryMonitor();
- mPerformanceMonitor.startCrashMonitor();
SharedPreferencesUtils.initialize(
this,
() -> {
@@ -156,15 +146,16 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
Log.w(TAG, "Unable to find package '" + getPackageName() + "'.", e);
mVersionName = "";
}
- Log.i(TAG, "Starting TV app " + getVersionName());
+ Log.i(TAG, "Starting Live TV " + getVersionName());
// 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.
+ mEpgFetcher = EpgFetcherImpl.create(this);
SetupAnimationHelper.initialize(this);
getTvInputManagerHelper();
- Log.i(TAG, "Started TV app " + mVersionName);
+ Log.i(TAG, "Started Live TV " + mVersionName);
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.onCreate");
}
@@ -219,10 +210,8 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
mEpgFetcher.startRoutineService();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ChannelPreviewUpdater.getInstance(this).startRoutineService();
- if (CommonFeatures.DVR.isEnabled(this)) {
- RecordedProgramPreviewUpdater.getInstance(this)
- .updatePreviewDataForRecordedPrograms();
- }
+ RecordedProgramPreviewUpdater.getInstance(this)
+ .updatePreviewDataForRecordedPrograms();
}
}
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.start");
@@ -248,6 +237,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
}
@Override
+ public EpgFetcher getEpgFetcher() {
+ return mEpgFetcher;
+ }
+
+ @Override
public synchronized SetupUtils getSetupUtils() {
return mSetupUtils;
}
@@ -292,7 +286,16 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
/** Returns {@link ChannelDataManager}. */
@Override
public ChannelDataManager getChannelDataManager() {
- return mChannelDataManager.get();
+ if (mChannelDataManager == null) {
+ mChannelDataManager = new ChannelDataManager(this, getTvInputManagerHelper());
+ mChannelDataManager.start();
+ }
+ return mChannelDataManager;
+ }
+
+ @Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return mChannelDataManager != null && mChannelDataManager.isDbLoadFinished();
}
/** Returns {@link ProgramDataManager}. */
@@ -311,6 +314,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
return mProgramDataManager;
}
+ @Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return mProgramDataManager != null && mProgramDataManager.isCurrentProgramsLoadFinished();
+ }
+
/** Returns {@link PreviewDataManager}. */
@TargetApi(Build.VERSION_CODES.O)
@Override
@@ -326,7 +334,12 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
@TargetApi(Build.VERSION_CODES.N)
@Override
public DvrDataManager getDvrDataManager() {
- return mDvrDataManager.get();
+ if (mDvrDataManager == null) {
+ DvrDataManagerImpl dvrDataManager = new DvrDataManagerImpl(this, Clock.SYSTEM);
+ mDvrDataManager = dvrDataManager;
+ dvrDataManager.start();
+ }
+ return mDvrDataManager;
}
@Override
@@ -338,11 +351,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
return mDvrStorageStatusManager;
}
- @Override
- public PerformanceMonitor getPerformanceMonitor() {
- return mPerformanceMonitor;
- }
-
/** Returns the main activity information. */
@Override
public MainActivityWrapper getMainActivityWrapper() {
@@ -442,7 +450,7 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
}
/**
- * Returns the version name of the TV app.
+ * Returns the version name of the live channels.
*
* @see PackageInfo#versionName
*/
@@ -481,37 +489,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
Optional<String> optionalEmbeddedTunerInputId =
mOptionalBuiltInTunerManager.transform(
BuiltInTunerManager::getEmbeddedTunerInputId);
- // If there is only play movies trailer input, we don't handle input count change.
- final String playMoviesInputIdPrefix = "com.google.android.videos/";
- int tunerInputCount = 0;
- boolean hasPlayMoviesInput = false;
- for (TvInputInfo input : inputs) {
- if (calledByTunerServiceChanged
- && !tunerServiceEnabled
- && optionalEmbeddedTunerInputId.isPresent()
- && optionalEmbeddedTunerInputId.get().equals(input.getId())) {
- continue;
- }
- if (input.getType() == TvInputInfo.TYPE_TUNER) {
- if (DEBUG) Log.d(TAG, "Tuner input: " + input.getId());
- ++tunerInputCount;
- if (input.getId().startsWith(playMoviesInputIdPrefix)) {
- hasPlayMoviesInput = true;
- }
- }
- }
- if (DEBUG) {
- Log.d(
- TAG,
- "Input count: "
- + tunerInputCount
- + " hasPlayMoviesChannel: "
- + hasPlayMoviesInput);
- }
- if (tunerInputCount == 1 && hasPlayMoviesInput) {
- if (DEBUG) Log.d(TAG, "There is only play movies input");
- skipTunerInputCheck = true;
- }
// Enable the TvActivity only if there is at least one tuner type input.
if (!skipTunerInputCheck) {
for (TvInputInfo input : inputs) {
@@ -538,24 +515,13 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
if (packageManager.getComponentEnabledSetting(name) != newState) {
packageManager.setComponentEnabledSetting(
name, newState, dontKillApp ? PackageManager.DONT_KILL_APP : 0);
- Log.i(TAG, (enable ? "Un-hide" : "Hide") + " TV app.");
+ Log.i(TAG, (enable ? "Un-hide" : "Hide") + " Live TV.");
}
mSetupUtils.onInputListUpdated(inputManager);
}
@Override
- @DbExecutor
public Executor getDbExecutor() {
return mDbExecutor;
}
-
- @Override
- public Lazy<EpgReader> providesEpgReader() {
- return mEpgReader;
- }
-
- @Override
- public BuildType getBuildType() {
- return mBuildType;
- }
}
diff --git a/src/com/android/tv/TvSingletons.java b/src/com/android/tv/TvSingletons.java
index 9e4f4620..20edf3d4 100644
--- a/src/com/android/tv/TvSingletons.java
+++ b/src/com/android/tv/TvSingletons.java
@@ -17,15 +17,16 @@
package com.android.tv;
import android.content.Context;
-
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BaseApplication;
import com.android.tv.common.BaseSingletons;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.has.HasUiFlags;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -36,27 +37,14 @@ import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.tunerinputcontroller.HasBuiltInTunerManager;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-
-import dagger.Lazy;
-
+import com.android.tv.util.account.AccountHelper;
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.util.concurrent.Executor;
+import javax.inject.Provider;
/** Interface with getters for application scoped singletons. */
public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, HasUiFlags {
- /*
- * Do not add any new methods here.
- *
- * To move a getter to Injection.
- * 1. Make a type injectable @Singleton.
- * 2. Mark the getter here as deprecated.
- * 3. Lazily inject the object in TvApplication.
- * 4. Move easy usages of getters to injection instead.
- * 5. Delete the method when all usages are migrated.
- */
-
/**
* Returns the @{@link TvSingletons} using the application context.
*
@@ -74,14 +62,24 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
@Deprecated
ChannelDataManager getChannelDataManager();
+ /**
+ * Checks if the {@link ChannelDataManager} instance has been created and all the channels has
+ * been loaded.
+ */
+ boolean isChannelDataManagerLoadFinished();
+
/** @deprecated use injection instead. */
@Deprecated
ProgramDataManager getProgramDataManager();
+ /**
+ * Checks if the {@link ProgramDataManager} instance has been created and the current programs
+ * for all the channels has been loaded.
+ */
+ boolean isProgramDataManagerCurrentProgramsLoadFinished();
+
PreviewDataManager getPreviewDataManager();
- /** @deprecated use injection instead. */
- @Deprecated
DvrDataManager getDvrDataManager();
DvrScheduleManager getDvrScheduleManager();
@@ -90,8 +88,6 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
RecordingScheduler getRecordingScheduler();
- /** @deprecated use injection instead. */
- @Deprecated
DvrWatchedPositionManager getDvrWatchedPositionManager();
InputSessionManager getInputSessionManager();
@@ -100,22 +96,26 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
MainActivityWrapper getMainActivityWrapper();
+ AccountHelper getAccountHelper();
+
boolean isRunningInMainProcess();
- /** @deprecated use injection instead. */
- @Deprecated
PerformanceMonitor getPerformanceMonitor();
/** @deprecated use injection instead. */
@Deprecated
TvInputManagerHelper getTvInputManagerHelper();
- Lazy<EpgReader> providesEpgReader();
+ Provider<EpgReader> providesEpgReader();
+
+ EpgFetcher getEpgFetcher();
/** @deprecated use injection instead. */
@Deprecated
SetupUtils getSetupUtils();
+ ExperimentLoader getExperimentLoader();
+
/** @deprecated use injection instead. */
@Deprecated
Executor getDbExecutor();
diff --git a/src/com/android/tv/app/LiveTvApplication.java b/src/com/android/tv/app/LiveTvApplication.java
index 80906537..38e85e48 100644
--- a/src/com/android/tv/app/LiveTvApplication.java
+++ b/src/com/android/tv/app/LiveTvApplication.java
@@ -22,34 +22,50 @@ import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.StubAnalytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.dagger.ApplicationModule;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
+import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
import com.android.tv.common.flags.impl.DefaultUiFlags;
import com.android.tv.common.singletons.HasSingletons;
+import com.android.tv.data.epg.EpgReader;
+import com.android.tv.data.epg.StubEpgReader;
import com.android.tv.modules.TvSingletonsModule;
import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-
+import com.android.tv.util.account.AccountHelper;
+import com.android.tv.util.account.AccountHelperImpl;
import com.google.common.base.Optional;
-
import dagger.android.AndroidInjector;
-
-import javax.inject.Inject;
+import javax.inject.Provider;
/** The top level application for Live TV. */
public class LiveTvApplication extends TvApplication implements HasSingletons<TvSingletons> {
static {
- STARTUP_MEASURE.onAppClassLoaded();
+ PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppClassLoaded();
}
+ private final Provider<EpgReader> mEpgReaderProvider =
+ new Provider<EpgReader>() {
+
+ @Override
+ public EpgReader get() {
+ return new StubEpgReader(LiveTvApplication.this);
+ }
+ };
+
private final DefaultBackendKnobsFlags mBackendKnobsFlags = new DefaultBackendKnobsFlags();
private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
private final DefaultUiFlags mUiFlags = new DefaultUiFlags();
-
+ private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
+ new DefaultConcurrentDvrPlaybackFlags();
+ private AccountHelper mAccountHelper;
private Analytics mAnalytics;
private Tracker mTracker;
- @Inject PerformanceMonitor mPerformanceMonitor;
+ private ExperimentLoader mExperimentLoader;
+ private PerformanceMonitor mPerformanceMonitor;
@Override
protected AndroidInjector<LiveTvApplication> applicationInjector() {
@@ -62,15 +78,38 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
@Override
public void onCreate() {
super.onCreate();
- STARTUP_MEASURE.onAppCreate(this);
+ PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppCreate(this);
}
+ /** Returns the {@link AccountHelperImpl}. */
@Override
- public PerformanceMonitor getPerformanceMonitor() {
+ public AccountHelper getAccountHelper() {
+ if (mAccountHelper == null) {
+ mAccountHelper = new AccountHelperImpl(getApplicationContext());
+ }
+ return mAccountHelper;
+ }
+
+ @Override
+ public synchronized PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = PerformanceMonitorManagerFactory.create().initialize(this);
+ }
return mPerformanceMonitor;
}
@Override
+ public Provider<EpgReader> providesEpgReader() {
+ return mEpgReaderProvider;
+ }
+
+ @Override
+ public ExperimentLoader getExperimentLoader() {
+ mExperimentLoader = new ExperimentLoader();
+ return mExperimentLoader;
+ }
+
+ @Override
public DefaultBackendKnobsFlags getBackendKnobs() {
return mBackendKnobsFlags;
}
@@ -109,6 +148,16 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
}
@Override
+ public BuildType getBuildType() {
+ return BuildType.AOSP;
+ }
+
+ @Override
+ public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ @Override
public TvSingletons singletons() {
return this;
}
diff --git a/src/com/android/tv/app/LiveTvApplicationComponent.java b/src/com/android/tv/app/LiveTvApplicationComponent.java
index 71ce1a8a..3d3f0492 100644
--- a/src/com/android/tv/app/LiveTvApplicationComponent.java
+++ b/src/com/android/tv/app/LiveTvApplicationComponent.java
@@ -15,7 +15,6 @@
*/
package com.android.tv.app;
-import com.android.tv.search.LocalSearchProvider;
import dagger.Component;
import dagger.android.AndroidInjectionModule;
import dagger.android.AndroidInjector;
@@ -23,10 +22,5 @@ import javax.inject.Singleton;
/** Dagger component for {@link LiveTvApplication}. */
@Singleton
-@Component(
- modules = {
- AndroidInjectionModule.class,
- LiveTvModule.class,
- LocalSearchProvider.Module.class
- })
+@Component(modules = {AndroidInjectionModule.class, LiveTvModule.class})
public interface LiveTvApplicationComponent extends AndroidInjector<LiveTvApplication> {}
diff --git a/src/com/android/tv/app/LiveTvModule.java b/src/com/android/tv/app/LiveTvModule.java
index db631bc0..a28749bd 100644
--- a/src/com/android/tv/app/LiveTvModule.java
+++ b/src/com/android/tv/app/LiveTvModule.java
@@ -16,49 +16,18 @@
package com.android.tv.app;
import com.android.tv.common.flags.impl.DefaultFlagsModule;
-import com.android.tv.data.epg.EpgReader;
-import com.android.tv.data.epg.StubEpgReader;
import com.android.tv.modules.TvApplicationModule;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.stub.StubPerformanceMonitor;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
-import com.android.tv.util.account.AccountHelper;
-import com.android.tv.util.account.AccountHelperImpl;
import com.google.common.base.Optional;
import dagger.Module;
import dagger.Provides;
-import javax.inject.Singleton;
/** Dagger module for {@link LiveTvApplication}. */
@Module(includes = {DefaultFlagsModule.class, TvApplicationModule.class})
class LiveTvModule {
@Provides
- static AccountHelper providesAccountHelper(AccountHelperImpl impl) {
- return impl;
- }
-
- @Provides
- static Optional<DeveloperOptionFragment.AdditionalDeveloperItemsFactory>
- providesAdditionalDeveloperItemsFactory() {
- return Optional.absent();
- }
-
- @Provides
Optional<BuiltInTunerManager> providesBuiltInTunerManager() {
return Optional.absent();
}
-
- @Provides
- @Singleton
- PerformanceMonitor providesPerformanceMonitor() {
- return new StubPerformanceMonitor();
- }
-
- @Provides
- @Singleton
- static EpgReader providesEpgReader(StubEpgReader impl) {
- return impl;
- }
}
diff --git a/src/com/android/tv/data/BaseProgram.java b/src/com/android/tv/data/BaseProgram.java
new file mode 100644
index 00000000..9650fd18
--- /dev/null
+++ b/src/com/android/tv/data/BaseProgram.java
@@ -0,0 +1,208 @@
+/*
+ * 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.data;
+
+import android.content.Context;
+import android.media.tv.TvContentRating;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.tv.R;
+import com.google.common.collect.ImmutableList;
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * Base class for {@link com.android.tv.data.Program} and {@link
+ * com.android.tv.dvr.data.RecordedProgram}.
+ */
+public abstract class BaseProgram {
+ /**
+ * Comparator used to compare {@link BaseProgram} according to its season and episodes number.
+ * If a program's season or episode number is null, it will be consider "smaller" than programs
+ * with season or episode numbers.
+ */
+ public static final Comparator<BaseProgram> EPISODE_COMPARATOR = new EpisodeComparator(false);
+
+ /**
+ * Comparator used to compare {@link BaseProgram} according to its season and episodes number
+ * with season numbers in a reversed order. If a program's season or episode number is null, it
+ * will be consider "smaller" than programs with season or episode numbers.
+ */
+ public static final Comparator<BaseProgram> SEASON_REVERSED_EPISODE_COMPARATOR =
+ new EpisodeComparator(true);
+
+ public static final String COLUMN_SERIES_ID = "series_id";
+
+ public static final String COLUMN_STATE = "state";
+
+ private static class EpisodeComparator implements Comparator<BaseProgram> {
+ private final boolean mReversedSeason;
+
+ EpisodeComparator(boolean reversedSeason) {
+ mReversedSeason = reversedSeason;
+ }
+
+ @Override
+ public int compare(BaseProgram lhs, BaseProgram rhs) {
+ if (lhs == rhs) {
+ return 0;
+ }
+ int seasonNumberCompare = numberCompare(lhs.getSeasonNumber(), rhs.getSeasonNumber());
+ if (seasonNumberCompare != 0) {
+ return mReversedSeason ? -seasonNumberCompare : seasonNumberCompare;
+ } else {
+ return numberCompare(lhs.getEpisodeNumber(), rhs.getEpisodeNumber());
+ }
+ }
+ }
+
+ /** Compares two strings represent season numbers or episode numbers of programs. */
+ public static int numberCompare(String s1, String s2) {
+ if (Objects.equals(s1, s2)) {
+ return 0;
+ } else if (s1 == null) {
+ return -1;
+ } else if (s2 == null) {
+ return 1;
+ } else if (s1.equals(s2)) {
+ return 0;
+ }
+ try {
+ return Integer.compare(Integer.parseInt(s1), Integer.parseInt(s2));
+ } catch (NumberFormatException e) {
+ return s1.compareTo(s2);
+ }
+ }
+
+ /** Returns ID of the program. */
+ public abstract long getId();
+
+ /** Returns the title of the program. */
+ public abstract String getTitle();
+
+ /** Returns the episode title. */
+ public abstract String getEpisodeTitle();
+
+ /** Returns the displayed title of the program episode. */
+ @Nullable
+ public String getEpisodeDisplayTitle(Context context) {
+ String episodeNumber = getEpisodeNumber();
+ String episodeTitle = getEpisodeTitle();
+ if (!TextUtils.isEmpty(episodeNumber)) {
+ episodeTitle = episodeTitle == null ? "" : episodeTitle;
+ String seasonNumber = getSeasonNumber();
+ if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
+ // Do not show "S0: ".
+ return context.getResources()
+ .getString(
+ R.string.display_episode_title_format_no_season_number,
+ episodeNumber,
+ episodeTitle);
+ } else {
+ return context.getResources()
+ .getString(
+ R.string.display_episode_title_format,
+ seasonNumber,
+ episodeNumber,
+ episodeTitle);
+ }
+ }
+ return episodeTitle;
+ }
+
+ /**
+ * Returns the content description of the program episode, suitable for being spoken by an
+ * accessibility service.
+ */
+ public String getEpisodeContentDescription(Context context) {
+ String episodeNumber = getEpisodeNumber();
+ String episodeTitle = getEpisodeTitle();
+ if (!TextUtils.isEmpty(episodeNumber)) {
+ episodeTitle = episodeTitle == null ? "" : episodeTitle;
+ String seasonNumber = getSeasonNumber();
+ if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
+ // Do not list season if it is empty or 0
+ return context.getResources()
+ .getString(
+ R.string.content_description_episode_format_no_season_number,
+ episodeNumber,
+ episodeTitle);
+ } else {
+ return context.getResources()
+ .getString(
+ R.string.content_description_episode_format,
+ seasonNumber,
+ episodeNumber,
+ episodeTitle);
+ }
+ }
+ return episodeTitle;
+ }
+
+ /** Returns the description of the program. */
+ public abstract String getDescription();
+
+ /** Returns the long description of the program. */
+ public abstract String getLongDescription();
+
+ /** Returns the start time of the program in Milliseconds. */
+ public abstract long getStartTimeUtcMillis();
+
+ /** Returns the end time of the program in Milliseconds. */
+ public abstract long getEndTimeUtcMillis();
+
+ /** Returns the duration of the program in Milliseconds. */
+ public abstract long getDurationMillis();
+
+ /** Returns the series ID. */
+ @Nullable
+ public abstract String getSeriesId();
+
+ /** Returns the season number. */
+ public abstract String getSeasonNumber();
+
+ /** Returns the episode number. */
+ public abstract String getEpisodeNumber();
+
+ /** Returns URI of the program's poster. */
+ public abstract String getPosterArtUri();
+
+ /** Returns URI of the program's thumbnail. */
+ public abstract String getThumbnailUri();
+
+ /** Returns the array of the ID's of the canonical genres. */
+ public abstract int[] getCanonicalGenreIds();
+
+ /** Returns the array of content ratings. */
+ public abstract ImmutableList<TvContentRating> getContentRatings();
+
+ /** Returns channel's ID of the program. */
+ public abstract long getChannelId();
+
+ /** Returns if the program is valid. */
+ public abstract boolean isValid();
+
+ /** Checks whether the program is episodic or not. */
+ public boolean isEpisodic() {
+ return getSeriesId() != null;
+ }
+
+ /** Generates the series ID for the other inputs than the tuner TV input. */
+ public static String generateSeriesId(String packageName, String title) {
+ return packageName + "/" + title;
+ }
+}
diff --git a/src/com/android/tv/data/BaseProgramImpl.java b/src/com/android/tv/data/BaseProgramImpl.java
deleted file mode 100644
index 9c8d0256..00000000
--- a/src/com/android/tv/data/BaseProgramImpl.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.data;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.data.api.BaseProgram;
-
-/** Base class for {@link ProgramImpl} and {@link com.android.tv.dvr.data.RecordedProgram}. */
-public abstract class BaseProgramImpl implements BaseProgram {
-
- @Override
- @Nullable
- public String getEpisodeDisplayTitle(Context context) {
- String episodeNumber = getEpisodeNumber();
- String episodeTitle = getEpisodeTitle();
- if (!TextUtils.isEmpty(episodeNumber)) {
- episodeTitle = episodeTitle == null ? "" : episodeTitle;
- String seasonNumber = getSeasonNumber();
- if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
- // Do not show "S0: ".
- return context.getResources()
- .getString(
- R.string.display_episode_title_format_no_season_number,
- episodeNumber,
- episodeTitle);
- } else {
- return context.getResources()
- .getString(
- R.string.display_episode_title_format,
- seasonNumber,
- episodeNumber,
- episodeTitle);
- }
- }
- return episodeTitle;
- }
-
- @Override
- public String getEpisodeContentDescription(Context context) {
- String episodeNumber = getEpisodeNumber();
- String episodeTitle = getEpisodeTitle();
- if (!TextUtils.isEmpty(episodeNumber)) {
- episodeTitle = episodeTitle == null ? "" : episodeTitle;
- String seasonNumber = getSeasonNumber();
- if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
- // Do not list season if it is empty or 0
- return context.getResources()
- .getString(
- R.string.content_description_episode_format_no_season_number,
- episodeNumber,
- episodeTitle);
- } else {
- return context.getResources()
- .getString(
- R.string.content_description_episode_format,
- seasonNumber,
- episodeNumber,
- episodeTitle);
- }
- }
- return episodeTitle;
- }
-
- @Override
- public boolean isEpisodic() {
- return !TextUtils.isEmpty(getSeriesId());
- }
-}
diff --git a/src/com/android/tv/data/ChannelDataManager.java b/src/com/android/tv/data/ChannelDataManager.java
index 67c32309..a5c786cf 100644
--- a/src/com/android/tv/data/ChannelDataManager.java
+++ b/src/com/android/tv/data/ChannelDataManager.java
@@ -37,18 +37,15 @@ import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
import android.util.MutableInt;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.data.api.Channel;
import com.android.tv.util.AsyncDbTask;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
@@ -59,7 +56,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
-import javax.inject.Singleton;
/**
* The class to manage channel data. Basic features: reading channel list and each channel's current
@@ -68,8 +64,6 @@ import javax.inject.Singleton;
* methods are called in only the main thread.
*/
@AnyThread
-@AutoFactory
-@Singleton
public class ChannelDataManager {
private static final String TAG = "ChannelDataManager";
private static final boolean DEBUG = false;
@@ -149,11 +143,21 @@ public class ChannelDataManager {
};
@MainThread
- public ChannelDataManager(
- @Provided @ApplicationContext Context context,
- @Provided TvInputManagerHelper inputManager,
- @Provided @DbExecutor Executor executor,
- @Provided ContentResolver contentResolver) {
+ public ChannelDataManager(Context context, TvInputManagerHelper inputManager) {
+ this(
+ context,
+ inputManager,
+ TvSingletons.getSingletons(context).getDbExecutor(),
+ context.getContentResolver());
+ }
+
+ @MainThread
+ @VisibleForTesting
+ ChannelDataManager(
+ Context context,
+ TvInputManagerHelper inputManager,
+ Executor executor,
+ ContentResolver contentResolver) {
mContext = context;
mInputManager = inputManager;
mDbExecutor = executor;
@@ -725,7 +729,7 @@ public class ChannelDataManager {
/**
* Updates a column {@code columnName} of DB table {@code uri} with the value {@code
* columnValue}. The selective rows in the ID list {@code ids} will be updated. The DB
- * operations will run on @{@link DbExecutor}.
+ * operations will run on {@link TvSingletons#getDbExecutor()}.
*/
private void updateOneColumnValue(
final String columnName, final int columnValue, final List<Long> ids) {
diff --git a/src/com/android/tv/data/InternalDataUtils.java b/src/com/android/tv/data/InternalDataUtils.java
index b17ed092..4c30d395 100644
--- a/src/com/android/tv/data/InternalDataUtils.java
+++ b/src/com/android/tv/data/InternalDataUtils.java
@@ -19,11 +19,8 @@ package com.android.tv.data;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-
-import com.android.tv.data.api.Program;
-import com.android.tv.data.api.Program.CriticScore;
+import com.android.tv.data.Program.CriticScore;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -52,7 +49,7 @@ public final class InternalDataUtils {
* @param bytes the bytes to be deserialized
* @param builder the builder for the Program class
*/
- public static void deserializeInternalProviderData(byte[] bytes, ProgramImpl.Builder builder) {
+ public static void deserializeInternalProviderData(byte[] bytes, Program.Builder builder) {
if (bytes == null || bytes.length == 0) {
return;
}
diff --git a/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java b/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
index 2332cda4..edb33556 100644
--- a/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
+++ b/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
@@ -16,8 +16,6 @@
package com.android.tv.data;
-import com.android.tv.data.api.Program;
-
public interface OnCurrentProgramUpdatedListener {
/** Called when the current program is updated. */
void onCurrentProgramUpdated(long channelId, Program program);
diff --git a/src/com/android/tv/data/PreviewDataManager.java b/src/com/android/tv/data/PreviewDataManager.java
index dbe6028c..8616aeec 100644
--- a/src/com/android/tv/data/PreviewDataManager.java
+++ b/src/com/android/tv/data/PreviewDataManager.java
@@ -32,14 +32,10 @@ import android.support.annotation.IntDef;
import android.support.annotation.MainThread;
import android.util.Log;
import android.util.Pair;
-
import androidx.tvprovider.media.tv.ChannelLogoUtils;
import androidx.tvprovider.media.tv.PreviewProgram;
-
import com.android.tv.R;
import com.android.tv.common.util.PermissionUtils;
-import com.android.tv.util.images.ImageLoader;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
@@ -222,7 +218,7 @@ public class PreviewDataManager {
Uri previewChannelsUri =
PreviewDataUtils.addQueryParamToUri(
TvContract.Channels.CONTENT_URI,
- Pair.create(PARAM_PREVIEW, String.valueOf(true)));
+ new Pair<>(PARAM_PREVIEW, String.valueOf(true)));
String packageName = mContext.getPackageName();
if (PermissionUtils.hasAccessAllEpg(mContext)) {
try (Cursor cursor =
@@ -432,14 +428,10 @@ public class PreviewDataManager {
continue;
}
try {
- int aspectRatio =
- ImageLoader.getAspectRatioFromPosterArtUri(
- mContext, program.getPosterArtUri().toString());
Uri programUri =
mContentResolver.insert(
TvContract.PreviewPrograms.CONTENT_URI,
- PreviewDataUtils.createPreviewProgramFromContent(
- program, aspectRatio)
+ PreviewDataUtils.createPreviewProgramFromContent(program)
.toContentValues());
if (programUri != null) {
long previewProgramId = ContentUris.parseId(programUri);
@@ -600,14 +592,13 @@ public class PreviewDataManager {
/** Creates a preview program. */
public static PreviewProgram createPreviewProgramFromContent(
- PreviewProgramContent program, int aspectRatio) {
+ PreviewProgramContent program) {
PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(program.getPreviewChannelId())
.setType(program.getType())
.setLive(program.getLive())
.setTitle(program.getTitle())
.setDescription(program.getDescription())
- .setPosterArtAspectRatio(aspectRatio)
.setPosterArtUri(program.getPosterArtUri())
.setIntentUri(program.getIntentUri())
.setPreviewVideoUri(program.getPreviewVideoUri())
diff --git a/src/com/android/tv/data/PreviewProgramContent.java b/src/com/android/tv/data/PreviewProgramContent.java
index 4ee57104..8d4b88cf 100644
--- a/src/com/android/tv/data/PreviewProgramContent.java
+++ b/src/com/android/tv/data/PreviewProgramContent.java
@@ -21,14 +21,10 @@ import android.net.Uri;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Pair;
-
import androidx.tvprovider.media.tv.TvContractCompat;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.util.Objects;
/** A class to store the content of preview programs. */
@@ -45,7 +41,7 @@ public class PreviewProgramContent {
private Uri mIntentUri;
private Uri mPreviewVideoUri;
- /** Create preview program content from {@link ProgramImpl} */
+ /** Create preview program content from {@link Program} */
public static PreviewProgramContent createFromProgram(
Context context, long previewChannelId, Program program) {
Channel channel =
@@ -83,7 +79,7 @@ public class PreviewProgramContent {
.setIntentUri(channel.getUri())
.setPreviewVideoUri(
PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
- channel.getUri(), Pair.create(PARAM_INPUT, channel.getInputId())))
+ channel.getUri(), new Pair<>(PARAM_INPUT, channel.getInputId())))
.build();
}
@@ -103,7 +99,7 @@ public class PreviewProgramContent {
.setPreviewVideoUri(
PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
recordedProgramUri,
- Pair.create(PARAM_INPUT, recordedProgram.getInputId())))
+ new Pair<>(PARAM_INPUT, recordedProgram.getInputId())))
.build();
}
diff --git a/src/com/android/tv/data/ProgramImpl.java b/src/com/android/tv/data/Program.java
index 5097e2d4..b688927a 100644
--- a/src/com/android/tv/data/ProgramImpl.java
+++ b/src/com/android/tv/data/Program.java
@@ -32,26 +32,24 @@ import android.support.annotation.UiThread;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
-
+import android.util.Log;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.util.CollectionUtils;
import com.android.tv.common.util.CommonUtils;
-import com.android.tv.data.api.BaseProgram;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvProviderUtils;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
-
import com.google.common.collect.ImmutableList;
-
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/** A convenience class to create and insert program information entries into the database. */
-public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Program {
+public final class Program extends BaseProgram implements Comparable<Program>, Parcelable {
private static final boolean DEBUG = false;
private static final boolean DEBUG_DUMP_DESCRIPTION = false;
private static final String TAG = "Program";
@@ -181,8 +179,8 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return builder.build();
}
- public static ProgramImpl fromParcel(Parcel in) {
- ProgramImpl program = new ProgramImpl();
+ public static Program fromParcel(Parcel in) {
+ Program program = new Program();
program.mId = in.readLong();
program.mPackageName = in.readString();
program.mChannelId = in.readLong();
@@ -221,7 +219,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
new Parcelable.Creator<Program>() {
@Override
public Program createFromParcel(Parcel in) {
- return ProgramImpl.fromParcel(in);
+ return Program.fromParcel(in);
}
@Override
@@ -253,21 +251,19 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
private ImmutableList<TvContentRating> mContentRatings;
private boolean mRecordingProhibited;
- private ProgramImpl() {
+ private Program() {
// Do nothing.
}
- @Override
public long getId() {
return mId;
}
- @Override
+ /** Returns the package name of this program. */
public String getPackageName() {
return mPackageName;
}
- @Override
public long getChannelId() {
return mChannelId;
}
@@ -278,6 +274,11 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mChannelId >= 0;
}
+ /** Returns {@code true} if the program is valid and {@code false} otherwise. */
+ public static boolean isProgramValid(Program program) {
+ return program != null && program.isValid();
+ }
+
@Override
public String getTitle() {
return mTitle;
@@ -301,11 +302,6 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
@Override
- public String getSeasonTitle() {
- return mSeasonTitle;
- }
-
- @Override
public String getEpisodeNumber() {
return mEpisodeNumber;
}
@@ -320,7 +316,6 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mEndTimeUtcMillis;
}
- @Override
public String getDurationString(Context context) {
// TODO(b/71717446): expire the calculated string
if (mDurationString == null) {
@@ -346,17 +341,15 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mLongDescription;
}
- @Override
public int getVideoWidth() {
return mVideoWidth;
}
- @Override
public int getVideoHeight() {
return mVideoHeight;
}
- @Override
+ /** Returns the list of Critic Scores for this program */
@Nullable
public List<CriticScore> getCriticScores() {
return mCriticScores;
@@ -378,12 +371,12 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mThumbnailUri;
}
- @Override
+ /** Returns {@code true} if the recording of this program is prohibited. */
public boolean isRecordingProhibited() {
return mRecordingProhibited;
}
- @Override
+ /** Returns array of canonical genres for this program. This is expected to be called rarely. */
@Nullable
public String[] getCanonicalGenres() {
if (mCanonicalGenreIds == null) {
@@ -402,7 +395,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mCanonicalGenreIds;
}
- @Override
+ /** Returns if this program has the genre. */
public boolean hasGenre(int genreId) {
if (genreId == GenreItems.ID_ALL_CHANNELS) {
return true;
@@ -443,11 +436,11 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
@Override
public boolean equals(Object other) {
- if (!(other instanceof ProgramImpl)) {
+ if (!(other instanceof Program)) {
return false;
}
// Compare all the properties because program ID can be invalid for the dummy programs.
- ProgramImpl program = (ProgramImpl) other;
+ Program program = (Program) other;
return Objects.equals(mPackageName, program.mPackageName)
&& mChannelId == program.mChannelId
&& mStartTimeUtcMillis == program.mStartTimeUtcMillis
@@ -471,7 +464,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
@Override
public int compareTo(@NonNull Program other) {
- return Long.compare(mStartTimeUtcMillis, other.getStartTimeUtcMillis());
+ return Long.compare(mStartTimeUtcMillis, other.mStartTimeUtcMillis);
}
@Override
@@ -523,7 +516,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
/**
- * Translates a {@link ProgramImpl} to {@link ContentValues} that are ready to be written into
+ * Translates a {@link Program} to {@link ContentValues} that are ready to be written into
* Database.
*/
@SuppressLint("InlinedApi")
@@ -602,37 +595,37 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return;
}
- mId = other.getId();
- mPackageName = other.getPackageName();
- mChannelId = other.getChannelId();
- mTitle = other.getTitle();
- mSeriesId = other.getSeriesId();
- mEpisodeTitle = other.getEpisodeTitle();
- mSeasonNumber = other.getSeasonNumber();
- mSeasonTitle = other.getSeasonTitle();
- mEpisodeNumber = other.getEpisodeNumber();
- mStartTimeUtcMillis = other.getStartTimeUtcMillis();
- mEndTimeUtcMillis = other.getEndTimeUtcMillis();
+ mId = other.mId;
+ mPackageName = other.mPackageName;
+ mChannelId = other.mChannelId;
+ mTitle = other.mTitle;
+ mSeriesId = other.mSeriesId;
+ mEpisodeTitle = other.mEpisodeTitle;
+ mSeasonNumber = other.mSeasonNumber;
+ mSeasonTitle = other.mSeasonTitle;
+ mEpisodeNumber = other.mEpisodeNumber;
+ mStartTimeUtcMillis = other.mStartTimeUtcMillis;
+ mEndTimeUtcMillis = other.mEndTimeUtcMillis;
mDurationString = null; // Recreate Duration when needed.
- mDescription = other.getDescription();
- mLongDescription = other.getLongDescription();
- mVideoWidth = other.getVideoWidth();
- mVideoHeight = other.getVideoHeight();
- mCriticScores = other.getCriticScores();
- mPosterArtUri = other.getPosterArtUri();
- mThumbnailUri = other.getThumbnailUri();
- mCanonicalGenreIds = other.getCanonicalGenreIds();
- mContentRatings = other.getContentRatings();
- mRecordingProhibited = other.isRecordingProhibited();
+ mDescription = other.mDescription;
+ mLongDescription = other.mLongDescription;
+ mVideoWidth = other.mVideoWidth;
+ mVideoHeight = other.mVideoHeight;
+ mCriticScores = other.mCriticScores;
+ mPosterArtUri = other.mPosterArtUri;
+ mThumbnailUri = other.mThumbnailUri;
+ mCanonicalGenreIds = other.mCanonicalGenreIds;
+ mContentRatings = other.mContentRatings;
+ mRecordingProhibited = other.mRecordingProhibited;
}
/** A Builder for the Program class */
public static final class Builder {
- private final ProgramImpl mProgram;
+ private final Program mProgram;
/** Creates a Builder for this Program class */
public Builder() {
- mProgram = new ProgramImpl();
+ mProgram = new Program();
// Fill initial data.
mProgram.mPackageName = null;
mProgram.mChannelId = Channel.INVALID_ID;
@@ -657,7 +650,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
*/
@VisibleForTesting
public Builder(Program other) {
- mProgram = new ProgramImpl();
+ mProgram = new Program();
mProgram.copyFrom(other);
}
@@ -913,7 +906,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
*
* @return the Program object constructed
*/
- public ProgramImpl build() {
+ public Program build() {
// Generate the series ID for the episodic program of other TV input.
if (TextUtils.isEmpty(mProgram.mTitle)) {
// If title is null, series cannot be generated for this program.
@@ -923,13 +916,17 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
// If series ID is not set, generate it for the episodic program of other TV input.
setSeriesId(BaseProgram.generateSeriesId(mProgram.mPackageName, mProgram.mTitle));
}
- ProgramImpl program = new ProgramImpl();
+ Program program = new Program();
program.copyFrom(mProgram);
return program;
}
}
- @Override
+ /**
+ * Prefetches the program poster art.
+ *
+ * <p>
+ */
public void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight) {
if (mPosterArtUri == null) {
return;
@@ -937,13 +934,20 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
ImageLoader.prefetchBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight);
}
- @Override
+ /**
+ * Loads the program poster art and returns it via {@code callback}.
+ *
+ * <p>Note that it may directly call {@code callback} if the program poster art already is
+ * loaded.
+ *
+ * @return {@code true} if the load is complete and the callback is executed.
+ */
@UiThread
public boolean loadPosterArt(
Context context,
int posterArtWidth,
int posterArtHeight,
- ImageLoader.ImageLoaderCallback<?> callback) {
+ ImageLoader.ImageLoaderCallback callback) {
if (mPosterArtUri == null) {
return false;
}
@@ -951,9 +955,24 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
}
- @Override
- public Parcelable toParcelable() {
- return this;
+ 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 (DEBUG && BuildConfig.ENG && isDuplicate) {
+ Log.w(
+ TAG,
+ "Duplicate programs detected! - \""
+ + p1.getTitle()
+ + "\" and \""
+ + p2.getTitle()
+ + "\"");
+ }
+ return isDuplicate;
}
@Override
@@ -990,4 +1009,54 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
out.writeByte((byte) (mRecordingProhibited ? 1 : 0));
}
+
+ /** Holds one type of critic score and its source. */
+ public static final class CriticScore implements Serializable, Parcelable {
+ /** The source of the rating. */
+ public final String source;
+ /** The score. */
+ public final String score;
+ /** The url of the logo image */
+ public final String logoUrl;
+
+ public static final Parcelable.Creator<CriticScore> CREATOR =
+ new Parcelable.Creator<CriticScore>() {
+ @Override
+ public CriticScore createFromParcel(Parcel in) {
+ String source = in.readString();
+ String score = in.readString();
+ String logoUri = in.readString();
+ return new CriticScore(source, score, logoUri);
+ }
+
+ @Override
+ public CriticScore[] newArray(int size) {
+ return new CriticScore[size];
+ }
+ };
+
+ /**
+ * Constructor for this class.
+ *
+ * @param source the source of the rating
+ * @param score the score
+ */
+ public CriticScore(String source, String score, String logoUrl) {
+ this.source = source;
+ this.score = score;
+ this.logoUrl = logoUrl;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int i) {
+ out.writeString(source);
+ out.writeString(score);
+ out.writeString(logoUrl);
+ }
+ }
}
diff --git a/src/com/android/tv/data/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index a866c78e..2f20c89a 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -33,24 +33,19 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.LruCache;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.memory.MemoryManageable;
import com.android.tv.common.util.Clock;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.MultiLongSparseArray;
-import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvProviderUtils;
import com.android.tv.util.Utils;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -80,11 +75,6 @@ public class ProgramDataManager implements MemoryManageable {
private static final long CURRENT_PROGRAM_UPDATE_WAIT_MS = TimeUnit.SECONDS.toMillis(5);
@VisibleForTesting static final long PROGRAM_GUIDE_SNAP_TIME_MS = TimeUnit.MINUTES.toMillis(30);
- // Default fetch hours
- private static final long FETCH_HOURS_MS = TimeUnit.HOURS.toMillis(24);
- // Load data earlier for smooth scrolling.
- private static final long BUFFER_HOURS_MS = TimeUnit.HOURS.toMillis(6);
-
// TODO: Use TvContract constants, once they become public.
private static final String PARAM_START_TIME = "start_time";
private static final String PARAM_END_TIME = "end_time";
@@ -96,20 +86,10 @@ public class ProgramDataManager implements MemoryManageable {
+ Programs.COLUMN_CHANNEL_ID
+ ", "
+ Programs.COLUMN_END_TIME_UTC_MILLIS;
- private static final String SORT_BY_CHANNEL_ID =
- Programs.COLUMN_CHANNEL_ID
- + ", "
- + Programs.COLUMN_START_TIME_UTC_MILLIS
- + " DESC, "
- + Programs.COLUMN_END_TIME_UTC_MILLIS
- + " ASC, "
- + Programs._ID
- + " DESC";
private static final int MSG_UPDATE_CURRENT_PROGRAMS = 1000;
private static final int MSG_UPDATE_ONE_CURRENT_PROGRAM = 1001;
private static final int MSG_UPDATE_PREFETCH_PROGRAM = 1002;
- private static final int MSG_UPDATE_CONTENT_RATINGS = 1003;
private final Context mContext;
private final Clock mClock;
@@ -118,7 +98,6 @@ public class ProgramDataManager implements MemoryManageable {
private final BackendKnobsFlags mBackendKnobsFlags;
private final PerformanceMonitor mPerformanceMonitor;
private final ChannelDataManager mChannelDataManager;
- private final TvInputManagerHelper mTvInputManagerHelper;
private boolean mStarted;
// Updated only on the main thread.
private volatile boolean mCurrentProgramsLoadFinished;
@@ -146,11 +125,6 @@ public class ProgramDataManager implements MemoryManageable {
private boolean mPauseProgramUpdate = false;
private final LruCache<Long, Program> mZeroLengthProgramCache = new LruCache<>(10);
- // Current tuned channel.
- private long mTunedChannelId;
- // Hours of data to be fetched, it is updated during horizontal scroll.
- // Note that it should never exceed programGuideMaxHours.
- private long mMaxFetchHoursMs = FETCH_HOURS_MS;
@MainThread
public ProgramDataManager(Context context) {
@@ -162,8 +136,7 @@ public class ProgramDataManager implements MemoryManageable {
Looper.myLooper(),
TvSingletons.getSingletons(context).getBackendKnobs(),
TvSingletons.getSingletons(context).getPerformanceMonitor(),
- TvSingletons.getSingletons(context).getChannelDataManager(),
- TvSingletons.getSingletons(context).getTvInputManagerHelper());
+ TvSingletons.getSingletons(context).getChannelDataManager());
}
@VisibleForTesting
@@ -175,8 +148,7 @@ public class ProgramDataManager implements MemoryManageable {
Looper looper,
BackendKnobsFlags backendKnobsFlags,
PerformanceMonitor performanceMonitor,
- ChannelDataManager channelDataManager,
- TvInputManagerHelper tvInputManagerHelper) {
+ ChannelDataManager channelDataManager) {
mContext = context;
mDbExecutor = executor;
mClock = time;
@@ -185,7 +157,6 @@ public class ProgramDataManager implements MemoryManageable {
mBackendKnobsFlags = backendKnobsFlags;
mPerformanceMonitor = performanceMonitor;
mChannelDataManager = channelDataManager;
- mTvInputManagerHelper = tvInputManagerHelper;
mProgramObserver =
new ContentObserver(mHandler) {
@Override
@@ -234,7 +205,6 @@ public class ProgramDataManager implements MemoryManageable {
// Should be called directly instead of posting MSG_UPDATE_CURRENT_PROGRAMS message
// to the handler. If not, another DB task can be executed before loading current programs.
handleUpdateCurrentPrograms();
- mHandler.sendEmptyMessage(MSG_UPDATE_CONTENT_RATINGS);
if (mPrefetchEnabled) {
mHandler.sendEmptyMessage(MSG_UPDATE_PREFETCH_PROGRAM);
}
@@ -289,67 +259,15 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- /**
- * Prefetch program data if needed.
- *
- * @param channelId ID of the channel to prefetch
- * @param selectedProgramIndex index of selected program.
- */
- public void prefetchChannel(long channelId, int selectedProgramIndex) {
- long startTimeMs =
- Utils.floorTime(
- mClock.currentTimeMillis() - PROGRAM_GUIDE_SNAP_TIME_MS,
- PROGRAM_GUIDE_SNAP_TIME_MS);
- long programGuideMaxHoursMs =
- TimeUnit.HOURS.toMillis(mBackendKnobsFlags.programGuideMaxHours());
- long endTimeMs = 0;
- if (mMaxFetchHoursMs < programGuideMaxHoursMs
- && isHorizontalLoadNeeded(startTimeMs, channelId, selectedProgramIndex)) {
- // Horizontal scrolling needs to load data of further days.
- mMaxFetchHoursMs = Math.min(programGuideMaxHoursMs, mMaxFetchHoursMs + FETCH_HOURS_MS);
- mCompleteInfoChannelIds.clear();
- }
- // Load max hours complete data for first channel.
- if (mCompleteInfoChannelIds.isEmpty()) {
- endTimeMs = startTimeMs + programGuideMaxHoursMs;
- } else if (!mCompleteInfoChannelIds.contains(channelId)) {
- endTimeMs = startTimeMs + mMaxFetchHoursMs;
- }
- if (endTimeMs > 0) {
- mCompleteInfoChannelIds.add(channelId);
- new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs).executeOnDbThread();
- }
- }
-
public void prefetchChannel(long channelId) {
- prefetchChannel(channelId, 0);
- }
-
- /**
- * Check if enough data is present for horizontal scroll, otherwise prefetch programs.
- *
- * <p>If end time of current program is past {@code BUFFER_HOURS_MS} less than the fetched time
- * we need to prefetch proceeding programs.
- *
- * @param startTimeMs Fetch start time, it is used to get fetch end time.
- * @param channelId
- * @param selectedProgramIndex
- * @return {@code true} If data load is needed, else {@code false}.
- */
- private boolean isHorizontalLoadNeeded(
- long startTimeMs, long channelId, int selectedProgramIndex) {
- if (mChannelIdProgramCache.containsKey(channelId)) {
- ArrayList<Program> programs = mChannelIdProgramCache.get(channelId);
- long marginEndTime = startTimeMs + mMaxFetchHoursMs - BUFFER_HOURS_MS;
- return programs.size() > selectedProgramIndex &&
- programs.get(selectedProgramIndex).getEndTimeUtcMillis() > marginEndTime;
+ if (mCompleteInfoChannelIds.add(channelId)) {
+ long startTimeMs =
+ Utils.floorTime(
+ mClock.currentTimeMillis() - PROGRAM_GUIDE_SNAP_TIME_MS,
+ PROGRAM_GUIDE_SNAP_TIME_MS);
+ long endTimeMs = startTimeMs + TimeUnit.HOURS.toMillis(getFetchDuration());
+ new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs).executeOnDbThread();
}
- return false;
- }
-
- public void onChannelTuned(long channelId) {
- mTunedChannelId = channelId;
- prefetchChannel(channelId);
}
/** A Callback interface to receive notification on program data retrieval from DB. */
@@ -362,10 +280,12 @@ public class ProgramDataManager implements MemoryManageable {
void onProgramUpdated();
/**
- * Called when we update program data during scrolling. Data is loaded from DB on request
- * basis. It loads data based on horizontal scrolling as well.
+ * Called when we update complete program data of specific channel during scrolling. Data is
+ * loaded from DB on request basis.
+ *
+ * @param channelId
*/
- void onChannelUpdated();
+ void onSingleChannelUpdated(long channelId);
}
/** Adds the {@link Callback}. */
@@ -392,7 +312,7 @@ public class ProgramDataManager implements MemoryManageable {
} else {
mPrefetchEnabled = false;
cancelPrefetchTask();
- clearChannelInfoMap();
+ mChannelIdProgramCache.clear();
mHandler.removeMessages(MSG_UPDATE_PREFETCH_PROGRAM);
}
}
@@ -619,7 +539,10 @@ public class ProgramDataManager implements MemoryManageable {
}
programMap.clear();
- String[] projection = ProgramImpl.PARTIAL_PROJECTION;
+ String[] projection =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.PARTIAL_PROJECTION
+ : Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(mContext, Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
projection =
@@ -639,7 +562,10 @@ public class ProgramDataManager implements MemoryManageable {
}
return null;
}
- Program program = ProgramImpl.fromCursorPartialProjection(c);
+ Program program =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.fromCursorPartialProjection(c)
+ : Program.fromCursor(c);
if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
@@ -649,14 +575,15 @@ public class ProgramDataManager implements MemoryManageable {
ArrayList<Program> programs = programMap.get(program.getChannelId());
if (programs == null) {
programs = new ArrayList<>();
- // To skip already loaded complete data.
- Program currentProgramInfo =
- mChannelIdCurrentProgramMap.get(program.getChannelId());
- if (currentProgramInfo != null
- && Program.isDuplicate(program, currentProgramInfo)) {
- program = currentProgramInfo;
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ // To skip already loaded complete data.
+ Program currentProgramInfo =
+ mChannelIdCurrentProgramMap.get(program.getChannelId());
+ if (currentProgramInfo != null
+ && Program.isDuplicate(program, currentProgramInfo)) {
+ program = currentProgramInfo;
+ }
}
-
programMap.put(program.getChannelId(), programs);
}
programs.add(program);
@@ -701,12 +628,15 @@ public class ProgramDataManager implements MemoryManageable {
mLastPrefetchTaskRunMs + PROGRAM_GUIDE_SNAP_TIME_MS,
PROGRAM_GUIDE_SNAP_TIME_MS)
- currentTime;
+ // Issue second pre-fetch immediately after the first partial update
+ if (mChannelIdProgramCache.isEmpty()) {
+ nextMessageDelayedTime = 0;
+ }
mChannelIdProgramCache = programs;
- // Since cache has partial data we need to reset the map of complete data.
- clearChannelInfoMap();
- // Get complete projection of tuned channel.
- prefetchChannel(mTunedChannelId);
-
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ // Since cache has partial data we need to reset the map of complete data.
+ mCompleteInfoChannelIds.clear();
+ }
notifyProgramUpdated();
if (mFromEmptyCacheTimeEvent != null) {
mPerformanceMonitor.stopTimer(
@@ -724,11 +654,6 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- private void clearChannelInfoMap() {
- mCompleteInfoChannelIds.clear();
- mMaxFetchHoursMs = FETCH_HOURS_MS;
- }
-
private long getFetchDuration() {
if (mChannelIdProgramCache.isEmpty()) {
return Math.max(1L, mBackendKnobsFlags.programGuideInitialFetchHours());
@@ -760,7 +685,7 @@ public class ProgramDataManager implements MemoryManageable {
mDbExecutor,
mContext,
TvContract.buildProgramsUriForChannel(channelId, startTimeMs, endTimeMs),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
SORT_BY_TIME);
@@ -771,7 +696,7 @@ public class ProgramDataManager implements MemoryManageable {
protected ArrayList<Program> onQuery(Cursor c) {
ArrayList<Program> programMap = new ArrayList<>();
while (c.moveToNext()) {
- Program program = ProgramImpl.fromCursor(c);
+ Program program = Program.fromCursor(c);
programMap.add(program);
}
return programMap;
@@ -780,7 +705,7 @@ public class ProgramDataManager implements MemoryManageable {
@Override
protected void onPostExecute(ArrayList<Program> programs) {
mChannelIdProgramCache.put(mChannelId, programs);
- notifyChannelUpdated();
+ notifySingleChannelUpdated(mChannelId);
}
}
@@ -790,9 +715,9 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- private void notifyChannelUpdated() {
+ private void notifySingleChannelUpdated(long channelId) {
for (Callback callback : mCallbacks) {
- callback.onChannelUpdated();
+ callback.onSingleChannelUpdated(channelId);
}
}
@@ -806,10 +731,10 @@ public class ProgramDataManager implements MemoryManageable {
.appendQueryParameter(PARAM_START_TIME, String.valueOf(time))
.appendQueryParameter(PARAM_END_TIME, String.valueOf(time))
.build(),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
- SORT_BY_CHANNEL_ID);
+ SORT_BY_TIME);
}
@Override
@@ -822,21 +747,17 @@ public class ProgramDataManager implements MemoryManageable {
if (isCancelled()) {
return programs;
}
- Program program = ProgramImpl.fromCursor(c);
- // Only one program is expected per channel for this query
- // However, skip overlapping programs from same channel
- if (Program.sameChannel(program, lastReadProgram)
- && Program.isOverlapping(program, lastReadProgram)) {
+ Program program = Program.fromCursor(c);
+ if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
} else {
lastReadProgram = program;
}
-
programs.add(program);
}
if (duplicateCount > 0) {
- Log.w(TAG, "Found " + duplicateCount + " overlapping programs");
+ Log.w(TAG, "Found " + duplicateCount + " duplicate programs");
}
}
return programs;
@@ -856,7 +777,9 @@ public class ProgramDataManager implements MemoryManageable {
for (Long channelId : removedChannelIds) {
if (mPrefetchEnabled) {
mChannelIdProgramCache.remove(channelId);
- mCompleteInfoChannelIds.remove(channelId);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mCompleteInfoChannelIds.remove(channelId);
+ }
}
mChannelIdCurrentProgramMap.remove(channelId);
notifyCurrentProgramUpdate(channelId, null);
@@ -874,7 +797,7 @@ public class ProgramDataManager implements MemoryManageable {
mDbExecutor,
mContext,
TvContract.buildProgramsUriForChannel(channelId, time, time),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
SORT_BY_TIME);
@@ -885,7 +808,7 @@ public class ProgramDataManager implements MemoryManageable {
public Program onQuery(Cursor c) {
Program program = null;
if (c != null && c.moveToNext()) {
- program = ProgramImpl.fromCursor(c);
+ program = Program.fromCursor(c);
}
return program;
}
@@ -946,9 +869,6 @@ public class ProgramDataManager implements MemoryManageable {
}
break;
}
- case MSG_UPDATE_CONTENT_RATINGS:
- mTvInputManagerHelper.getContentRatingsManager().update();
- break;
default:
// Do nothing
}
@@ -1012,7 +932,7 @@ public class ProgramDataManager implements MemoryManageable {
// Create dummy program which indicates data isn't loaded yet so DB query is required.
private Program createDummyProgram(long startTimeMs, long endTimeMs) {
- return new ProgramImpl.Builder()
+ return new Program.Builder()
.setChannelId(Channel.INVALID_ID)
.setStartTimeUtcMillis(startTimeMs)
.setEndTimeUtcMillis(endTimeMs)
diff --git a/src/com/android/tv/data/api/BaseProgram.java b/src/com/android/tv/data/api/BaseProgram.java
deleted file mode 100644
index 8acaf79e..00000000
--- a/src/com/android/tv/data/api/BaseProgram.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.android.tv.data.api;
-
-import android.content.Context;
-import android.media.tv.TvContentRating;
-import android.support.annotation.Nullable;
-import com.google.common.collect.ImmutableList;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * Base class for {@link com.android.tv.data.Program} and {@link
- * com.android.tv.dvr.data.RecordedProgram}.
- */
-public interface BaseProgram {
-
- /**
- * Comparator used to compare {@link BaseProgram} according to its season and episodes number.
- * If a program's season or episode number is null, it will be consider "smaller" than programs
- * with season or episode numbers.
- */
- Comparator<BaseProgram> EPISODE_COMPARATOR = new EpisodeComparator(false);
- /**
- * Comparator used to compare {@link BaseProgram} according to its season and episodes number
- * with season numbers in a reversed order. If a program's season or episode number is null, it
- * will be consider "smaller" than programs with season or episode numbers.
- */
- Comparator<BaseProgram> SEASON_REVERSED_EPISODE_COMPARATOR = new EpisodeComparator(true);
-
- String COLUMN_SERIES_ID = "series_id";
- String COLUMN_STATE = "state";
-
- /** Compares two strings represent season numbers or episode numbers of programs. */
- static int numberCompare(String s1, String s2) {
- if (Objects.equals(s1, s2)) {
- return 0;
- } else if (s1 == null) {
- return -1;
- } else if (s2 == null) {
- return 1;
- } else if (s1.equals(s2)) {
- return 0;
- }
- try {
- return Integer.compare(Integer.parseInt(s1), Integer.parseInt(s2));
- } catch (NumberFormatException e) {
- return s1.compareTo(s2);
- }
- }
-
- /** Generates the series ID for the other inputs than the tuner TV input. */
- static String generateSeriesId(String packageName, String title) {
- return packageName + "/" + title;
- }
-
- /** Returns ID of the program. */
- long getId();
-
- /** Returns the title of the program. */
- String getTitle();
-
- /** Returns the episode title. */
- String getEpisodeTitle();
-
- /** Returns the displayed title of the program episode. */
- @Nullable
- String getEpisodeDisplayTitle(Context context);
-
- /**
- * Returns the content description of the program episode, suitable for being spoken by an
- * accessibility service.
- */
- String getEpisodeContentDescription(Context context);
-
- /** Returns the description of the program. */
- String getDescription();
-
- /** Returns the long description of the program. */
- String getLongDescription();
-
- /** Returns the start time of the program in Milliseconds. */
- long getStartTimeUtcMillis();
-
- /** Returns the end time of the program in Milliseconds. */
- long getEndTimeUtcMillis();
-
- /** Returns the duration of the program in Milliseconds. */
- long getDurationMillis();
-
- /** Returns the series ID. */
- @Nullable
- String getSeriesId();
-
- /** Returns the season number. */
- String getSeasonNumber();
-
- /** Returns the episode number. */
- String getEpisodeNumber();
-
- /** Returns URI of the program's poster. */
- String getPosterArtUri();
-
- /** Returns URI of the program's thumbnail. */
- String getThumbnailUri();
-
- /** Returns the array of the ID's of the canonical genres. */
- int[] getCanonicalGenreIds();
-
- /** Returns the array of content ratings. */
- ImmutableList<TvContentRating> getContentRatings();
-
- /** Returns channel's ID of the program. */
- long getChannelId();
-
- /** Returns if the program is valid. */
- boolean isValid();
-
- /** Checks whether the program is episodic or not. */
- boolean isEpisodic();
-
- /** Generates the series ID for the other inputs than the tuner TV input. */
- class EpisodeComparator implements Comparator<BaseProgram> {
- private final boolean mReversedSeason;
-
- EpisodeComparator(boolean reversedSeason) {
- mReversedSeason = reversedSeason;
- }
-
- @Override
- public int compare(BaseProgram lhs, BaseProgram rhs) {
- if (lhs == rhs) {
- return 0;
- }
- int seasonNumberCompare = numberCompare(lhs.getSeasonNumber(), rhs.getSeasonNumber());
- if (seasonNumberCompare != 0) {
- return mReversedSeason ? -seasonNumberCompare : seasonNumberCompare;
- } else {
- return numberCompare(lhs.getEpisodeNumber(), rhs.getEpisodeNumber());
- }
- }
- }
-}
diff --git a/src/com/android/tv/data/api/Program.java b/src/com/android/tv/data/api/Program.java
deleted file mode 100644
index f2221f6e..00000000
--- a/src/com/android/tv/data/api/Program.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.android.tv.data.api;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-
-import com.android.tv.util.images.ImageLoader;
-
-import java.io.Serializable;
-import java.util.List;
-
-/** A convenience interface to create and insert program information entries into the database. */
-public interface Program extends BaseProgram, Comparable<Program> {
-
- /** Returns {@code true} if the program is valid and {@code false} otherwise. */
- static boolean isProgramValid(Program program) {
- return program != null && program.isValid();
- }
-
- static boolean isDuplicate(Program p1, Program p2) {
- if (p1 == null || p2 == null) {
- return false;
- }
- return p1.getChannelId() == p2.getChannelId()
- && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
- && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
- }
-
- /** True if the start or end times overlap. */
- static boolean isOverlapping(@Nullable Program p1, @Nullable Program p2) {
- return p1 != null
- && p2 != null
- && p1.getStartTimeUtcMillis() < p2.getEndTimeUtcMillis()
- && p1.getEndTimeUtcMillis() > p2.getStartTimeUtcMillis();
- }
-
- /** True if the channels IDs are the same. */
- static boolean sameChannel(@Nullable Program p1, @Nullable Program p2) {
- return p1 != null && p2 != null && p1.getChannelId() == p2.getChannelId();
- }
-
- /** Returns the package name of this program. */
- String getPackageName();
-
- /** Returns the season title */
- String getSeasonTitle();
-
- /** Gets the localized duration of the program */
- String getDurationString(Context context);
-
- int getVideoWidth();
-
- int getVideoHeight();
-
- /** Returns the list of Critic Scores for this program */
- @Nullable
- List<CriticScore> getCriticScores();
-
- /** Returns {@code true} if the recording of this program is prohibited. */
- boolean isRecordingProhibited();
-
- /** Returns array of canonical genres for this program. This is expected to be called rarely. */
- @Nullable
- String[] getCanonicalGenres();
-
- /** Returns if this program has the genre. */
- boolean hasGenre(int genreId);
-
- /** Prefetch the program poster art. */
- void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight);
-
- /**
- * Loads the program poster art and returns it via {@code callback}.
- *
- * <p>Note that it may directly call {@code callback} if the program poster art already is
- * loaded.
- *
- * @return {@code true} if the load is complete and the callback is executed.
- */
- @UiThread
- boolean loadPosterArt(
- Context context,
- int posterArtWidth,
- int posterArtHeight,
- ImageLoader.ImageLoaderCallback<?> callback);
-
- /** Returns a {@link Parcelable} representation of this instance. */
- Parcelable toParcelable();
-
- /** Holds one type of critic score and its source. */
- final class CriticScore implements Serializable, Parcelable {
- /** The source of the rating. */
- public final String source;
- /** The score. */
- public final String score;
- /** The url of the logo image */
- public final String logoUrl;
-
- public static final Creator<CriticScore> CREATOR =
- new Creator<CriticScore>() {
- @Override
- public CriticScore createFromParcel(Parcel in) {
- String source = in.readString();
- String score = in.readString();
- String logoUri = in.readString();
- return new CriticScore(source, score, logoUri);
- }
-
- @Override
- public CriticScore[] newArray(int size) {
- return new CriticScore[size];
- }
- };
-
- /**
- * Constructor for this class.
- *
- * @param source the source of the rating
- * @param score the score
- */
- public CriticScore(String source, String score, String logoUrl) {
- this.source = source;
- this.score = score;
- this.logoUrl = logoUrl;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int i) {
- out.writeString(source);
- out.writeString(score);
- out.writeString(logoUrl);
- }
- }
-}
diff --git a/src/com/android/tv/data/epg/EpgFetchHelper.java b/src/com/android/tv/data/epg/EpgFetchHelper.java
index 4e889115..3843ca99 100644
--- a/src/com/android/tv/data/epg/EpgFetchHelper.java
+++ b/src/com/android/tv/data/epg/EpgFetchHelper.java
@@ -28,15 +28,12 @@ import android.preference.PreferenceManager;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.common.CommonConstants;
import com.android.tv.common.util.Clock;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.features.TvFeatures;
import com.android.tv.util.TvProviderUtils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -109,7 +106,7 @@ class EpgFetchHelper {
ops.add(
ContentProviderOperation.newUpdate(
TvContract.buildProgramUri(oldProgram.getId()))
- .withValues(ProgramImpl.toContentValues(newProgram, context))
+ .withValues(Program.toContentValues(newProgram, context))
.build());
oldProgramsIndex++;
newProgramsIndex++;
@@ -135,7 +132,7 @@ class EpgFetchHelper {
if (addNewProgram) {
ops.add(
ContentProviderOperation.newInsert(Programs.CONTENT_URI)
- .withValues(ProgramImpl.toContentValues(newProgram, context))
+ .withValues(Program.toContentValues(newProgram, context))
.build());
}
// Throttle the batch operation not to cause TransactionTooLargeException.
@@ -202,7 +199,7 @@ class EpgFetchHelper {
@WorkerThread
private static List<Program> queryPrograms(
Context context, long channelId, long startTimeMs, long endTimeMs) {
- String[] projection = ProgramImpl.PROJECTION;
+ String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
projection =
TvProviderUtils.addExtraColumnsToProjection(
@@ -222,7 +219,7 @@ class EpgFetchHelper {
}
ArrayList<Program> programs = new ArrayList<>();
while (c.moveToNext()) {
- programs.add(ProgramImpl.fromCursor(c));
+ programs.add(Program.fromCursor(c));
}
return programs;
}
diff --git a/src/com/android/tv/data/epg/EpgFetchService.java b/src/com/android/tv/data/epg/EpgFetchService.java
index cfa79cb0..aa4f3588 100644
--- a/src/com/android/tv/data/epg/EpgFetchService.java
+++ b/src/com/android/tv/data/epg/EpgFetchService.java
@@ -18,24 +18,22 @@ package com.android.tv.data.epg;
import android.app.job.JobParameters;
import android.app.job.JobService;
-
import com.android.tv.Starter;
+import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import dagger.android.AndroidInjection;
-
-import javax.inject.Inject;
-
/** JobService to Fetch EPG data. */
public class EpgFetchService extends JobService {
- @Inject EpgFetcher mEpgFetcher;
- @Inject ChannelDataManager mChannelDataManager;
+ private EpgFetcher mEpgFetcher;
+ private ChannelDataManager mChannelDataManager;
@Override
public void onCreate() {
- AndroidInjection.inject(this);
super.onCreate();
Starter.start(this);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(getApplicationContext());
+ mEpgFetcher = tvSingletons.getEpgFetcher();
+ mChannelDataManager = tvSingletons.getChannelDataManager();
}
@Override
diff --git a/src/com/android/tv/data/epg/EpgFetcherImpl.java b/src/com/android/tv/data/epg/EpgFetcherImpl.java
index 27d7f8d5..b191421f 100644
--- a/src/com/android/tv/data/epg/EpgFetcherImpl.java
+++ b/src/com/android/tv/data/epg/EpgFetcherImpl.java
@@ -38,12 +38,10 @@ import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.buildtype.HasBuildType;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.util.Clock;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.LocationUtils;
@@ -54,22 +52,17 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.ChannelLogoFetcher;
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.epg.EpgReader.EpgChannel;
import com.android.tv.features.TvFeatures;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.Utils;
-
import com.google.android.tv.partner.support.EpgInput;
import com.google.android.tv.partner.support.EpgInputs;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -80,8 +73,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
/**
* The service class to fetch EPG routinely or on-demand during channel scanning
*
@@ -118,6 +109,7 @@ public class EpgFetcherImpl implements EpgFetcher {
private static final int MSG_FINISH_FETCH_DURING_SCAN = 3;
private static final int MSG_RETRY_PREPARE_FETCH_DURING_SCAN = 4;
+ private static final int QUERY_CHANNEL_COUNT = 50;
private static final int MINIMUM_CHANNELS_TO_DECIDE_LINEUP = 3;
private final Context mContext;
@@ -138,9 +130,31 @@ public class EpgFetcherImpl implements EpgFetcher {
private Clock mClock;
- @Inject
- public EpgFetcherImpl(
- @ApplicationContext Context context,
+ public static EpgFetcher create(Context context) {
+ context = context.getApplicationContext();
+ TvSingletons tvSingletons = TvSingletons.getSingletons(context);
+ ChannelDataManager channelDataManager = tvSingletons.getChannelDataManager();
+ PerformanceMonitor performanceMonitor = tvSingletons.getPerformanceMonitor();
+ EpgReader epgReader = tvSingletons.providesEpgReader().get();
+ Clock clock = tvSingletons.getClock();
+ EpgInputWhiteList epgInputWhiteList =
+ new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
+ BackendKnobsFlags backendKnobsFlags = tvSingletons.getBackendKnobs();
+ HasBuildType.BuildType buildType = tvSingletons.getBuildType();
+ return new EpgFetcherImpl(
+ context,
+ epgInputWhiteList,
+ channelDataManager,
+ epgReader,
+ performanceMonitor,
+ clock,
+ backendKnobsFlags,
+ buildType);
+ }
+
+ @VisibleForTesting
+ EpgFetcherImpl(
+ Context context,
EpgInputWhiteList epgInputWhiteList,
ChannelDataManager channelDataManager,
EpgReader epgReader,
@@ -455,16 +469,23 @@ public class EpgFetcherImpl implements EpgFetcher {
if (epgChannels.size() == 0) {
return;
}
- int batchSize = (int) Math.max(1, mBackendKnobsFlags.epgFetcherChannelsPerProgramFetch());
- for (Iterable<EpgChannel> batch : Iterables.partition(epgChannels, batchSize)) {
- batchUpdateEpg(mEpgReader.getPrograms(ImmutableSet.copyOf(batch), durationSec));
+ Set<EpgReader.EpgChannel> batch = new HashSet<>(QUERY_CHANNEL_COUNT);
+ for (EpgReader.EpgChannel epgChannel : epgChannels) {
+ batch.add(epgChannel);
+ if (batch.size() >= QUERY_CHANNEL_COUNT) {
+ batchUpdateEpg(mEpgReader.getPrograms(batch, durationSec));
+ batch.clear();
+ }
+ }
+ if (!batch.isEmpty()) {
+ batchUpdateEpg(mEpgReader.getPrograms(batch, durationSec));
}
}
@WorkerThread
private void batchUpdateEpg(Map<EpgReader.EpgChannel, Collection<Program>> allPrograms) {
for (Map.Entry<EpgReader.EpgChannel, Collection<Program>> entry : allPrograms.entrySet()) {
- List<Program> programs = new ArrayList<>(entry.getValue());
+ List<Program> programs = new ArrayList(entry.getValue());
if (programs == null) {
continue;
}
@@ -583,7 +604,6 @@ public class EpgFetcherImpl implements EpgFetcher {
? ((Integer) REASON_CLOUD_EPG_FAILURE)
: anyCloudEpgSuccess ? null : builtInResult;
}
- clearUnusedLineups(null);
return builtInResult;
} finally {
TrafficStats.setThreadStatsTag(oldTag);
diff --git a/src/com/android/tv/data/epg/EpgInputWhiteList.java b/src/com/android/tv/data/epg/EpgInputWhiteList.java
index 4a5f98bb..24b4fe3d 100644
--- a/src/com/android/tv/data/epg/EpgInputWhiteList.java
+++ b/src/com/android/tv/data/epg/EpgInputWhiteList.java
@@ -21,14 +21,13 @@ import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import com.android.tv.common.BuildConfig;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import javax.inject.Inject;
/** Checks if a package or a input is white listed. */
public final class EpgInputWhiteList {
@@ -37,7 +36,6 @@ public final class EpgInputWhiteList {
private static final String QA_DEV_INPUTS =
"com.example.partnersupportsampletvinput/.SampleTvInputService,"
+ "com.android.tv.tuner.sample.dvb/.tvinput.SampleDvbTunerTvInputService";
- private final LegacyFlags mLegacyFlags;
/** Returns the package portion of a inputId */
@Nullable
@@ -45,12 +43,10 @@ public final class EpgInputWhiteList {
return inputId == null ? null : inputId.substring(0, inputId.indexOf("/"));
}
- private final CloudEpgFlags mCloudEpgFlags;
+ private final CloudEpgFlags cloudEpgFlags;
- @Inject
- public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags, LegacyFlags legacyFlags) {
- mCloudEpgFlags = cloudEpgFlags;
- mLegacyFlags = legacyFlags;
+ public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags) {
+ this.cloudEpgFlags = cloudEpgFlags;
}
public boolean isInputWhiteListed(String inputId) {
@@ -75,8 +71,8 @@ public final class EpgInputWhiteList {
}
private Set<String> getWhiteListedInputs() {
- Set<String> result = toInputSet(mCloudEpgFlags.thirdPartyEpgInputsCsv());
- if (BuildConfig.ENG || mLegacyFlags.enableQaFeatures()) {
+ Set<String> result = toInputSet(cloudEpgFlags.thirdPartyEpgInputsCsv());
+ if (BuildConfig.ENG || Experiments.ENABLE_QA_FEATURES.get()) {
HashSet<String> moreInputs = new HashSet<>(toInputSet(QA_DEV_INPUTS));
if (result.isEmpty()) {
result = moreInputs;
diff --git a/src/com/android/tv/data/epg/EpgReader.java b/src/com/android/tv/data/epg/EpgReader.java
index 8c0e3f09..c9fcd979 100644
--- a/src/com/android/tv/data/epg/EpgReader.java
+++ b/src/com/android/tv/data/epg/EpgReader.java
@@ -19,14 +19,11 @@ package com.android.tv.data.epg;
import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
-
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.SeriesInfo;
-
import com.google.auto.value.AutoValue;
-
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -39,8 +36,8 @@ public interface EpgReader {
/** Value class that holds a EpgChannelId and its corresponding {@link Channel} */
@AutoValue
abstract class EpgChannel {
- public static EpgChannel createEpgChannel(
- Channel channel, String epgChannelId, boolean dbUpdateNeeded) {
+ public static EpgChannel createEpgChannel(Channel channel, String epgChannelId,
+ boolean dbUpdateNeeded) {
return new AutoValue_EpgReader_EpgChannel(channel, epgChannelId, dbUpdateNeeded);
}
diff --git a/src/com/android/tv/data/epg/StubEpgReader.java b/src/com/android/tv/data/epg/StubEpgReader.java
index 19bf786e..3b001481 100644
--- a/src/com/android/tv/data/epg/StubEpgReader.java
+++ b/src/com/android/tv/data/epg/StubEpgReader.java
@@ -16,25 +16,21 @@
package com.android.tv.data.epg;
+import android.content.Context;
import android.support.annotation.NonNull;
-
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.SeriesInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.inject.Inject;
-
/** A stub class to read EPG. */
public class StubEpgReader implements EpgReader {
- @Inject
- public StubEpgReader() {}
+ public StubEpgReader(@SuppressWarnings("unused") Context context) {}
@Override
public boolean isAvailable() {
diff --git a/src/com/android/tv/dialog/PinDialogFragment.java b/src/com/android/tv/dialog/PinDialogFragment.java
index c7145583..87308093 100644
--- a/src/com/android/tv/dialog/PinDialogFragment.java
+++ b/src/com/android/tv/dialog/PinDialogFragment.java
@@ -18,7 +18,6 @@ package com.android.tv.dialog;
import android.app.ActivityManager;
import android.app.Dialog;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.media.tv.TvContentRating;
@@ -34,13 +33,10 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
import com.android.tv.R;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dialog.picker.TvPinPicker;
-import com.android.tv.util.TvInputManagerHelper;
+import com.android.tv.dialog.picker.PinPicker;
import com.android.tv.util.TvSettings;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.UiFlags;
-import javax.inject.Inject;
public class PinDialogFragment extends SafeDismissDialogFragment {
private static final String TAG = "PinDialogFragment";
@@ -84,8 +80,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private TextView mWrongPinView;
private View mEnterPinView;
private TextView mTitleView;
-
- private TvPinPicker mTvPinPicker;
+ private PinPicker mPicker;
private SharedPreferences mSharedPreferences;
private String mPrevPin;
private String mPin;
@@ -93,8 +88,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private int mWrongPinCount;
private long mDisablePinUntil;
private final Handler mHandler = new Handler();
- @Inject TvInputManagerHelper mTvInputManagerHelper;
- @Inject UiFlags mUiFlags;
public static PinDialogFragment create(int type) {
return create(type, null);
@@ -110,12 +103,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
@Override
- public void onAttach(Context context) {
- AndroidInjection.inject(this);
- super.onAttach(context);
- }
-
- @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRequestType = getArguments().getInt(ARGS_TYPE, PIN_DIALOG_TYPE_ENTER_PIN);
@@ -167,8 +154,8 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mWrongPinView = (TextView) v.findViewById(R.id.wrong_pin);
mEnterPinView = v.findViewById(R.id.enter_pin);
mTitleView = (TextView) mEnterPinView.findViewById(R.id.title);
- mTvPinPicker = v.findViewById(R.id.tv_pin_picker);
- mTvPinPicker.setOnClickListener(
+ mPicker = v.findViewById(R.id.pin_picker);
+ mPicker.setOnClickListener(
view -> {
String pin = getPinInput();
if (!TextUtils.isEmpty(pin)) {
@@ -196,7 +183,8 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mTitleView.setText(
getString(
R.string.pin_enter_unlock_dvr,
- mTvInputManagerHelper
+ TvSingletons.getSingletons(getContext())
+ .getTvInputManagerHelper()
.getContentRatingsManager()
.getDisplayNameForRating(tvContentRating)));
}
@@ -216,8 +204,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
if (mType != PIN_DIALOG_TYPE_NEW_PIN) {
updateWrongPin();
}
-
- mTvPinPicker.requestFocus();
+ mPicker.requestFocus();
return v;
}
@@ -351,11 +338,11 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private String getPinInput() {
- return mTvPinPicker.getPin();
+ return mPicker.getPinInput();
}
private void resetPinInput() {
- mTvPinPicker.resetPin();
+ mPicker.resetPinInput();
}
/**
diff --git a/src/com/android/tv/dialog/picker/PinPicker.java b/src/com/android/tv/dialog/picker/PinPicker.java
new file mode 100644
index 00000000..f501dfd1
--- /dev/null
+++ b/src/com/android/tv/dialog/picker/PinPicker.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tv.dialog.picker;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v17.leanback.widget.picker.Picker;
+import android.support.v17.leanback.widget.picker.PickerColumn;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import java.util.ArrayList;
+import java.util.List;
+
+/** 4 digit picker */
+public final class PinPicker extends Picker {
+ // TODO(b/116144491): use leanback pin picker.
+
+ private final List<PickerColumn> mPickers = new ArrayList<>();
+ private OnClickListener mOnClickListener;
+
+ // the version of picker I link to does not have this constructor
+ public PinPicker(Context context, AttributeSet attributeSet) {
+ this(context, attributeSet, 0);
+ }
+
+ public PinPicker(Context context, AttributeSet attributeSet, int defStyleAttr) {
+ super(context, attributeSet, defStyleAttr);
+
+ for (int i = 0; i < 4; i++) {
+ PickerColumn pickerColumn = new PickerColumn();
+ pickerColumn.setMinValue(0);
+ pickerColumn.setMaxValue(9);
+ pickerColumn.setLabelFormat("%d");
+ mPickers.add(pickerColumn);
+ }
+ setSeparator(" ");
+ setColumns(mPickers);
+ setActivated(true);
+ setFocusable(true);
+ super.setOnClickListener(this::onClick);
+ }
+
+ public String getPinInput() {
+ String result = "";
+ try {
+ for (PickerColumn column : mPickers) {
+
+ result += column.getCurrentValue();
+ }
+ } catch (IllegalStateException e) {
+ result = "";
+ }
+ return result;
+ }
+
+ @Override
+ public void setOnClickListener(@Nullable OnClickListener l) {
+ mOnClickListener = l;
+ }
+
+ private void onClick(View v) {
+ int selectedColumn = getSelectedColumn();
+ int nextColumn = selectedColumn + 1;
+ // Only call the click listener if we are on the last column
+ // Otherwise move to the next column
+ if (nextColumn == getColumnsCount()) {
+ if (mOnClickListener != null) {
+ mOnClickListener.onClick(v);
+ }
+ } else {
+ setSelectedColumn(nextColumn);
+ onRequestFocusInDescendants(ViewGroup.FOCUS_FORWARD, null);
+ }
+ }
+
+ public void resetPinInput() {
+ setActivated(false);
+ for (int i = 0; i < 4; i++) {
+ setColumnValue(i, 0, true);
+ }
+ setSelectedColumn(0);
+ setActivated(true); // This resets the focus
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ int keyCode = event.getKeyCode();
+ int digit = digitFromKeyCode(keyCode);
+ if (digit != -1) {
+ int selectedColumn = getSelectedColumn();
+ setColumnValue(selectedColumn, digit, false);
+ int nextColumn = selectedColumn + 1;
+ if (nextColumn < getColumnsCount()) {
+ setSelectedColumn(nextColumn);
+ onRequestFocusInDescendants(ViewGroup.FOCUS_FORWARD, null);
+ } else {
+ callOnClick();
+ }
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @VisibleForTesting
+ static int digitFromKeyCode(int keyCode) {
+ if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
+ return keyCode - KeyEvent.KEYCODE_0;
+ } else if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyCode <= KeyEvent.KEYCODE_NUMPAD_9) {
+ return keyCode - KeyEvent.KEYCODE_NUMPAD_0;
+ }
+ return -1;
+ }
+}
diff --git a/src/com/android/tv/dialog/picker/TvPinPicker.java b/src/com/android/tv/dialog/picker/TvPinPicker.java
deleted file mode 100644
index 064b7f02..00000000
--- a/src/com/android/tv/dialog/picker/TvPinPicker.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.dialog.picker;
-
-import static android.content.Context.ACCESSIBILITY_SERVICE;
-
-import android.content.Context;
-import androidx.leanback.widget.picker.PinPicker;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityManager;
-
-/** 4 digit picker */
-public final class TvPinPicker extends PinPicker {
-
- private boolean mSkipPerformClick = true;
- private boolean mIsAccessibilityEnabled = false;
-
- public TvPinPicker(Context context, AttributeSet attributeSet) {
- this(context, attributeSet, 0);
- }
-
- public TvPinPicker(Context context, AttributeSet attributeSet, int defStyleAttr) {
- super(context, attributeSet, defStyleAttr);
- setActivated(true);
- AccessibilityManager am =
- (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
- mIsAccessibilityEnabled = am.isEnabled();
- }
-
- @Override
- public boolean performClick() {
- // (b/120096347) Skip first click when talkback is enabled
- if (mSkipPerformClick && mIsAccessibilityEnabled) {
- mSkipPerformClick = false;
- /* Force focus to next value */
- setColumnValue(getSelectedColumn(), 1, true);
- return false;
- }
- return super.performClick();
- }
-}
diff --git a/src/com/android/tv/dvr/DvrDataManagerImpl.java b/src/com/android/tv/dvr/DvrDataManagerImpl.java
index 3e26a231..0053650b 100644
--- a/src/com/android/tv/dvr/DvrDataManagerImpl.java
+++ b/src/com/android/tv/dvr/DvrDataManagerImpl.java
@@ -37,10 +37,8 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.recording.RecordingStorageStatusManager.OnStorageMountChangedListener;
import com.android.tv.common.util.Clock;
@@ -50,7 +48,6 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.provider.DvrDatabaseHelper;
import com.android.tv.dvr.provider.DvrDbFuture.AddScheduleFuture;
import com.android.tv.dvr.provider.DvrDbFuture.AddSeriesRecordingFuture;
import com.android.tv.dvr.provider.DvrDbFuture.DeleteScheduleFuture;
@@ -63,14 +60,11 @@ import com.android.tv.dvr.provider.DvrDbSync;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.AsyncDbTask.AsyncRecordedProgramQueryTask;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvUriMatcher;
-
import com.google.common.base.Predicate;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -82,13 +76,9 @@ import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/** DVR Data manager to handle recordings and schedules. */
@MainThread
@TargetApi(Build.VERSION_CODES.N)
-@Singleton
public class DvrDataManagerImpl extends BaseDvrDataManager {
private static final String TAG = "DvrDataManagerImpl";
private static final boolean DEBUG = false;
@@ -108,7 +98,6 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
private final HashMap<Long, SeriesRecording> mSeriesRecordingsForRemovedInput = new HashMap<>();
private final Context mContext;
- private final DvrDatabaseHelper mDbHelper;
private Executor mDbExecutor;
private final ContentObserver mContentObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@@ -198,28 +187,20 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
return moved;
}
- @Inject
- public DvrDataManagerImpl(
- @ApplicationContext Context context,
- Clock clock,
- TvInputManagerHelper tvInputManagerHelper,
- @DbExecutor Executor dbExecutor,
- DvrDatabaseHelper dbHelper) {
+ public DvrDataManagerImpl(Context context, Clock clock) {
super(context, clock);
mContext = context;
TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- mInputManager = tvInputManagerHelper;
+ mInputManager = tvSingletons.getTvInputManagerHelper();
mStorageStatusManager = tvSingletons.getRecordingStorageStatusManager();
- mDbExecutor = dbExecutor;
- mDbHelper = dbHelper;
- start();
+ mDbExecutor = tvSingletons.getDbExecutor();
}
- private void start() {
+ public void start() {
mInputManager.addCallback(mInputCallback);
mStorageStatusManager.addListener(mStorageMountChangedListener);
DvrQuerySeriesRecordingFuture dvrQuerySeriesRecordingTask =
- new DvrQuerySeriesRecordingFuture(mDbHelper);
+ new DvrQuerySeriesRecordingFuture(mContext);
ListenableFuture<List<SeriesRecording>> dvrQuerySeriesRecordingFuture =
dvrQuerySeriesRecordingTask.executeOnDbThread(
new FutureCallback<List<SeriesRecording>>() {
@@ -232,8 +213,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (SoftPreconditions.checkState(
!seriesIds.contains(r.getSeriesId()),
TAG,
- "Skip loading series recording with duplicate series"
- + " ID: "
+ "Skip loading series recording with duplicate series ID: "
+ r)) {
seriesIds.add(r.getSeriesId());
if (isInputAvailable(r.getInputId())) {
@@ -257,7 +237,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
});
mPendingDvrFuture.add(dvrQuerySeriesRecordingFuture);
- DvrQueryScheduleFuture dvrQueryScheduleTask = new DvrQueryScheduleFuture(mDbHelper);
+ DvrQueryScheduleFuture dvrQueryScheduleTask = new DvrQueryScheduleFuture(mContext);
ListenableFuture<List<ScheduledRecording>> dvrQueryScheduleFuture =
dvrQueryScheduleTask.executeOnDbThread(
new FutureCallback<List<ScheduledRecording>>() {
@@ -661,7 +641,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifyScheduledRecordingAdded(schedules);
}
ListenableFuture addScheduleFuture =
- new AddScheduleFuture(mDbHelper)
+ new AddScheduleFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, schedules);
mNoStopFuture.add(addScheduleFuture);
removeDeletedSchedules(schedules);
@@ -683,7 +663,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingAdded(seriesRecordings);
}
ListenableFuture addSeriesRecordingFuture =
- new AddSeriesRecordingFuture(mDbHelper)
+ new AddSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(addSeriesRecordingFuture);
}
@@ -743,7 +723,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -751,7 +731,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesNotToDelete.isEmpty()) {
ListenableFuture updateScheduleFuture =
- new UpdateScheduleFuture(mDbHelper)
+ new UpdateScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesNotToDelete));
@@ -794,7 +774,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingRemoved(seriesRecordings);
}
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(deleteSeriesRecordingFuture);
removeDeletedSchedules(seriesRecordings);
@@ -849,7 +829,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (updateDb) {
ListenableFuture updateScheduleFuture =
- new UpdateScheduleFuture(mDbHelper)
+ new UpdateScheduleFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, scheduleArray);
mNoStopFuture.add(updateScheduleFuture);
}
@@ -876,7 +856,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingChanged(seriesRecordings);
}
ListenableFuture updateSeriesRecordingFuture =
- new UpdateSeriesRecordingFuture(mDbHelper)
+ new UpdateSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(updateSeriesRecordingFuture);
}
@@ -897,7 +877,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -922,7 +902,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -970,7 +950,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
mSeriesRecordingsForRemovedInput.remove(r.getId());
}
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
SeriesRecording.toArray(removedSeriesRecordings));
@@ -1063,13 +1043,13 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
}
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
mNoStopFuture.add(deleteScheduleFuture);
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
SeriesRecording.toArray(seriesRecordingsToDelete));
@@ -1105,7 +1085,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (!removedSeriesRecordings.isEmpty()) {
SeriesRecording[] removed = SeriesRecording.toArray(removedSeriesRecordings);
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, removed);
mNoStopFuture.add(deleteSeriesRecordingFuture);
if (mDvrLoadFinished) {
diff --git a/src/com/android/tv/dvr/DvrManager.java b/src/com/android/tv/dvr/DvrManager.java
index 12982c6c..cc9ad37a 100644
--- a/src/com/android/tv/dvr/DvrManager.java
+++ b/src/com/android/tv/dvr/DvrManager.java
@@ -37,13 +37,12 @@ import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
import com.android.tv.dvr.DvrScheduleManager.OnInitializeListener;
@@ -52,7 +51,6 @@ import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.Utils;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -189,7 +187,7 @@ public class DvrManager {
? mScheduleManager.suggestNewPriority()
: mScheduleManager.suggestHighestPriority(
seriesRecording.getInputId(),
- Range.create(
+ new Range(
program.getStartTimeUtcMillis(),
program.getEndTimeUtcMillis()),
seriesRecording.getPriority()));
diff --git a/src/com/android/tv/dvr/DvrScheduleManager.java b/src/com/android/tv/dvr/DvrScheduleManager.java
index 3afcc422..7202dce0 100644
--- a/src/com/android/tv/dvr/DvrScheduleManager.java
+++ b/src/com/android/tv/dvr/DvrScheduleManager.java
@@ -25,12 +25,11 @@ import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -38,7 +37,6 @@ import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.recorder.InputTaskScheduler;
import com.android.tv.util.CompositeComparator;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -78,7 +76,7 @@ public class DvrScheduleManager {
ScheduledRecording.ID_COMPARATOR);
private final Context mContext;
- private final DvrDataManager mDataManager;
+ private final DvrDataManagerImpl mDataManager;
private final ChannelDataManager mChannelDataManager;
private final Map<String, List<ScheduledRecording>> mInputScheduleMap = new HashMap<>();
@@ -97,7 +95,7 @@ public class DvrScheduleManager {
public DvrScheduleManager(Context context) {
mContext = context;
TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- mDataManager = tvSingletons.getDvrDataManager();
+ mDataManager = (DvrDataManagerImpl) tvSingletons.getDvrDataManager();
mChannelDataManager = tvSingletons.getChannelDataManager();
if (mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished()) {
buildData();
diff --git a/src/com/android/tv/dvr/DvrStorageStatusManager.java b/src/com/android/tv/dvr/DvrStorageStatusManager.java
index a0ae8939..dc347a9e 100644
--- a/src/com/android/tv/dvr/DvrStorageStatusManager.java
+++ b/src/com/android/tv/dvr/DvrStorageStatusManager.java
@@ -114,7 +114,7 @@ public class DvrStorageStatusManager extends RecordingStorageStatusManager {
return;
}
for (TvInputInfo info : tvInputInfoList) {
- if (CommonUtils.isBundledInput(info.getId()) && dvrManager != null) {
+ if (CommonUtils.isBundledInput(info.getId())) {
dvrManager.forgetStorage(info.getId());
}
}
diff --git a/src/com/android/tv/dvr/DvrWatchedPositionManager.java b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
index b4fea7f3..8616962f 100644
--- a/src/com/android/tv/dvr/DvrWatchedPositionManager.java
+++ b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
@@ -20,10 +20,8 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.media.tv.TvInputManager;
import android.support.annotation.IntDef;
-
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -38,7 +36,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
*/
public class DvrWatchedPositionManager {
private SharedPreferences mWatchedPositions;
- private final Map<Long, Set<WatchedPositionChangedListener>> mListeners = new HashMap<>();
+ private final Map<Long, Set> mListeners = new HashMap<>();
/**
* The minimum percentage of recorded program being watched that will be considered as being
diff --git a/src/com/android/tv/dvr/data/RecordedProgram.java b/src/com/android/tv/dvr/data/RecordedProgram.java
index 61430551..899e65ac 100644
--- a/src/com/android/tv/dvr/data/RecordedProgram.java
+++ b/src/com/android/tv/dvr/data/RecordedProgram.java
@@ -36,10 +36,9 @@ import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.data.RecordedProgramState;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.StringUtils;
-import com.android.tv.data.BaseProgramImpl;
+import com.android.tv.data.BaseProgram;
import com.android.tv.data.GenreItems;
import com.android.tv.data.InternalDataUtils;
-import com.android.tv.data.api.BaseProgram;
import com.android.tv.util.TvProviderUtils;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
@@ -50,7 +49,7 @@ import java.util.concurrent.TimeUnit;
/** Immutable instance of {@link android.media.tv.TvContract.RecordedPrograms}. */
@TargetApi(Build.VERSION_CODES.N)
@AutoValue
-public abstract class RecordedProgram extends BaseProgramImpl {
+public abstract class RecordedProgram extends BaseProgram {
public static final int ID_NOT_SET = -1;
private static final String TAG = "RecordedProgram";
diff --git a/src/com/android/tv/dvr/data/ScheduledRecording.java b/src/com/android/tv/dvr/data/ScheduledRecording.java
index 1237fb3e..ba6d3cf9 100644
--- a/src/com/android/tv/dvr/data/ScheduledRecording.java
+++ b/src/com/android/tv/dvr/data/ScheduledRecording.java
@@ -27,17 +27,15 @@ import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Range;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.util.CompositeComparator;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
@@ -494,7 +492,7 @@ public final class ScheduledRecording implements Parcelable {
}
};
- /** The ID internal to TV app */
+ /** The ID internal to Live TV */
private long mId;
/**
diff --git a/src/com/android/tv/dvr/data/SeriesRecording.java b/src/com/android/tv/dvr/data/SeriesRecording.java
index cd7d9662..6cb0e836 100644
--- a/src/com/android/tv/dvr/data/SeriesRecording.java
+++ b/src/com/android/tv/dvr/data/SeriesRecording.java
@@ -22,14 +22,11 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.text.TextUtils;
-
-import com.android.tv.data.BaseProgramImpl;
-import com.android.tv.data.api.BaseProgram;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
import com.android.tv.util.Utils;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -88,8 +85,7 @@ public class SeriesRecording implements Parcelable {
(SeriesRecording lhs, SeriesRecording rhs) -> Long.compare(lhs.mId, rhs.mId);
/**
- * Creates a new Builder with the values set from the series information of {@link
- * BaseProgramImpl}.
+ * Creates a new Builder with the values set from the series information of {@link BaseProgram}.
*/
public static Builder builder(String inputId, BaseProgram p) {
return new Builder()
diff --git a/src/com/android/tv/dvr/provider/DvrContract.java b/src/com/android/tv/dvr/provider/DvrContract.java
index 8539ae36..a5f2e2cd 100644
--- a/src/com/android/tv/dvr/provider/DvrContract.java
+++ b/src/com/android/tv/dvr/provider/DvrContract.java
@@ -20,7 +20,7 @@ import android.provider.BaseColumns;
/**
* The contract between the DVR provider and applications. Contains definitions for the supported
- * columns. It's for the internal use in TV app.
+ * columns. It's for the internal use in Live TV.
*/
public final class DvrContract {
/** Column definition for Schedules table. */
@@ -69,8 +69,8 @@ public final class DvrContract {
public static final String FAILED_REASON_INVALID_CHANNEL = "FAILED_REASON_INVALID_CHANNEL";
/** The recording failed because the scheduler was stopped */
- public static final String FAILED_REASON_SCHEDULER_STOPPED =
- "FAILED_REASON_SCHEDULER_STOPPED";
+ public static final String FAILED_REASON_SCHEDULER_STOPPED
+ = "FAILED_REASON_SCHEDULER_STOPPED";
/** The recording failed because some messages were not sent to the message queue */
public static final String FAILED_REASON_MESSAGE_NOT_SENT =
@@ -84,7 +84,8 @@ public final class DvrContract {
"FAILED_REASON_CONNECTION_FAILED";
/**
- * The recording failed because a required recording resource was not able to be allocated.
+ * The recording failed because a required recording resource was not able to be
+ * allocated.
*/
public static final String FAILED_REASON_RESOURCE_BUSY = "FAILED_REASON_RESOURCE_BUSY";
diff --git a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
index 1dcda8e0..ebf133db 100644
--- a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
+++ b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
@@ -26,18 +26,12 @@ import android.database.sqlite.SQLiteStatement;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
-
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/** A data class for one recorded contents. */
-@Singleton
public class DvrDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DvrDatabaseHelper";
private static final boolean DEBUG = false;
@@ -244,9 +238,8 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
return "DELETE FROM " + tableName + " WHERE " + BaseColumns._ID + "=?";
}
- @Inject
- public DvrDatabaseHelper(@ApplicationContext Context context) {
- super(context, DB_NAME, null, DATABASE_VERSION);
+ public DvrDatabaseHelper(Context context) {
+ super(context.getApplicationContext(), DB_NAME, null, DATABASE_VERSION);
}
@Override
@@ -273,12 +266,8 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
return;
}
if (oldVersion < 18) {
- db.execSQL(
- "ALTER TABLE "
- + Schedules.TABLE_NAME
- + " ADD COLUMN "
- + Schedules.COLUMN_FAILED_REASON
- + " TEXT DEFAULT null;");
+ db.execSQL("ALTER TABLE " + Schedules.TABLE_NAME + " ADD COLUMN "
+ + Schedules.COLUMN_FAILED_REASON + " TEXT DEFAULT null;");
}
}
diff --git a/src/com/android/tv/dvr/provider/DvrDbFuture.java b/src/com/android/tv/dvr/provider/DvrDbFuture.java
index cbc2c07d..ae8c480b 100644
--- a/src/com/android/tv/dvr/provider/DvrDbFuture.java
+++ b/src/com/android/tv/dvr/provider/DvrDbFuture.java
@@ -16,23 +16,21 @@
package com.android.tv.dvr.provider;
+import android.content.Context;
import android.database.Cursor;
import android.support.annotation.Nullable;
import android.util.Log;
-
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
import com.android.tv.util.MainThreadExecutor;
-
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
@@ -40,24 +38,29 @@ import java.util.concurrent.Executors;
/** {@link DvrDbFuture} that defaults to executing on its own single threaded Executor Service. */
public abstract class DvrDbFuture<ParamsT, ResultT> {
private static final NamedThreadFactory THREAD_FACTORY =
- new NamedThreadFactory(DvrDbFuture.class.getSimpleName());
+ new NamedThreadFactory(DvrDbFuture.class.getSimpleName());
private static final ListeningExecutorService DB_EXECUTOR =
- MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(THREAD_FACTORY));
+ MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(THREAD_FACTORY));
- final DvrDatabaseHelper mDbHelper;
+ private static DvrDatabaseHelper sDbHelper;
private ListenableFuture<ResultT> mFuture;
- private DvrDbFuture(DvrDatabaseHelper mDbHelper) {
- this.mDbHelper = mDbHelper;
+ final Context mContext;
+
+ private DvrDbFuture(Context context) {
+ mContext = context;
}
- /** Execute the task on the {@link #DB_EXECUTOR} thread and return Future */
+ /** Execute the task on the {@link #DB_EXECUTOR} thread and return Future*/
@SafeVarargs
public final ListenableFuture<ResultT> executeOnDbThread(
- FutureCallback<ResultT> callback, ParamsT... params) {
- mFuture = DB_EXECUTOR.submit(() -> dbHelperInBackground(params));
- Futures.addCallback(mFuture, callback, MainThreadExecutor.getInstance());
- return mFuture;
+ FutureCallback<ResultT> callback, ParamsT... params) {
+ if (sDbHelper == null) {
+ sDbHelper = new DvrDatabaseHelper(mContext.getApplicationContext());
+ }
+ mFuture = DB_EXECUTOR.submit(() -> dbHelperInBackground(params));
+ Futures.addCallback(mFuture, callback, MainThreadExecutor.getInstance());
+ return mFuture;
}
/** Executes in the background after initializing DbHelper} */
@@ -69,48 +72,52 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
/** Inserts schedules. */
- public static class AddScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public AddScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class AddScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public AddScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.insertSchedules(params);
+ sDbHelper.insertSchedules(params);
return null;
}
}
/** Update schedules. */
- public static class UpdateScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public UpdateScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class UpdateScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public UpdateScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.updateSchedules(params);
+ sDbHelper.updateSchedules(params);
return null;
}
}
/** Delete schedules. */
- public static class DeleteScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public DeleteScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DeleteScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public DeleteScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.deleteSchedules(params);
+ sDbHelper.deleteSchedules(params);
return null;
}
}
/** Returns all {@link ScheduledRecording}s. */
- public static class DvrQueryScheduleFuture extends DvrDbFuture<Void, List<ScheduledRecording>> {
- public DvrQueryScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DvrQueryScheduleFuture
+ extends DvrDbFuture<Void, List<ScheduledRecording>> {
+ public DvrQueryScheduleFuture(Context context) {
+ super(context);
}
@Override
@@ -120,7 +127,7 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
return null;
}
List<ScheduledRecording> scheduledRecordings = new ArrayList<>();
- try (Cursor c = mDbHelper.query(Schedules.TABLE_NAME, ScheduledRecording.PROJECTION)) {
+ try (Cursor c = sDbHelper.query(Schedules.TABLE_NAME, ScheduledRecording.PROJECTION)) {
while (c.moveToNext() && !isCancelled()) {
scheduledRecordings.add(ScheduledRecording.fromCursor(c));
}
@@ -130,40 +137,43 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
/** Inserts series recordings. */
- public static class AddSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public AddSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class AddSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public AddSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.insertSeriesRecordings(params);
+ sDbHelper.insertSeriesRecordings(params);
return null;
}
}
/** Update series recordings. */
- public static class UpdateSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public UpdateSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class UpdateSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public UpdateSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.updateSeriesRecordings(params);
+ sDbHelper.updateSeriesRecordings(params);
return null;
}
}
/** Delete series recordings. */
- public static class DeleteSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public DeleteSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DeleteSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public DeleteSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.deleteSeriesRecordings(params);
+ sDbHelper.deleteSeriesRecordings(params);
return null;
}
}
@@ -173,8 +183,8 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
extends DvrDbFuture<Void, List<SeriesRecording>> {
private static final String TAG = "DvrQuerySeriesRecording";
- public DvrQuerySeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public DvrQuerySeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
@@ -185,7 +195,7 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
List<SeriesRecording> scheduledRecordings = new ArrayList<>();
try (Cursor c =
- mDbHelper.query(SeriesRecordings.TABLE_NAME, SeriesRecording.PROJECTION)) {
+ sDbHelper.query(SeriesRecordings.TABLE_NAME, SeriesRecording.PROJECTION)) {
while (c.moveToNext() && !isCancelled()) {
scheduledRecordings.add(SeriesRecording.fromCursor(c));
}
diff --git a/src/com/android/tv/dvr/provider/DvrDbSync.java b/src/com/android/tv/dvr/provider/DvrDbSync.java
index c2eae771..7658ca45 100644
--- a/src/com/android/tv/dvr/provider/DvrDbSync.java
+++ b/src/com/android/tv/dvr/provider/DvrDbSync.java
@@ -29,19 +29,17 @@ import android.os.Looper;
import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.WritableDvrDataManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.util.AsyncDbTask.AsyncQueryProgramTask;
import com.android.tv.util.TvUriMatcher;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -51,7 +49,6 @@ import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
/**
* A class to synchronizes DVR DB with TvProvider.
@@ -68,11 +65,9 @@ public class DvrDbSync {
private static final String TAG = "DvrDbSync";
private static final boolean DEBUG = false;
- private static final long RECORD_MARGIN_MS = TimeUnit.SECONDS.toMillis(10);
-
private final Context mContext;
private final DvrManager mDvrManager;
- private final WritableDvrDataManager mDataManager;
+ private final DvrDataManagerImpl mDataManager;
private final ChannelDataManager mChannelDataManager;
private final Executor mDbExecutor;
private final Queue<Long> mProgramIdQueue = new LinkedList<>();
@@ -143,7 +138,7 @@ public class DvrDbSync {
}
};
- public DvrDbSync(Context context, WritableDvrDataManager dataManager) {
+ public DvrDbSync(Context context, DvrDataManagerImpl dataManager) {
this(
context,
dataManager,
@@ -156,7 +151,7 @@ public class DvrDbSync {
@VisibleForTesting
DvrDbSync(
Context context,
- WritableDvrDataManager dataManager,
+ DvrDataManagerImpl dataManager,
ChannelDataManager channelDataManager,
DvrManager dvrManager,
SeriesRecordingScheduler seriesRecordingScheduler,
@@ -330,15 +325,10 @@ public class DvrDbSync {
// Old program belongs to a series but the new one doesn't.
seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
}
- // Change start time only when the recording is not started yet and if it is not
- // within marginal time of current time. Marginal check is needed to prevent the
- // update of start time if recording is just triggered or about to get triggered.
- boolean marginalToCurrentTime = RECORD_MARGIN_MS >
- Math.abs(System.currentTimeMillis() - schedule.getStartTimeMs());
+ // Change start time only when the recording is not started yet.
boolean needToChangeStartTime =
schedule.getState() != ScheduledRecording.STATE_RECORDING_IN_PROGRESS
- && program.getStartTimeUtcMillis() != schedule.getStartTimeMs()
- && !marginalToCurrentTime;
+ && program.getStartTimeUtcMillis() != schedule.getStartTimeMs();
if (needToChangeStartTime) {
builder.setStartTimeMs(program.getStartTimeUtcMillis());
needUpdate = true;
diff --git a/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
index a66e5b02..02e197f1 100644
--- a/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
+++ b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
@@ -25,19 +25,16 @@ import android.net.Uri;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.PermissionUtils;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.AsyncDbTask.AsyncProgramQueryTask;
import com.android.tv.util.AsyncDbTask.CursorFilter;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -50,11 +47,11 @@ import java.util.Set;
public abstract class EpisodicProgramLoadTask {
private static final String TAG = "EpisodicProgramLoadTask";
- private static final int PROGRAM_ID_INDEX = ProgramImpl.getColumnIndex(Programs._ID);
+ private static final int PROGRAM_ID_INDEX = Program.getColumnIndex(Programs._ID);
private static final int START_TIME_INDEX =
- ProgramImpl.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
+ Program.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
private static final int RECORDING_PROHIBITED_INDEX =
- ProgramImpl.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
+ Program.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
private static final String PARAM_START_TIME = "start_time";
private static final String PARAM_END_TIME = "end_time";
@@ -292,7 +289,7 @@ public abstract class EpisodicProgramLoadTask {
&& mDisallowedProgramIds.contains(c.getLong(PROGRAM_ID_INDEX))) {
return false;
}
- Program program = ProgramImpl.fromCursor(c);
+ Program program = Program.fromCursor(c);
for (SeriesRecording seriesRecording : mSeriesRecordings) {
boolean programMatches;
if (mIgnoreChannelOption) {
diff --git a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
index 92b4e06a..696038cf 100644
--- a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
+++ b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
@@ -27,12 +27,11 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.LongSparseArray;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.CollectionUtils;
import com.android.tv.common.util.SharedPreferencesUtils;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
@@ -44,9 +43,6 @@ import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesInfo;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
-
-import dagger.Lazy;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -58,6 +54,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import javax.inject.Provider;
/**
* Creates the {@link com.android.tv.dvr.data.ScheduledRecording}s for the {@link
@@ -532,9 +529,10 @@ public class SeriesRecordingScheduler {
private class FetchSeriesInfoTask extends AsyncTask<Void, Void, SeriesInfo> {
private final SeriesRecording mSeriesRecording;
- private final Lazy<EpgReader> mEpgReaderProvider;
+ private final Provider<EpgReader> mEpgReaderProvider;
- FetchSeriesInfoTask(SeriesRecording seriesRecording, Lazy<EpgReader> epgReaderProvider) {
+ FetchSeriesInfoTask(
+ SeriesRecording seriesRecording, Provider<EpgReader> epgReaderProvider) {
mSeriesRecording = seriesRecording;
mEpgReaderProvider = epgReaderProvider;
}
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
index 1f4faf31..5e3caa9c 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
@@ -22,16 +22,13 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.util.List;
/**
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
index 56ffc884..a6bbe137 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
@@ -22,17 +22,14 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
-
import java.util.List;
/**
diff --git a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
index b24281ad..6be35cb2 100644
--- a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
@@ -18,9 +18,9 @@ package com.android.tv.dvr.ui;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
diff --git a/src/com/android/tv/dvr/ui/DvrConflictFragment.java b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
index 5e0a96bb..649cc89a 100644
--- a/src/com/android/tv/dvr/ui/DvrConflictFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
@@ -21,25 +21,22 @@ import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.recorder.ConflictChecker;
import com.android.tv.dvr.recorder.ConflictChecker.OnUpcomingConflictChangeListener;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java b/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
index 81fc3ed5..611962d0 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
index fda4cdee..a900cc70 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
@@ -20,9 +20,9 @@ import android.app.Activity;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
index e8f501e9..e6b54f67 100644
--- a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
@@ -20,15 +20,13 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import androidx.leanback.app.GuidedStepFragment;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelWatchConflictFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
@@ -38,7 +36,7 @@ import com.android.tv.ui.DetailsActivity;
public class DvrHalfSizedDialogFragment extends HalfSizedDialogFragment {
/** Key for input ID. Type: String. */
public static final String KEY_INPUT_ID = "DvrHalfSizedDialogFragment.input_id";
- /** Key for the program. Type: {@link ProgramImpl}. */
+ /** Key for the program. Type: {@link com.android.tv.data.Program}. */
public static final String KEY_PROGRAM = "DvrHalfSizedDialogFragment.program";
/** Key for the channel ID. Type: long. */
public static final String KEY_CHANNEL_ID = "DvrHalfSizedDialogFragment.channel_id";
diff --git a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
index 01631b99..6fba4d98 100644
--- a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
diff --git a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
index 3237acd7..02b2da1d 100644
--- a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
@@ -21,8 +21,8 @@ import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
import com.android.tv.R;
import com.android.tv.ui.DetailsActivity;
diff --git a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
index ae41f501..5bb97e90 100644
--- a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
@@ -22,9 +22,9 @@ import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
diff --git a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
index 7131f626..72603d03 100644
--- a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
@@ -22,21 +22,18 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
-
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
-
import java.util.Collections;
import java.util.List;
@@ -55,7 +52,7 @@ public class DvrScheduleFragment extends DvrGuidedStepFragment {
private static final int ACTION_RECORD_EPISODE = 1;
private static final int ACTION_RECORD_SERIES = 2;
- private ProgramImpl mProgram;
+ private Program mProgram;
private boolean mAddCurrentProgramToSeries;
@Override
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
index 730237c4..a237f1d2 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
@@ -20,13 +20,15 @@ import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.util.Log;
import android.widget.Toast;
+
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrManager;
+
import java.util.ArrayList;
import java.util.List;
@@ -68,7 +70,7 @@ public class DvrSeriesDeletionActivity extends Activity {
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
deleteSelectedIds(true);
} else {
- // NOTE: If TV app ever supports both embedded and separate DVR inputs
+ // NOTE: If Live TV ever supports both embedded and separate DVR inputs
// then we should try to do the delete regardless.
Log.i(
TAG,
@@ -91,14 +93,14 @@ public class DvrSeriesDeletionActivity extends Activity {
dvrManager.removeRecordedPrograms(mIdsToDelete, deleteFiles);
}
Toast.makeText(
- this,
- getResources()
- .getQuantityString(
- R.plurals.dvr_msg_episodes_deleted,
- mIdsToDelete.size(),
- mIdsToDelete.size(),
- recordingSize),
- Toast.LENGTH_LONG)
+ this,
+ getResources()
+ .getQuantityString(
+ R.plurals.dvr_msg_episodes_deleted,
+ mIdsToDelete.size(),
+ mIdsToDelete.size(),
+ recordingSize),
+ Toast.LENGTH_LONG)
.show();
finish();
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
index 10ef226b..ff213231 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
@@ -19,10 +19,10 @@ package com.android.tv.dvr.ui;
import android.content.Context;
import android.media.tv.TvInputManager;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.text.TextUtils;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
index d72099ba..9acb5b5e 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
@@ -18,7 +18,7 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
public class DvrSeriesScheduledDialogActivity extends Activity {
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
index 7d369904..c6e26850 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
@@ -20,26 +20,22 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
-
import java.util.List;
public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
/**
* The key for program list which will be passed to {@link DvrSeriesSchedulesFragment}. Type:
- * List<{@link ProgramImpl}>
+ * List<{@link Program}>
*/
public static final String SERIES_SCHEDULED_KEY_PROGRAMS = "series_scheduled_key_programs";
@@ -50,7 +46,6 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
private SeriesRecording mSeriesRecording;
private boolean mShowViewScheduleOption;
private List<Program> mPrograms;
- private String mSeriesRecordingTitle;
private int mSchedulesAddedCount = 0;
private boolean mHasConflict = false;
@@ -80,7 +75,6 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
getActivity().finish();
return;
}
- mSeriesRecordingTitle = mSeriesRecording.getTitle();
mPrograms = (List<Program>) BigArguments.getArgument(SERIES_SCHEDULED_KEY_PROGRAMS);
BigArguments.reset();
mSchedulesAddedCount =
@@ -168,7 +162,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_no_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle);
+ mSeriesRecording.getTitle());
} else {
// mInThisSeriesConflictCount equals 0 and mOutThisSeriesConflictCount equals 0 means
// mHasConflict is false. So we don't need to check that case.
@@ -178,7 +172,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_this_and_other_series_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mInThisSeriesConflictCount + mOutThisSeriesConflictCount);
} else if (mInThisSeriesConflictCount != 0) {
return getResources()
@@ -186,7 +180,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_recording_scheduled_only_this_series_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mInThisSeriesConflictCount);
} else {
if (mOutThisSeriesConflictCount == 1) {
@@ -195,14 +189,14 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_only_other_series_one_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle);
+ mSeriesRecording.getTitle());
} else {
return getResources()
.getQuantityString(
R.plurals.dvr_series_scheduled_only_other_series_many_conflicts,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mOutThisSeriesConflictCount);
}
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
index eb3ca283..1a51cf46 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
@@ -19,13 +19,10 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-
-import androidx.leanback.app.GuidedStepFragment;
-
+import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.ProgramImpl;
/** Activity to show details view in DVR. */
public class DvrSeriesSettingsActivity extends Activity {
@@ -43,7 +40,7 @@ public class DvrSeriesSettingsActivity extends Activity {
public static final String IS_WINDOW_TRANSLUCENT = "windows_translucent";
/**
* Name of the program list. The list contains the programs which belong to the series. Type:
- * List<{@link ProgramImpl}>
+ * List<{@link com.android.tv.data.Program}>
*/
public static final String PROGRAM_LIST = "program_list";
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
index 7fc201c5..eadb3b9e 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
@@ -21,19 +21,17 @@ import android.app.FragmentManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.util.LongSparseArray;
-
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -41,7 +39,6 @@ import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.data.SeriesRecording.ChannelOption;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -72,7 +69,6 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
private Program mCurrentProgram;
private String mFragmentTitle;
- private String mSeriesRecordingTitle;
private String mProrityActionTitle;
private String mProrityActionHighestText;
private String mProrityActionLowestText;
@@ -96,7 +92,6 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
getActivity().finish();
return;
}
- mSeriesRecordingTitle = mSeriesRecording.getTitle();
mShowViewScheduleOptionInDialog =
getArguments()
.getBoolean(DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG);
@@ -166,8 +161,9 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String breadcrumb = mSeriesRecording.getTitle();
String title = mFragmentTitle;
- return new Guidance(title, null, mSeriesRecordingTitle, null);
+ return new Guidance(title, null, breadcrumb, null);
}
@Override
diff --git a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
index 1475a8c3..1ab4c500 100644
--- a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
@@ -23,17 +23,13 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.data.ScheduledRecording;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -48,7 +44,7 @@ import java.util.List;
public class DvrStopRecordingFragment extends DvrGuidedStepFragment {
/** The action ID for the stop action. */
public static final int ACTION_STOP = 1;
- /** Key for the program. Type: {@link ProgramImpl}. */
+ /** Key for the program. Type: {@link com.android.tv.data.Program}. */
public static final String KEY_REASON = "DvrStopRecordingFragment.type";
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
index 4a8ce04e..15abf902 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
@@ -18,7 +18,7 @@ package com.android.tv.dvr.ui;
import android.app.DialogFragment;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
index 0b8f5df0..99211fdb 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrUiHelper.java b/src/com/android/tv/dvr/ui/DvrUiHelper.java
index 657abfa2..a121cf99 100644
--- a/src/com/android/tv/dvr/ui/DvrUiHelper.java
+++ b/src/com/android/tv/dvr/ui/DvrUiHelper.java
@@ -33,7 +33,6 @@ import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
-import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.widget.ImageView;
@@ -45,9 +44,9 @@ import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.util.CommonUtils;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.RecordedProgram;
@@ -76,7 +75,6 @@ import com.android.tv.ui.DetailsActivity;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
-import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -124,7 +122,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
args.putBoolean(
DvrScheduleFragment.KEY_ADD_CURRENT_PROGRAM_TO_SERIES, addCurrentProgramToSeries);
showDialogFragment(activity, new DvrScheduleDialogFragment(), args, true, true);
@@ -146,7 +144,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrProgramConflictDialogFragment(), args, false, true);
}
@@ -229,7 +227,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrAlreadyScheduledDialogFragment(), args, false, true);
}
@@ -239,18 +237,14 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrAlreadyRecordedDialogFragment(), args, false, true);
}
/** Shows program information dialog. */
public static void showWriteStoragePermissionRationaleDialog(Activity activity) {
- showDialogFragment(
- activity,
- new DvrWriteStoragePermissionRationaleDialogFragment(),
- new Bundle(),
- false,
- false);
+ showDialogFragment(activity, new DvrWriteStoragePermissionRationaleDialogFragment(),
+ new Bundle(), false, false);
}
/**
@@ -465,7 +459,7 @@ public class DvrUiHelper {
boolean removeEmptySeriesSchedule,
boolean isWindowTranslucent,
boolean showViewScheduleOptionInDialog,
- @Nullable Program currentProgram) {
+ Program currentProgram) {
SeriesRecording series =
TvSingletons.getSingletons(context)
.getDvrDataManager()
@@ -487,15 +481,13 @@ public class DvrUiHelper {
new EpisodicProgramLoadTask(context, series) {
@Override
protected void onPostExecute(List<Program> loadedPrograms) {
- if (sProgressDialog != null) {
- sProgressDialog.dismiss();
- sProgressDialog = null;
- }
+ sProgressDialog.dismiss();
+ sProgressDialog = null;
startSeriesSettingsActivityInternal(
context,
seriesRecordingId,
loadedPrograms == null
- ? ImmutableList.of()
+ ? Collections.EMPTY_LIST
: loadedPrograms,
removeEmptySeriesSchedule,
isWindowTranslucent,
@@ -532,7 +524,7 @@ public class DvrUiHelper {
boolean removeEmptySeriesSchedule,
boolean isWindowTranslucent,
boolean showViewScheduleOptionInDialog,
- @Nullable Program currentProgram) {
+ Program currentProgram) {
SoftPreconditions.checkState(
programs != null, TAG, "Start series settings activity but programs is null");
Intent intent = new Intent(context, DvrSeriesSettingsActivity.class);
@@ -545,9 +537,7 @@ public class DvrUiHelper {
intent.putExtra(
DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG,
showViewScheduleOptionInDialog);
- if (currentProgram != null) {
- intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram.toParcelable());
- }
+ intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram);
context.startActivity(intent);
}
@@ -692,18 +682,16 @@ public class DvrUiHelper {
}
SpannableStringBuilder builder;
if (TextUtils.isEmpty(seasonNumber) || seasonNumber.equals("0")) {
- Spanned temp =
+ builder =
TextUtils.isEmpty(episodeNumber)
- ? SpannableStringBuilder.valueOf(title)
- : Html.fromHtml(
- context.getString(
- R.string.program_title_with_episode_number_no_season,
- title,
- episodeNumber));
- builder = SpannableStringBuilder.valueOf(temp);
+ ? new SpannableStringBuilder(title)
+ : new SpannableStringBuilder(Html.fromHtml(context.getString(
+ R.string.program_title_with_episode_number_no_season,
+ title,
+ episodeNumber)));
} else {
builder =
- SpannableStringBuilder.valueOf(
+ new SpannableStringBuilder(
Html.fromHtml(
context.getString(
R.string.program_title_with_episode_number,
diff --git a/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java b/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
index 25f7f38b..c93f5831 100644
--- a/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
@@ -19,8 +19,8 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
index 7a26d5ed..1eb8080a 100644
--- a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
+++ b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.support.annotation.VisibleForTesting;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.PresenterSelector;
import com.android.tv.common.SoftPreconditions;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
index c0a57c0f..0172f76f 100644
--- a/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
diff --git a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
index a06705c6..41ace9a4 100644
--- a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
+++ b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
@@ -17,10 +17,10 @@
package com.android.tv.dvr.ui.browse;
import android.graphics.drawable.Drawable;
-import androidx.leanback.R;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.R;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
index 88ef112f..8c311d68 100644
--- a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
@@ -19,13 +19,12 @@ package com.android.tv.dvr.ui.browse;
import android.content.Context;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
-
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
+import com.android.tv.common.flags.has.HasConcurrentDvrPlaybackFlags;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -34,10 +33,7 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
import com.android.tv.dvr.ui.DvrUiHelper;
-
-import dagger.android.AndroidInjection;
-
-import javax.inject.Inject;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/** {@link RecordingDetailsFragment} for current recording in DVR. */
public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
@@ -47,7 +43,8 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
private DvrDataManager mDvrDataManger;
private RecordedProgram mRecordedProgram;
- @Inject DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private boolean mPaused;
private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
new DvrDataManager.ScheduledRecordingListener() {
@@ -79,10 +76,12 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
@Override
public void onAttach(Context context) {
- AndroidInjection.inject(this);
super.onAttach(context);
mDvrDataManger = TvSingletons.getSingletons(context).getDvrDataManager();
mDvrDataManger.addScheduledRecordingListener(mScheduledRecordingListener);
+ mDvrWatchedPositionManager =
+ TvSingletons.getSingletons(getActivity()).getDvrWatchedPositionManager();
+ mConcurrentDvrPlaybackFlags = HasConcurrentDvrPlaybackFlags.fromContext(context);
}
@Override
@@ -116,7 +115,9 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
res.getString(R.string.dvr_detail_stop_recording),
null,
res.getDrawable(R.drawable.lb_ic_stop)));
- if (mRecordedProgram != null && mRecordedProgram.isPartial()) {
+ if (mConcurrentDvrPlaybackFlags.enabled()
+ && mRecordedProgram != null
+ && mRecordedProgram.isPartial()) {
if (mDvrWatchedPositionManager.getWatchedStatus(mRecordedProgram)
== DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
adapter.set(
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContent.java b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
index b5e05264..e179743c 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContent.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
@@ -20,11 +20,10 @@ import android.content.Context;
import android.media.tv.TvContract;
import android.support.annotation.Nullable;
import android.text.TextUtils;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
@@ -127,10 +126,9 @@ public class DetailsContent {
}
private static String getErrorMessage(Context context, ScheduledRecording recording) {
- int reason =
- recording.getFailedReason() == null
- ? ScheduledRecording.FAILED_REASON_OTHER
- : recording.getFailedReason();
+ int reason = recording.getFailedReason() == null
+ ? ScheduledRecording.FAILED_REASON_OTHER
+ : recording.getFailedReason();
switch (reason) {
case ScheduledRecording.FAILED_REASON_PROGRAM_ENDED_BEFORE_RECORDING_STARTED:
return context.getString(R.string.dvr_recording_failed_not_started);
@@ -138,7 +136,8 @@ public class DetailsContent {
return context.getString(R.string.dvr_recording_failed_resource_busy);
case ScheduledRecording.FAILED_REASON_INPUT_UNAVAILABLE:
return context.getString(
- R.string.dvr_recording_failed_input_unavailable, recording.getInputId());
+ R.string.dvr_recording_failed_input_unavailable,
+ recording.getInputId());
case ScheduledRecording.FAILED_REASON_INPUT_DVR_UNSUPPORTED:
return context.getString(R.string.dvr_recording_failed_input_dvr_unsupported);
case ScheduledRecording.FAILED_REASON_INSUFFICIENT_SPACE:
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
index fafc70cf..6b5fd1fd 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
@@ -24,7 +24,7 @@ import android.app.Activity;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
-import androidx.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Presenter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -40,10 +40,10 @@ import com.android.tv.util.Utils;
/**
* An {@link Presenter} for rendering a detailed description of an DVR item. Typically this
* Presenter will be used in a {@link
- * androidx.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
- * originated from {@link androidx.leanback.widget.AbstractDetailsDescriptionPresenter}.
+ * android.support.v17.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
+ * originated from {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
* The latter class are re-used to provide a customized version of {@link
- * androidx.leanback.widget.DetailsOverviewRow}.
+ * android.support.v17.leanback.widget.DetailsOverviewRow}.
*/
public class DetailsContentPresenter extends Presenter {
/** The ViewHolder for the {@link DetailsContentPresenter}. */
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
index 8a4c7854..4e41daee 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
@@ -21,7 +21,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import androidx.leanback.app.BackgroundManager;
+import android.support.v17.leanback.app.BackgroundManager;
/** The Background Helper. */
public class DetailsViewBackgroundHelper {
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
index 7262b4a0..5743ea5c 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
@@ -22,13 +22,13 @@ import android.media.tv.TvInputManager;
import android.os.Bundle;
import com.android.tv.R;
import com.android.tv.Starter;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
/** {@link android.app.Activity} for DVR UI. */
public class DvrBrowseActivity extends Activity {
{
- StartupMeasureFactory.create().onActivityInit();
+ PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
}
private DvrBrowseFragment mFragment;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
index 786942e0..17ba1939 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
@@ -21,14 +21,13 @@ import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.text.TextUtils;
-import androidx.leanback.app.BrowseFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.TitleViewAdapter;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.TitleViewAdapter;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
@@ -476,7 +475,7 @@ public class DvrBrowseFragment extends BrowseFragment
mRecentAdapter.add(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
SeriesRecording seriesRecording = null;
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
if (latestProgram == null
@@ -500,7 +499,7 @@ public class DvrBrowseFragment extends BrowseFragment
private void handleRecordedProgramRemoved(RecordedProgram recordedProgram) {
mRecentAdapter.remove(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram =
mSeriesId2LatestProgram.get(recordedProgram.getSeriesId());
@@ -521,7 +520,7 @@ public class DvrBrowseFragment extends BrowseFragment
mRecentAdapter.change(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
SeriesRecording seriesRecording = null;
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
if (latestProgram == null
@@ -664,7 +663,7 @@ public class DvrBrowseFragment extends BrowseFragment
}
}
if (getSelectedPosition() >= mRowsAdapter.size()) {
- setSelectedPosition(mRowsAdapter.size() - 1);
+ setSelectedPosition(mRecentAdapter.size() - 1);
}
}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
index a38180a5..f90981f0 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
@@ -25,15 +25,15 @@ import android.media.tv.TvContentRating;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.text.TextUtils;
import android.widget.Toast;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
index ebdee32f..4298d86a 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
@@ -19,7 +19,7 @@ package com.android.tv.dvr.ui.browse;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.CallSuper;
-import androidx.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Presenter;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
index 625f8f76..a2d1cb28 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.browse;
import android.content.Context;
-import androidx.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ListRowPresenter;
import android.view.ViewGroup;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
index 5f58af8e..bf963547 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
@@ -19,9 +19,9 @@ package com.android.tv.dvr.ui.browse;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
import android.os.Bundle;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.util.PermissionUtils;
@@ -32,7 +32,7 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.ui.DetailsActivity;
-/** {@link androidx.leanback.app.DetailsFragment} for recorded program in DVR. */
+/** {@link android.support.v17.leanback.app.DetailsFragment} for recorded program in DVR. */
public class RecordedProgramDetailsFragment extends DvrDetailsFragment
implements DvrDataManager.RecordedProgramListener {
private static final int ACTION_RESUME_PLAYING = 1;
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
index ac7c5745..c83ceaf0 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
@@ -23,16 +23,14 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
-import android.text.Layout;
+import android.support.v17.leanback.widget.BaseCardView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.leanback.widget.BaseCardView;
import com.android.tv.R;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.ui.ViewUtils;
@@ -44,7 +42,7 @@ import com.android.tv.util.images.ImageLoader;
*/
public class RecordingCardView extends BaseCardView {
// This value should be the same with
- // androidx.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
+ // android.support.v17.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
private static final int ANIMATION_DURATION = 150;
private final ImageView mImageView;
private final int mImageWidth;
@@ -64,7 +62,6 @@ public class RecordingCardView extends BaseCardView {
private final boolean mExpandTitleWhenFocused;
private boolean mExpanded;
private String mDetailBackgroundImageUri;
- private Layout mTitleViewLayout;
public RecordingCardView(Context context) {
this(context, false);
@@ -123,14 +120,6 @@ public class RecordingCardView extends BaseCardView {
* value));
}
});
- getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- getViewTreeObserver().removeOnGlobalLayoutListener(this);
- mTitleViewLayout = mFoldedTitleView.getLayout();
- }
- });
mExpandTitleWhenFocused = expandTitleWhenFocused;
}
@@ -165,8 +154,7 @@ public class RecordingCardView extends BaseCardView {
* @param withAnimation {@code true} to expand/fold with animation.
*/
public void expandTitle(boolean expand, boolean withAnimation) {
- if (expand != mExpanded && mTitleViewLayout != null
- && mTitleViewLayout.getEllipsisCount(0) > 0) {
+ if (expand != mExpanded && mFoldedTitleView.getLayout().getEllipsisCount(0) > 0) {
if (withAnimation) {
if (expand) {
mExpandTitleAnimator.start();
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
index e85f983f..243681c6 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.browse;
import android.os.Bundle;
-import androidx.leanback.app.DetailsFragment;
+import android.support.v17.leanback.app.DetailsFragment;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.ui.DetailsActivity;
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
index 7ef8e59f..f08bb12b 100644
--- a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
@@ -18,9 +18,9 @@ package com.android.tv.dvr.ui.browse;
import android.content.res.Resources;
import android.os.Bundle;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
index 1c020091..9104ef10 100644
--- a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
@@ -21,21 +21,21 @@ import android.graphics.drawable.Drawable;
import android.media.tv.TvInputManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.text.TextUtils;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.data.RecordedProgram;
diff --git a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
index 293e1d94..77a63508 100644
--- a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
index 1d93c8cb..0ca05fac 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
@@ -17,24 +17,23 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.DateHeaderRowPresenter;
-import com.android.tv.common.flags.UiFlags;
/** A fragment to show the DVR history. */
public class DvrHistoryFragment extends DetailsFragment
implements DvrDataManager.ScheduledRecordingListener,
- DvrDataManager.RecordedProgramListener {
+ DvrDataManager.RecordedProgramListener {
private DvrHistoryRowAdapter mRowsAdapter;
private TextView mEmptyInfoScreenView;
@@ -49,17 +48,11 @@ public class DvrHistoryFragment extends DetailsFragment
presenterSelector.addClassPresenter(
ScheduleRow.class, new ScheduleRowPresenter(getContext()));
TvSingletons singletons = TvSingletons.getSingletons(getContext());
- UiFlags uiFlags = singletons.getUiFlags();
- mDvrDataManager = singletons.getDvrDataManager();
- mRowsAdapter =
- new DvrHistoryRowAdapter(
- getContext(),
- presenterSelector,
- singletons.getClock(),
- mDvrDataManager,
- uiFlags);
+ mRowsAdapter = new DvrHistoryRowAdapter(
+ getContext(), presenterSelector, singletons.getClock());
setAdapter(mRowsAdapter);
mRowsAdapter.start();
+ mDvrDataManager = singletons.getDvrDataManager();
mDvrDataManager.addScheduledRecordingListener(this);
mDvrDataManager.addRecordedProgramListener(this);
mEmptyInfoScreenView = (TextView) getActivity().findViewById(R.id.empty_info_screen);
@@ -142,6 +135,7 @@ public class DvrHistoryFragment extends DetailsFragment
hideEmptyMessage();
}
}
+
}
@Override
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
index a10367fb..156d1a7e 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
@@ -20,19 +20,20 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import android.util.Log;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.Clock;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.ScheduledProgramReaper;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow;
import com.android.tv.util.Utils;
-import com.android.tv.common.flags.UiFlags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -47,8 +48,8 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private static final boolean DEBUG = false;
private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
+ private static final int MAX_HISTORY_DAYS = ScheduledProgramReaper.DAYS;
- private final long mMaxHistoryDays;
private final Context mContext;
private final Clock mClock;
private final DvrDataManager mDvrDataManager;
@@ -56,16 +57,11 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private final Map<Long, ScheduledRecording> mRecordedProgramScheduleMap = new HashMap<>();
public DvrHistoryRowAdapter(
- Context context,
- ClassPresenterSelector classPresenterSelector,
- Clock clock,
- DvrDataManager dvrDataManager,
- UiFlags uiFlags) {
+ Context context, ClassPresenterSelector classPresenterSelector, Clock clock) {
super(classPresenterSelector);
mContext = context;
mClock = clock;
- mDvrDataManager = dvrDataManager;
- mMaxHistoryDays = uiFlags.maxHistoryDays();
+ mDvrDataManager = TvSingletons.getSingletons(mContext).getDvrDataManager();
mTitles.add(mContext.getString(R.string.dvr_date_today));
mTitles.add(mContext.getString(R.string.dvr_date_yesterday));
}
@@ -82,9 +78,9 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
List<RecordedProgram> recordedProgramList = mDvrDataManager.getRecordedPrograms();
recordingList.addAll(
- recordedProgramsToScheduledRecordings(recordedProgramList, mMaxHistoryDays));
- recordingList.sort(
- ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
+ recordedProgramsToScheduledRecordings(recordedProgramList, MAX_HISTORY_DAYS));
+ recordingList
+ .sort(ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
long deadLine = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
for (int i = 0; i < recordingList.size(); ) {
ArrayList<ScheduledRecording> section = new ArrayList<>();
@@ -132,7 +128,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
}
private List<ScheduledRecording> recordedProgramsToScheduledRecordings(
- List<RecordedProgram> programs, long maxDays) {
+ List<RecordedProgram> programs, int maxDays) {
List<ScheduledRecording> result = new ArrayList<>();
for (RecordedProgram recordedProgram : programs) {
ScheduledRecording scheduledRecording =
@@ -146,12 +142,12 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
@Nullable
private ScheduledRecording recordedProgramsToScheduledRecordings(
- RecordedProgram program, long maxDays) {
+ RecordedProgram program, int maxDays) {
long firstMillisecondToday = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
- if (maxDays != 0
- && maxDays
- < Utils.computeDateDifference(
- program.getStartTimeUtcMillis(), firstMillisecondToday)) {
+ if (maxDays
+ < Utils.computeDateDifference(
+ program.getStartTimeUtcMillis(),
+ firstMillisecondToday)) {
return null;
}
ScheduledRecording scheduledRecording = ScheduledRecording.builder(program).build();
@@ -179,7 +175,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
return;
}
ScheduledRecording schedule =
- recordedProgramsToScheduledRecordings(program, mMaxHistoryDays);
+ recordedProgramsToScheduledRecordings(program, MAX_HISTORY_DAYS);
if (schedule == null) {
return;
}
@@ -252,10 +248,8 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
for (; index < size(); index++) {
if (get(index) instanceof ScheduleRow) {
ScheduleRow scheduleRow = (ScheduleRow) get(index);
- if (ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
- .reversed()
- .compare(scheduleRow.getSchedule(), recording)
- > 0) {
+ if (ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed()
+ .compare(scheduleRow.getSchedule(), recording) > 0) {
break;
}
pre = index;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
index d0884f99..82b85630 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
@@ -20,15 +20,13 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.IntDef;
-
import com.android.tv.R;
import com.android.tv.Starter;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.dvr.ui.BigArguments;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
index 43a3579a..d97b61f4 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.DateHeaderRowPresenter;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
index 50bc04c7..d376e358 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
@@ -25,24 +25,20 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.transition.Fade;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
import com.android.tv.dvr.ui.BigArguments;
-
import java.util.Collections;
import java.util.List;
@@ -57,7 +53,7 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
"series_schedules_key_series_recording";
/**
* The key for programs which belong to the series recording whose scheduled recording list will
- * be displayed. Type: List<{@link ProgramImpl}>
+ * be displayed. Type: List<{@link Program}>
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_PROGRAMS =
"series_schedules_key_series_programs";
diff --git a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
index ccb497fb..d5808412 100644
--- a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
+++ b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
@@ -17,8 +17,7 @@
package com.android.tv.dvr.ui.list;
import android.content.Context;
-
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.ScheduledRecording.Builder;
import com.android.tv.dvr.ui.DvrUiHelper;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
index de259f5a..ef4a4337 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
@@ -22,8 +22,8 @@ import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Log;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
index ff296f49..11680a0d 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
@@ -24,7 +24,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.IntDef;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
index 5c687cde..bbddc07f 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
@@ -16,9 +16,8 @@
package com.android.tv.dvr.ui.list;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.SeriesRecording;
-
import java.util.List;
/** A base class for the rows for schedules' header. */
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
index 2550eebc..28a44bf3 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
@@ -19,7 +19,7 @@ package com.android.tv.dvr.ui.list;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
index 2c377549..9a9c94ea 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
@@ -20,22 +20,19 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.media.tv.TvInputInfo;
import android.os.Build;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.util.ArrayMap;
import android.util.Log;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
index 4aa1200e..f24ad2c0 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
@@ -16,6 +16,7 @@
package com.android.tv.dvr.ui.playback;
+import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.content.res.Configuration;
@@ -27,12 +28,9 @@ import com.android.tv.Starter;
import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.util.Utils;
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerActivity;
/** Activity to play a {@link RecordedProgram}. */
-public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedListener {
+public class DvrPlaybackActivity extends Activity implements OnPinCheckedListener {
private static final String TAG = "DvrPlaybackActivity";
private static final boolean DEBUG = false;
@@ -41,7 +39,6 @@ public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedL
@Override
public void onCreate(Bundle savedInstanceState) {
- AndroidInjection.inject(this);
Starter.start(this);
if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
@@ -95,16 +92,4 @@ public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedL
void setOnPinCheckListener(OnPinCheckedListener listener) {
mOnPinCheckedListener = listener;
}
-
- /**
- * Exports {@link DvrPlaybackActivity} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract DvrPlaybackActivity contributesDvrPlaybackActivity();
-
- @ContributesAndroidInjector
- abstract DvrPlaybackOverlayFragment contributesDvrPlaybackOverlayFragment();
- }
}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
index 35c5d4e4..791d26bb 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
@@ -26,15 +26,15 @@ import android.media.session.PlaybackState;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.media.PlaybackControlGlue;
-import androidx.leanback.widget.AbstractDetailsDescriptionPresenter;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.PlaybackControlsRow;
-import androidx.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
-import androidx.leanback.widget.PlaybackControlsRow.MultiAction;
-import androidx.leanback.widget.PlaybackControlsRowPresenter;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.media.PlaybackControlGlue;
+import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
index 0c96cac8..1059e852 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
@@ -26,25 +26,24 @@ import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
+import android.support.v17.leanback.app.PlaybackFragment;
+import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SinglePresenterSelector;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
-import androidx.leanback.app.PlaybackFragment;
-import androidx.leanback.app.PlaybackFragmentGlueHost;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.BaseOnItemViewClickedListener;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.RowPresenter;
-import androidx.leanback.widget.SinglePresenterSelector;
import com.android.tv.R;
-import com.android.tv.audio.AudioManagerHelper;
-import com.android.tv.common.buildtype.HasBuildType.BuildType;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.TvSingletons;
+import com.android.tv.data.BaseProgram;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
@@ -56,11 +55,8 @@ import com.android.tv.ui.AppLayerTvView;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvTrackInfoUtils;
import com.android.tv.util.Utils;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.List;
-import javax.inject.Inject;
public class DvrPlaybackOverlayFragment extends PlaybackFragment {
// TODO: Handles audio focus. Deals with block and ratings.
@@ -79,7 +75,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
private ArrayObjectAdapter mRowsAdapter;
private SortedArrayAdapter<BaseProgram> mRelatedRecordingsRowAdapter;
private DvrPlaybackCardPresenter mRelatedRecordingCardPresenter;
- private AudioManagerHelper mAudioManagerHelper;
+ private DvrDataManager mDvrDataManager;
private AppLayerTvView mTvView;
private View mBlockScreenView;
private ListRow mRelatedRecordingsRow;
@@ -101,24 +97,9 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
}
};
- @Inject DvrDataManager mDvrDataManager;
- @Inject LegacyFlags mLegacyFlags;
- @Inject BuildType buildType;
-
- @Override
- public void onAttach(Context context) {
- if (DEBUG) {
- Log.d(TAG, "onAttach");
- }
- AndroidInjection.inject(this);
- super.onAttach(context);
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
- if (DEBUG) {
- Log.d(TAG, "onCreate");
- }
+ if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
mVerticalPaddingBase =
getActivity()
@@ -134,6 +115,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
.getResources()
.getDimensionPixelOffset(
R.dimen.dvr_playback_overlay_padding_top_no_secondary_row);
+ mDvrDataManager = TvSingletons.getSingletons(getActivity()).getDvrDataManager();
if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
mDvrDataManager.addRecordedProgramLoadFinishedListener(
new DvrDataManager.OnRecordedProgramLoadFinishedListener() {
@@ -171,8 +153,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTvView = getActivity().findViewById(R.id.dvr_tv_view);
- mTvView.setUseSecureSurface(
- buildType != BuildType.ENG && !mLegacyFlags.enableDeveloperFeatures());
mBlockScreenView = getActivity().findViewById(R.id.block_screen);
mDvrPlayer = new DvrPlayer(mTvView, getActivity());
mMediaSessionHelper =
@@ -260,16 +240,13 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
setFadingEnabled(false);
long programId =
((RecordedProgram) itemViewHolder.view.getTag()).getId();
- if (DEBUG) {
- Log.d(TAG, "Play Related Recording:" + programId);
- }
+ if (DEBUG) Log.d(TAG, "Play Related Recording:" + programId);
Intent intent = new Intent(getContext(), DvrPlaybackActivity.class);
intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, programId);
getContext().startActivity(intent);
}
}
});
- mAudioManagerHelper = new AudioManagerHelper(getActivity(), mDvrPlayer.getView());
if (mProgram != null) {
setUpRows();
preparePlayback(getActivity().getIntent());
@@ -278,9 +255,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
@Override
public void onPause() {
- if (DEBUG) {
- Log.d(TAG, "onPause");
- }
+ if (DEBUG) Log.d(TAG, "onPause");
super.onPause();
if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING
|| mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_REWINDING) {
@@ -295,12 +270,9 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
@Override
public void onDestroy() {
- if (DEBUG) {
- Log.d(TAG, "onDestroy");
- }
+ if (DEBUG) Log.d(TAG, "onDestroy");
mPlaybackControlHelper.unregisterCallback();
mMediaSessionHelper.release();
- mAudioManagerHelper.abandonAudioFocus();
mRelatedRecordingCardPresenter.unbindAllViewHolders();
mDvrPlayer.release();
super.onDestroy();
@@ -444,7 +416,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
private void preparePlayback(Intent intent) {
mMediaSessionHelper.setupPlayback(mProgram, getSeekTimeFromIntent(intent));
mPlaybackControlHelper.updateSecondaryRow(false, false);
- mAudioManagerHelper.requestAudioFocus();
getActivity().getMediaController().getTransportControls().prepare();
updateRelatedRecordingsRow();
}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
index 95858e3c..b4481df8 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
@@ -19,8 +19,8 @@ package com.android.tv.dvr.ui.playback;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.TextUtils;
import android.transition.Transition;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
index 6cfa2e20..d14646b8 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
@@ -326,11 +326,6 @@ public class DvrPlayer {
return mProgram;
}
- /** Returns the DVR tv view. */
- public DvrTvView getView() {
- return mTvView;
- }
-
/** Returns the currrent playback posistion in msecs. */
public long getPlaybackPosition() {
return mTimeShiftCurrentPositionMs;
@@ -521,17 +516,13 @@ public class DvrPlayer {
for (TvTrackInfo trackInfo : trackInfos) {
if (trackInfo.getId().equals(trackId)) {
float videoAspectRatio;
- float videoPixelAspectRatio =
- trackInfo.getVideoPixelAspectRatio();
int videoWidth = trackInfo.getVideoWidth();
int videoHeight = trackInfo.getVideoHeight();
if (videoWidth > 0 && videoHeight > 0) {
videoAspectRatio =
- (float) trackInfo.getVideoWidth()
+ trackInfo.getVideoPixelAspectRatio()
+ * trackInfo.getVideoWidth()
/ trackInfo.getVideoHeight();
- videoAspectRatio *=
- videoPixelAspectRatio > 0 ?
- videoPixelAspectRatio : 1;
} else {
// Aspect ratio is unknown. Pass the message to
// listeners.
diff --git a/src/com/android/tv/features/TvFeatures.java b/src/com/android/tv/features/TvFeatures.java
index a18d9c89..208d53f6 100644
--- a/src/com/android/tv/features/TvFeatures.java
+++ b/src/com/android/tv/features/TvFeatures.java
@@ -27,11 +27,14 @@ import static com.android.tv.common.feature.FeatureUtils.or;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
-
+import android.support.annotation.VisibleForTesting;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.ExperimentFeature;
import com.android.tv.common.feature.Feature;
import com.android.tv.common.feature.FeatureUtils;
import com.android.tv.common.feature.FlagFeature;
+import com.android.tv.common.feature.PropertyFeature;
import com.android.tv.common.feature.Sdk;
import com.android.tv.common.feature.TestableFeature;
import com.android.tv.common.flags.has.HasUiFlags;
@@ -39,7 +42,7 @@ import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.common.util.PermissionUtils;
/**
- * List of {@link Feature} for the TV app.
+ * List of {@link Feature} for the Live TV App.
*
* <p>Remove the {@code Feature} once it is launched.
*/
@@ -48,6 +51,16 @@ public final class TvFeatures extends CommonFeatures {
/** When enabled store network affiliation information to TV provider */
public static final Feature STORE_NETWORK_AFFILIATION = ENG_ONLY_FEATURE;
+ /** When enabled use system setting for turning on analytics. */
+ public static final Feature ANALYTICS_OPT_IN =
+ ExperimentFeature.from(Experiments.ENABLE_ANALYTICS_VIA_CHECKBOX);
+ /**
+ * Analytics that include sensitive information such as channel or program identifiers.
+ *
+ * <p>See <a href="http://b/22062676">b/22062676</a>
+ */
+ public static final Feature ANALYTICS_V2 = and(ON, ANALYTICS_OPT_IN);
+
private static final Feature TV_PROVIDER_ALLOWS_INSERT_TO_PROGRAM_TABLE =
or(Sdk.AT_LEAST_O, PartnerFeatures.TVPROVIDER_ALLOWS_SYSTEM_INSERTS_TO_PROGRAM_TABLE);
@@ -74,7 +87,7 @@ public final class TvFeatures extends CommonFeatures {
or(
FlagFeature.from(
context -> HasSingletons.get(HasUiFlags.class, context),
- input -> input.getUiFlags().unhideLauncher()),
+ input -> input.getUiFlags().uhideLauncher()),
// If LC app runs as non-system app, we unhide the app.
not(PermissionUtils::hasAccessAllEpg));
@@ -101,5 +114,8 @@ public final class TvFeatures extends CommonFeatures {
/** Use input blacklist to disable partner's tuner input. */
public static final Feature USE_PARTNER_INPUT_BLACKLIST = ON;
+ @VisibleForTesting
+ public static final Feature TEST_FEATURE = PropertyFeature.create("test_feature", false);
+
private TvFeatures() {}
}
diff --git a/src/com/android/tv/guide/GenreListAdapter.java b/src/com/android/tv/guide/GenreListAdapter.java
index 995b053c..b4baf421 100644
--- a/src/com/android/tv/guide/GenreListAdapter.java
+++ b/src/com/android/tv/guide/GenreListAdapter.java
@@ -18,7 +18,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.support.annotation.MainThread;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/ProgramGrid.java b/src/com/android/tv/guide/ProgramGrid.java
index 96e161cd..caafb045 100644
--- a/src/com/android/tv/guide/ProgramGrid.java
+++ b/src/com/android/tv/guide/ProgramGrid.java
@@ -19,7 +19,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
@@ -256,19 +256,8 @@ public class ProgramGrid extends VerticalGridView {
scrollToPosition(getAdapter().getItemCount() - 1);
return null;
} else if (getSelectedPosition() == getAdapter().getItemCount() - 1) {
- int itemCount = getLayoutManager().getItemCount();
- int childCount = getChildCount();
- // b/129466363 For an item which overalps with previous layout GridLayoutManager
- // will scroll to first child of current layout, instead of going to previous one.
- // smoothscrollToPosition will invalidate all layouts and scroll to position 0.
- // This condition checks for an item which overlaps with the first layout
- if (itemCount > 2 * (childCount + 1) || itemCount <= childCount) {
- scrollToPosition(0);
- return null;
- } else {
- smoothScrollToPosition(0);
- return getChildAt(0);
- }
+ scrollToPosition(0);
+ return null;
}
return focused;
}
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index 8ae61e8a..bc1b11b6 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -32,7 +32,10 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.OnChildSelectedListener;
+import android.support.v17.leanback.widget.SearchOrbView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;
@@ -41,11 +44,6 @@ import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-
-import androidx.leanback.widget.OnChildSelectedListener;
-import androidx.leanback.widget.SearchOrbView;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.ChannelTuner;
import com.android.tv.MainActivity;
import com.android.tv.R;
@@ -67,9 +65,7 @@ import com.android.tv.ui.ViewUtils;
import com.android.tv.ui.hideable.AutoHideScheduler;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
-import com.android.tv.common.flags.UiFlags;
-
+import com.android.tv.common.flags.BackendKnobsFlags;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -116,7 +112,6 @@ public class ProgramGuide
private final int mAnimationDuration;
private final int mDetailPadding;
private final SearchOrbView mSearchOrb;
- private final UiFlags mUiFlags;
private int mCurrentTimeIndicatorWidth;
private final View mContainer;
@@ -190,14 +185,15 @@ public class ProgramGuide
mActivity = activity;
TvSingletons singletons = TvSingletons.getSingletons(mActivity);
mPerformanceMonitor = singletons.getPerformanceMonitor();
- mUiFlags = singletons.getUiFlags();
+ BackendKnobsFlags backendKnobsFlags = singletons.getBackendKnobs();
mProgramManager =
new ProgramManager(
tvInputManagerHelper,
channelDataManager,
programDataManager,
dvrDataManager,
- dvrScheduleManager);
+ dvrScheduleManager,
+ backendKnobsFlags);
mChannelTuner = channelTuner;
mTracker = tracker;
mPreShowRunnable = preShowRunnable;
@@ -265,7 +261,7 @@ public class ProgramGuide
}
});
mSidePanelGridView.setOnChildSelectedListener(
- new androidx.leanback.widget.OnChildSelectedListener() {
+ new android.support.v17.leanback.widget.OnChildSelectedListener() {
@Override
public void onChildSelected(ViewGroup viewGroup, View view, int i, long l) {
mSearchOrb.animate().alpha(i == 0 ? 1.0f : 0.0f);
@@ -286,8 +282,7 @@ public class ProgramGuide
res.getInteger(R.integer.max_recycled_view_pool_epg_header_row_item));
mTimelineRow.setAdapter(mTimeListAdapter);
- ProgramTableAdapter programTableAdapter =
- new ProgramTableAdapter(mActivity, this, mUiFlags);
+ ProgramTableAdapter programTableAdapter = new ProgramTableAdapter(mActivity, this);
programTableAdapter.registerAdapterDataObserver(
new RecyclerView.AdapterDataObserver() {
@Override
diff --git a/src/com/android/tv/guide/ProgramItemView.java b/src/com/android/tv/guide/ProgramItemView.java
index 5ec293f7..a46beab7 100644
--- a/src/com/android/tv/guide/ProgramItemView.java
+++ b/src/com/android/tv/guide/ProgramItemView.java
@@ -23,7 +23,6 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
-import android.os.Build;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -35,7 +34,6 @@ 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.TvSingletons;
@@ -43,22 +41,17 @@ import com.android.tv.analytics.Tracker;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.Clock;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.guide.ProgramManager.TableEntry;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
-
-import dagger.android.HasAndroidInjector;
-
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
public class ProgramItemView extends TextView {
private static final String TAG = "ProgramItemView";
@@ -80,8 +73,8 @@ public class ProgramItemView extends TextView {
private static TextAppearanceSpan sGrayedOutEpisodeTitleStyle;
private final DvrManager mDvrManager;
- @Inject Clock mClock;
- @Inject ChannelDataManager mChannelDataManager;
+ private final Clock mClock;
+ private final ChannelDataManager mChannelDataManager;
private ProgramGuide mProgramGuide;
private TableEntry mTableEntry;
private int mMaxWidthForRipple;
@@ -209,11 +202,12 @@ public class ProgramItemView extends TextView {
public ProgramItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- ((HasAndroidInjector) context).androidInjector().inject(this);
setOnClickListener(ON_CLICKED);
setOnFocusChangeListener(ON_FOCUS_CHANGED);
TvSingletons singletons = TvSingletons.getSingletons(getContext());
mDvrManager = singletons.getDvrManager();
+ mChannelDataManager = singletons.getChannelDataManager();
+ mClock = singletons.getClock();
}
private void initIfNeeded() {
@@ -536,9 +530,6 @@ public class ProgramItemView extends TextView {
}
private static int getStateCount(StateListDrawable stateListDrawable) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return stateListDrawable.getStateCount();
- }
try {
Object stateCount =
StateListDrawable.class
@@ -555,9 +546,6 @@ public class ProgramItemView extends TextView {
}
private static Drawable getStateDrawable(StateListDrawable stateListDrawable, int index) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return stateListDrawable.getStateDrawable(index);
- }
try {
Object drawable =
StateListDrawable.class
diff --git a/src/com/android/tv/guide/ProgramListAdapter.java b/src/com/android/tv/guide/ProgramListAdapter.java
index 68ae43ee..397bacfb 100644
--- a/src/com/android/tv/guide/ProgramListAdapter.java
+++ b/src/com/android/tv/guide/ProgramListAdapter.java
@@ -17,7 +17,7 @@
package com.android.tv.guide;
import android.content.res.Resources;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/ProgramManager.java b/src/com/android/tv/guide/ProgramManager.java
index 516a4d9c..3a5a4a02 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -21,20 +21,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
-
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.data.ProgramImpl;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrScheduleManager.OnConflictStateChangeListener;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
+import com.android.tv.common.flags.BackendKnobsFlags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -62,6 +60,7 @@ public class ProgramManager {
private final ProgramDataManager mProgramDataManager;
private final DvrDataManager mDvrDataManager; // Only set if DVR is enabled
private final DvrScheduleManager mDvrScheduleManager;
+ private final BackendKnobsFlags mBackendKnobsFlags;
private long mStartUtcMillis;
private long mEndUtcMillis;
@@ -125,8 +124,16 @@ public class ProgramManager {
}
@Override
- public void onChannelUpdated() {
- updateTableEntriesWithoutNotification(false);
+ public void onSingleChannelUpdated(long channelId) {
+ boolean parentalControlsEnabled =
+ mTvInputManagerHelper
+ .getParentalControlSettings()
+ .isParentalControlsEnabled();
+ // Inline the updating of the mChannelIdEntriesMap here so we can only call
+ // getParentalControlSettings once.
+ List<TableEntry> entries =
+ createProgramEntries(channelId, parentalControlsEnabled);
+ mChannelIdEntriesMap.put(channelId, entries);
notifyTableEntriesUpdated();
}
};
@@ -208,12 +215,14 @@ public class ProgramManager {
ChannelDataManager channelDataManager,
ProgramDataManager programDataManager,
@Nullable DvrDataManager dvrDataManager,
- @Nullable DvrScheduleManager dvrScheduleManager) {
+ @Nullable DvrScheduleManager dvrScheduleManager,
+ BackendKnobsFlags backendKnobsFlags) {
mTvInputManagerHelper = tvInputManagerHelper;
mChannelDataManager = channelDataManager;
mProgramDataManager = programDataManager;
mDvrDataManager = dvrDataManager;
mDvrScheduleManager = dvrScheduleManager;
+ mBackendKnobsFlags = backendKnobsFlags;
}
void programGuideVisibilityChanged(boolean visible) {
@@ -242,6 +251,7 @@ public class ProgramManager {
mDvrScheduleManager.removeOnConflictStateChangeListener(
mOnConflictStateChangeListener);
}
+ mChannelIdEntriesMap.clear();
}
}
@@ -416,12 +426,14 @@ public class ProgramManager {
}
/**
- * Returns an entry as {@link ProgramImpl} for a given {@code channelId} and {@code index} of
- * entries within the currently managed time range. Returned {@link ProgramImpl} can be a dummy
- * one (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
+ * Returns an entry as {@link Program} for a given {@code channelId} and {@code index} of
+ * entries within the currently managed time range. Returned {@link Program} can be a dummy one
+ * (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
*/
TableEntry getTableEntry(long channelId, int index) {
- mProgramDataManager.prefetchChannel(channelId, index);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mProgramDataManager.prefetchChannel(channelId);
+ }
return mChannelIdEntriesMap.get(channelId).get(index);
}
@@ -695,7 +707,7 @@ public class ProgramManager {
/**
* Entry for program guide table. An "entry" can be either an actual program or a gap between
* programs. This is needed for {@link ProgramListAdapter} because {@link
- * androidx.leanback.widget.HorizontalGridView} ignores margins between items.
+ * android.support.v17.leanback.widget.HorizontalGridView} ignores margins between items.
*/
static class TableEntry {
/** Channel ID which this entry is included. */
@@ -725,7 +737,7 @@ public class ProgramManager {
private TableEntry(
long channelId,
- ProgramImpl program,
+ Program program,
long entryStartUtcMillis,
long entryEndUtcMillis,
boolean isBlocked) {
@@ -747,7 +759,7 @@ public class ProgramManager {
mIsBlocked = isBlocked;
}
- /** A stable id useful for {@link androidx.recyclerview.widget.RecyclerView.Adapter}. */
+ /** A stable id useful for {@link android.support.v7.widget.RecyclerView.Adapter}. */
long getId() {
// using a negative entryEndUtcMillis keeps it from conflicting with program Id
return program != null ? program.getId() : -entryEndUtcMillis;
diff --git a/src/com/android/tv/guide/ProgramRow.java b/src/com/android/tv/guide/ProgramRow.java
index 6f8f31c1..3317c15f 100644
--- a/src/com/android/tv/guide/ProgramRow.java
+++ b/src/com/android/tv/guide/ProgramRow.java
@@ -18,7 +18,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.graphics.Rect;
-import androidx.recyclerview.widget.LinearLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
diff --git a/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java b/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
index a6a4624b..5e498be4 100644
--- a/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
+++ b/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
@@ -17,8 +17,8 @@
package com.android.tv.guide;
import android.os.Bundle;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerViewAccessibilityDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
diff --git a/src/com/android/tv/guide/ProgramTableAdapter.java b/src/com/android/tv/guide/ProgramTableAdapter.java
index aed8b900..7576bf50 100644
--- a/src/com/android/tv/guide/ProgramTableAdapter.java
+++ b/src/com/android/tv/guide/ProgramTableAdapter.java
@@ -28,8 +28,8 @@ import android.media.tv.TvInputInfo;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.RecycledViewPool;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.RecycledViewPool;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
@@ -47,14 +47,13 @@ import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeL
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
+import com.android.tv.data.Program.CriticScore;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.api.Program.CriticScore;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -68,8 +67,6 @@ import com.android.tv.util.images.ImageLoader;
import com.android.tv.util.images.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.images.ImageLoader.LoadTvInputLogoTask;
-import com.android.tv.common.flags.UiFlags;
-
import java.util.ArrayList;
import java.util.List;
@@ -112,11 +109,10 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
private final String mRecordingInProgressText;
private final int mDvrPaddingStartWithTrack;
private final int mDvrPaddingStartWithOutTrack;
- private final UiFlags mUiFlags;
private RecyclerView mRecyclerView;
- ProgramTableAdapter(Context context, ProgramGuide programGuide, UiFlags uiFlags) {
+ ProgramTableAdapter(Context context, ProgramGuide programGuide) {
mContext = context;
mAccessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -130,7 +126,6 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
}
mProgramGuide = programGuide;
mProgramManager = programGuide.getProgramManager();
- mUiFlags = uiFlags;
Resources res = context.getResources();
mChannelLogoWidth =
@@ -661,35 +656,6 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
mDvrIndicator.setVisibility(View.GONE);
}
- if (mUiFlags.enableCriticRatings()) {
- // display critic scores if any exist
- List<CriticScore> criticScores = program.getCriticScores();
- if (criticScores != null) {
- // inflate more critic score views if required
- if (criticScores.size() > mCriticScoreViews.size()) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- LinearLayout layout =
- (LinearLayout)
- inflater.inflate(
- R.layout.program_guide_critic_score_layout,
- null);
- mCriticScoreViews.add(layout);
- }
- // fill critic score views and add to layout
- for (int i = 0; i < criticScores.size(); i++) {
- View criticScoreView = mCriticScoreViews.get(i);
- ViewParent previousParentView = criticScoreView.getParent();
- if (previousParentView != null
- && previousParentView instanceof ViewGroup) {
- ((ViewGroup) previousParentView).removeView(criticScoreView);
- }
- updateCriticScoreView(
- this, program.getId(), criticScores.get(i), criticScoreView);
- mCriticScoresLayout.addView(mCriticScoreViews.get(i));
- }
- }
- }
-
if (blockedRating == null) {
mBlockView.setVisibility(View.GONE);
updateTextView(mDescriptionView, program.getDescription());
diff --git a/src/com/android/tv/guide/TimeListAdapter.java b/src/com/android/tv/guide/TimeListAdapter.java
index 62fec69a..9c10c952 100644
--- a/src/com/android/tv/guide/TimeListAdapter.java
+++ b/src/com/android/tv/guide/TimeListAdapter.java
@@ -17,7 +17,7 @@
package com.android.tv.guide;
import android.content.res.Resources;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/TimelineGridView.java b/src/com/android/tv/guide/TimelineGridView.java
index 2d257878..c4922b75 100644
--- a/src/com/android/tv/guide/TimelineGridView.java
+++ b/src/com/android/tv/guide/TimelineGridView.java
@@ -17,8 +17,8 @@
package com.android.tv.guide;
import android.content.Context;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
diff --git a/src/com/android/tv/menu/ActionCardView.java b/src/com/android/tv/menu/ActionCardView.java
index 0e789c67..3ecd5f5c 100644
--- a/src/com/android/tv/menu/ActionCardView.java
+++ b/src/com/android/tv/menu/ActionCardView.java
@@ -19,7 +19,6 @@ package com.android.tv.menu;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -94,13 +93,6 @@ public class ActionCardView extends RelativeLayout implements ItemListRowView.Ca
}
}
- /** Request focus and accessibility focus on card view. */
- @Override
- public boolean requestFocusWithAccessibility() {
- return requestFocus() &&
- performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
-
@Override
public void onRecycled() {}
}
diff --git a/src/com/android/tv/menu/AppLinkCardView.java b/src/com/android/tv/menu/AppLinkCardView.java
index 49d32fed..fd93c314 100644
--- a/src/com/android/tv/menu/AppLinkCardView.java
+++ b/src/com/android/tv/menu/AppLinkCardView.java
@@ -26,13 +26,13 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
-import androidx.palette.graphics.Palette;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.data.api.Channel;
diff --git a/src/com/android/tv/menu/BaseCardView.java b/src/com/android/tv/menu/BaseCardView.java
index ed78cb73..3a94ebbf 100644
--- a/src/com/android/tv/menu/BaseCardView.java
+++ b/src/com/android/tv/menu/BaseCardView.java
@@ -27,7 +27,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
@@ -136,13 +135,6 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
}
}
- /** Request focus and accessibility focus on card view. */
- @Override
- public boolean requestFocusWithAccessibility() {
- return requestFocus() &&
- performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
-
/** Sets text of this card view. */
public void setText(int resId) {
if (mTextResId != resId) {
diff --git a/src/com/android/tv/menu/ChannelCardView.java b/src/com/android/tv/menu/ChannelCardView.java
index 7fe5e491..76056ee4 100644
--- a/src/com/android/tv/menu/ChannelCardView.java
+++ b/src/com/android/tv/menu/ChannelCardView.java
@@ -26,14 +26,12 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.images.ImageLoader;
-
import java.util.Objects;
/** A view to render channel card. */
diff --git a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
index 3a502304..9cecb9c0 100644
--- a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
+++ b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
@@ -23,15 +23,13 @@ import android.os.Message;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.util.Log;
-
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.util.List;
/** A poster image prefetcher to show the program poster art in the Channels row faster. */
diff --git a/src/com/android/tv/menu/ChannelsRow.java b/src/com/android/tv/menu/ChannelsRow.java
index dbfc7820..7d03bf2b 100644
--- a/src/com/android/tv/menu/ChannelsRow.java
+++ b/src/com/android/tv/menu/ChannelsRow.java
@@ -73,7 +73,6 @@ public class ChannelsRow extends ItemListRow {
mTvRecommendation = null;
}
mChannelsPosterPrefetcher.cancel();
- mChannelsAdapter.release();
}
/** Handle the update event of the recent channel. */
diff --git a/src/com/android/tv/menu/ChannelsRowAdapter.java b/src/com/android/tv/menu/ChannelsRowAdapter.java
index e6b61037..4a9e4765 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -47,7 +47,6 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
private final int mMaxCount;
private final int mMinCount;
private final ChannelChanger mChannelChanger;
- private final AccessibilityManager mAccessibilityManager;
private boolean mShowChannelUpDown;
@@ -67,9 +66,10 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
mMaxCount = maxCount;
setHasStableIds(true);
mChannelChanger = (ChannelChanger) (context);
- mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
- mShowChannelUpDown = mAccessibilityManager.isEnabled();
- mAccessibilityManager.addAccessibilityStateChangeListener(this);
+ AccessibilityManager accessibilityManager =
+ context.getSystemService(AccessibilityManager.class);
+ mShowChannelUpDown = accessibilityManager.isEnabled();
+ accessibilityManager.addAccessibilityStateChangeListener(this);
}
@Override
@@ -316,10 +316,4 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
mShowChannelUpDown = enabled;
update();
}
-
- @Override
- public void release() {
- mAccessibilityManager.removeAccessibilityStateChangeListener(this);
- super.release();
- }
}
diff --git a/src/com/android/tv/menu/ItemListRowView.java b/src/com/android/tv/menu/ItemListRowView.java
index cc6d23c3..7042324d 100644
--- a/src/com/android/tv/menu/ItemListRowView.java
+++ b/src/com/android/tv/menu/ItemListRowView.java
@@ -17,9 +17,9 @@
package com.android.tv.menu;
import android.content.Context;
-import androidx.leanback.widget.HorizontalGridView;
-import androidx.leanback.widget.OnChildSelectedListener;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.HorizontalGridView;
+import android.support.v17.leanback.widget.OnChildSelectedListener;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
@@ -44,8 +44,6 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
void onSelected();
void onDeselected();
-
- boolean requestFocusWithAccessibility();
}
private HorizontalGridView mListView;
@@ -116,13 +114,6 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
}
}
- @Override
- protected void requestChildFocus() {
- if (mSelectedCard != null) {
- mSelectedCard.requestFocusWithAccessibility();
- }
- }
-
public abstract static class ItemListAdapter<T>
extends RecyclerView.Adapter<ItemListAdapter.MyViewHolder> {
private final MainActivity mMainActivity;
diff --git a/src/com/android/tv/menu/Menu.java b/src/com/android/tv/menu/Menu.java
index 0687441e..6bdbf87b 100644
--- a/src/com/android/tv/menu/Menu.java
+++ b/src/com/android/tv/menu/Menu.java
@@ -23,7 +23,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
-import androidx.leanback.widget.HorizontalGridView;
+import android.support.v17.leanback.widget.HorizontalGridView;
import android.util.Log;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import com.android.tv.ChannelTuner;
diff --git a/src/com/android/tv/menu/MenuLayoutManager.java b/src/com/android/tv/menu/MenuLayoutManager.java
index 8f95db77..a600f704 100644
--- a/src/com/android/tv/menu/MenuLayoutManager.java
+++ b/src/com/android/tv/menu/MenuLayoutManager.java
@@ -25,15 +25,15 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.support.annotation.UiThread;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v4.view.animation.FastOutLinearInInterpolator;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
+import android.support.v4.view.animation.LinearOutSlowInInterpolator;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.Property;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.TextView;
-import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
-import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
-import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.util.Utils;
diff --git a/src/com/android/tv/menu/MenuRow.java b/src/com/android/tv/menu/MenuRow.java
index 0945a0c5..8dc12bad 100644
--- a/src/com/android/tv/menu/MenuRow.java
+++ b/src/com/android/tv/menu/MenuRow.java
@@ -31,8 +31,6 @@ public abstract class MenuRow {
private MenuRowView mMenuRowView;
- private boolean mIsReselected = false;
-
// TODO: Check if the heightResId is really necessary.
public MenuRow(Context context, Menu menu, int titleResId, int heightResId) {
this(context, menu, context.getString(titleResId), heightResId);
@@ -102,19 +100,4 @@ public abstract class MenuRow {
public boolean hideTitleWhenSelected() {
return false;
}
-
- /**
- * Sets if menu row is reselected.
- *
- * @param isReselected {@code true} if row is reselected;
- * else {@code false}.
- */
- public void setIsReselected(boolean isReselected) {
- mIsReselected = isReselected;
- }
-
- /** Returns true if row is reselected. */
- public boolean isReselected() {
- return mIsReselected;
- }
}
diff --git a/src/com/android/tv/menu/MenuRowFactory.java b/src/com/android/tv/menu/MenuRowFactory.java
index a3837a10..048d725d 100644
--- a/src/com/android/tv/menu/MenuRowFactory.java
+++ b/src/com/android/tv/menu/MenuRowFactory.java
@@ -24,7 +24,6 @@ import com.android.tv.R;
import com.android.tv.common.customization.CustomAction;
import com.android.tv.common.customization.CustomizationManager;
import com.android.tv.ui.TunableTvView;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.List;
/** A factory class to create menu rows. */
@@ -32,15 +31,12 @@ public class MenuRowFactory {
private final MainActivity mMainActivity;
private final TunableTvView mTvView;
private final CustomizationManager mCustomizationManager;
- private final LegacyFlags mLegacyFlags;
/** A constructor. */
- public MenuRowFactory(
- MainActivity mainActivity, TunableTvView tvView, LegacyFlags mLegacyFlags) {
+ public MenuRowFactory(MainActivity mainActivity, TunableTvView tvView) {
mMainActivity = mainActivity;
mTvView = tvView;
mCustomizationManager = new CustomizationManager(mainActivity);
- this.mLegacyFlags = mLegacyFlags;
mCustomizationManager.initialize();
}
@@ -64,8 +60,7 @@ public class MenuRowFactory {
return new TvOptionsRow(
mMainActivity,
menu,
- mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW),
- mLegacyFlags);
+ mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW));
}
return null;
}
@@ -75,17 +70,13 @@ public class MenuRowFactory {
/** The ID of the row. */
public static final String ID = TvOptionsRow.class.getName();
- private TvOptionsRow(
- Context context,
- Menu menu,
- List<CustomAction> customActions,
- LegacyFlags legacyFlags) {
+ private TvOptionsRow(Context context, Menu menu, List<CustomAction> customActions) {
super(
context,
menu,
R.string.menu_title_options,
R.dimen.action_card_height,
- new TvOptionsRowAdapter(context, customActions, legacyFlags));
+ new TvOptionsRowAdapter(context, customActions));
}
}
diff --git a/src/com/android/tv/menu/MenuRowView.java b/src/com/android/tv/menu/MenuRowView.java
index e09a4ef0..a064f352 100644
--- a/src/com/android/tv/menu/MenuRowView.java
+++ b/src/com/android/tv/menu/MenuRowView.java
@@ -25,7 +25,6 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
@@ -90,18 +89,6 @@ public abstract class MenuRowView extends LinearLayout {
float textSizeDeselected =
res.getDimensionPixelSize(R.dimen.menu_row_title_text_size_deselected);
mTitleViewScaleSelected = textSizeSelected / textSizeDeselected;
- this.setAccessibilityDelegate(
- new AccessibilityDelegate() {
- @Override
- public void sendAccessibilityEvent(View host, int eventType) {
- super.sendAccessibilityEvent(host, eventType);
- if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED &&
- !mRow.isReselected()) {
- requestChildFocus();
- }
- }
- }
- );
}
@Override
@@ -190,9 +177,6 @@ public abstract class MenuRowView extends LinearLayout {
mLastFocusView = v;
}
- /** Subclasses should implement this to request focus on child. */
- protected abstract void requestChildFocus();
-
/**
* Called when the focus of a child view is changed. The inherited class should override this
* method instead of calling {@link
diff --git a/src/com/android/tv/menu/MenuView.java b/src/com/android/tv/menu/MenuView.java
index add4a774..f5fec000 100644
--- a/src/com/android/tv/menu/MenuView.java
+++ b/src/com/android/tv/menu/MenuView.java
@@ -250,40 +250,39 @@ public class MenuView extends FrameLayout implements IMenuView {
// The bounds of the views move and overlap with each other during the animation. In this
// situation, the framework can't perform the correct focus navigation. So the menu view
// should search by itself.
- if (direction == View.FOCUS_UP || direction == View.FOCUS_DOWN) {
- return getUpDownFocus(focused, direction);
- }
- return super.focusSearch(focused, direction);
- }
-
- private View getUpDownFocus(View focused, int direction) {
- View newView = super.focusSearch(focused, direction);
- MenuRowView oldfocusedParent = getParentMenuRowView(focused);
- MenuRowView newFocusedParent = getParentMenuRowView(newView);
- int selectedPosition = mLayoutManager.getSelectedPosition();
- int start, delta;
if (direction == View.FOCUS_UP) {
- start = selectedPosition - 1;
- delta = -1;
- } else {
- start = selectedPosition + 1;
- delta = 1;
- }
- if (newFocusedParent != oldfocusedParent) {
- // The focus leaves from the current menu row view.
- int count = mMenuRowViews.size();
- int i = start;
- while (i < count && i >= 0) {
- MenuRowView view = mMenuRowViews.get(i);
- if (view.getVisibility() == View.VISIBLE) {
- mMenuRows.get(i).setIsReselected(false);
- return view;
+ View newView = super.focusSearch(focused, direction);
+ MenuRowView oldfocusedParent = getParentMenuRowView(focused);
+ MenuRowView newFocusedParent = getParentMenuRowView(newView);
+ int selectedPosition = mLayoutManager.getSelectedPosition();
+ if (newFocusedParent != oldfocusedParent) {
+ // The focus leaves from the current menu row view.
+ for (int i = selectedPosition - 1; i >= 0; --i) {
+ MenuRowView view = mMenuRowViews.get(i);
+ if (view.getVisibility() == View.VISIBLE) {
+ return view;
+ }
+ }
+ }
+ return newView;
+ } else if (direction == View.FOCUS_DOWN) {
+ View newView = super.focusSearch(focused, direction);
+ MenuRowView oldfocusedParent = getParentMenuRowView(focused);
+ MenuRowView newFocusedParent = getParentMenuRowView(newView);
+ int selectedPosition = mLayoutManager.getSelectedPosition();
+ if (newFocusedParent != oldfocusedParent) {
+ // The focus leaves from the current menu row view.
+ int count = mMenuRowViews.size();
+ for (int i = selectedPosition + 1; i < count; ++i) {
+ MenuRowView view = mMenuRowViews.get(i);
+ if (view.getVisibility() == View.VISIBLE) {
+ return view;
+ }
}
- i += delta;
}
+ return newView;
}
- mMenuRows.get(selectedPosition).setIsReselected(true);
- return newView;
+ return super.focusSearch(focused, direction);
}
private MenuRowView getParentMenuRowView(View view) {
diff --git a/src/com/android/tv/menu/PlayControlsButton.java b/src/com/android/tv/menu/PlayControlsButton.java
index 1b85d632..ac3292a3 100644
--- a/src/com/android/tv/menu/PlayControlsButton.java
+++ b/src/com/android/tv/menu/PlayControlsButton.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -147,11 +146,4 @@ public class PlayControlsButton extends FrameLayout {
mIcon.setAlpha(enabled ? ALPHA_ENABLED : ALPHA_DISABLED);
mLabel.setEnabled(enabled);
}
-
- /** Request focus and accessibility focus to the button */
- public boolean requestFocusWithAccessibility() {
- return mButton.requestFocus() &&
- mButton.performAccessibilityAction(
- AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
}
diff --git a/src/com/android/tv/menu/PlayControlsRowView.java b/src/com/android/tv/menu/PlayControlsRowView.java
index 5dde3be0..0ce74ae1 100644
--- a/src/com/android/tv/menu/PlayControlsRowView.java
+++ b/src/com/android/tv/menu/PlayControlsRowView.java
@@ -24,7 +24,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TimeShiftManager;
@@ -32,8 +31,8 @@ import com.android.tv.TimeShiftManager.TimeShiftActionId;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
@@ -488,11 +487,6 @@ public class PlayControlsRowView extends MenuRowView {
}
}
- @Override
- protected void requestChildFocus() {
- mPlayPauseButton.requestFocusWithAccessibility();
- }
-
/** Updates the view contents. It is called from the PlayControlsRow. */
public void update() {
updateAll(false);
diff --git a/src/com/android/tv/menu/TvOptionsRowAdapter.java b/src/com/android/tv/menu/TvOptionsRowAdapter.java
index 418560a8..fe52b25e 100644
--- a/src/com/android/tv/menu/TvOptionsRowAdapter.java
+++ b/src/com/android/tv/menu/TvOptionsRowAdapter.java
@@ -19,8 +19,8 @@ package com.android.tv.menu;
import android.content.Context;
import android.media.tv.TvTrackInfo;
import com.android.tv.TvOptionsManager;
-import com.android.tv.common.BuildConfig;
import com.android.tv.common.customization.CustomAction;
+import com.android.tv.common.util.CommonUtils;
import com.android.tv.data.DisplayMode;
import com.android.tv.features.TvFeatures;
import com.android.tv.ui.TvViewUiManager;
@@ -28,7 +28,6 @@ import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.List;
@@ -36,12 +35,8 @@ import java.util.List;
* An adapter of options.
*/
public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
- private final LegacyFlags mLegacyFlags;
-
- public TvOptionsRowAdapter(
- Context context, List<CustomAction> customActions, LegacyFlags mLegacyFlags) {
+ public TvOptionsRowAdapter(Context context, List<CustomAction> customActions) {
super(context, customActions);
- this.mLegacyFlags = mLegacyFlags;
}
@Override
@@ -54,7 +49,7 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
}
actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
actionList.add(MenuAction.MORE_CHANNELS_ACTION);
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
actionList.add(MenuAction.DEV_ACTION);
}
actionList.add(MenuAction.SETTINGS_ACTION);
diff --git a/src/com/android/tv/modules/TvApplicationModule.java b/src/com/android/tv/modules/TvApplicationModule.java
index 99753d1e..45383ae1 100644
--- a/src/com/android/tv/modules/TvApplicationModule.java
+++ b/src/com/android/tv/modules/TvApplicationModule.java
@@ -16,101 +16,43 @@
package com.android.tv.modules;
import android.content.Context;
-
import com.android.tv.MainActivity;
-import com.android.tv.SetupPassthroughActivity;
import com.android.tv.TvApplication;
-import com.android.tv.common.buildtype.BuildTypeModule;
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.dagger.annotations.ApplicationContext;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ChannelDataManagerFactory;
-import com.android.tv.data.epg.EpgFetchService;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.data.epg.EpgFetcherImpl;
-import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrDataManagerImpl;
-import com.android.tv.dvr.WritableDvrDataManager;
-import com.android.tv.dvr.ui.playback.DvrPlaybackActivity;
import com.android.tv.onboarding.OnboardingActivity;
-import com.android.tv.onboarding.SetupSourcesFragment;
-import com.android.tv.setup.SystemSetupActivity;
-import com.android.tv.ui.DetailsActivity;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TvInputManagerHelper;
-
-import dagger.Binds;
import dagger.Module;
import dagger.Provides;
-import dagger.android.ContributesAndroidInjector;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-
import javax.inject.Singleton;
/** Dagger module for {@link TvApplication}. */
@Module(
includes = {
ApplicationModule.class,
- BuildTypeModule.class,
- DetailsActivity.Module.class,
- DvrPlaybackActivity.Module.class,
- MainActivity.Module.class,
- OnboardingActivity.Module.class,
- SetupPassthroughActivity.Module.class,
- SetupSourcesFragment.ContentFragment.Module.class,
- SystemSetupActivity.Module.class,
TvSingletonsModule.class,
+ MainActivity.Module.class,
+ OnboardingActivity.Module.class
})
-public abstract class TvApplicationModule {
+public class TvApplicationModule {
private static final NamedThreadFactory THREAD_FACTORY = new NamedThreadFactory("tv-app-db");
@Provides
@AsyncDbTask.DbExecutor
@Singleton
- static Executor providesDbExecutor() {
+ Executor providesDbExecutor() {
return Executors.newSingleThreadExecutor(THREAD_FACTORY);
}
@Provides
@Singleton
- static TvInputManagerHelper providesTvInputManagerHelper(
- @ApplicationContext Context context, LegacyFlags legacyFlags) {
- TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context, legacyFlags);
+ TvInputManagerHelper providesTvInputManagerHelper(@ApplicationContext Context context) {
+ TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context);
tvInputManagerHelper.start();
- // Since this is injected as a Lazy in the application start is delayed.
return tvInputManagerHelper;
}
-
- @Provides
- @Singleton
- static ChannelDataManager providesChannelDataManager(ChannelDataManagerFactory factory) {
- ChannelDataManager channelDataManager = factory.create();
- channelDataManager.start();
- // Since this is injected as a Lazy in the application start is delayed.
- return channelDataManager;
- }
-
- @Binds
- @Singleton
- abstract DvrDataManager providesDvrDataManager(DvrDataManagerImpl impl);
-
- @Binds
- @Singleton
- abstract WritableDvrDataManager providesWritableDvrDataManager(DvrDataManagerImpl impl);
-
- @Binds
- @Singleton
- abstract EpgFetcher epgFetcher(EpgFetcherImpl impl);
-
- @ContributesAndroidInjector
- abstract PinDialogFragment contributesPinDialogFragment();
-
- @ContributesAndroidInjector
- abstract EpgFetchService contributesEpgFetchService();
}
diff --git a/src/com/android/tv/modules/TvSingletonsModule.java b/src/com/android/tv/modules/TvSingletonsModule.java
index f8d10fde..f998c08b 100644
--- a/src/com/android/tv/modules/TvSingletonsModule.java
+++ b/src/com/android/tv/modules/TvSingletonsModule.java
@@ -16,9 +16,8 @@
package com.android.tv.modules;
import com.android.tv.TvSingletons;
+import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-
import dagger.Module;
import dagger.Provides;
@@ -37,8 +36,8 @@ public class TvSingletonsModule {
}
@Provides
- DvrWatchedPositionManager providesDvrWatchedPositionManager() {
- return mTvSingletons.getDvrWatchedPositionManager();
+ ChannelDataManager providesChannelDataManager() {
+ return mTvSingletons.getChannelDataManager();
}
@Provides
diff --git a/src/com/android/tv/onboarding/OnboardingActivity.java b/src/com/android/tv/onboarding/OnboardingActivity.java
index 1739e5a0..776ae664 100644
--- a/src/com/android/tv/onboarding/OnboardingActivity.java
+++ b/src/com/android/tv/onboarding/OnboardingActivity.java
@@ -88,7 +88,7 @@ public class OnboardingActivity extends SetupActivity {
TvSingletons singletons = TvSingletons.getSingletons(this);
mInputManager = singletons.getTvInputManagerHelper();
if (PermissionUtils.hasAccessAllEpg(this) || PermissionUtils.hasReadTvListings(this)) {
- // Make the channels of the new inputs which have been setup outside TV app
+ // Make the channels of the new inputs which have been setup outside Live TV
// browsable.
if (mChannelDataManager.isDbLoadFinished()) {
mSetupUtils.markNewChannelsBrowsable();
@@ -187,7 +187,7 @@ public class OnboardingActivity extends SetupActivity {
}
// Even though other app can handle the intent, the setup launched by
// Live
- // channels should go through TV app SetupPassthroughActivity.
+ // channels should go through Live channels SetupPassthroughActivity.
intent.setComponent(
new ComponentName(this, SetupPassthroughActivity.class));
try {
diff --git a/src/com/android/tv/onboarding/SetupSourcesFragment.java b/src/com/android/tv/onboarding/SetupSourcesFragment.java
index b54d1bc9..3566c9c3 100644
--- a/src/com/android/tv/onboarding/SetupSourcesFragment.java
+++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java
@@ -16,44 +16,33 @@
package com.android.tv.onboarding;
-import android.app.Activity;
+import android.content.Context;
import android.graphics.Typeface;
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.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.TvInputNewComparator;
-import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.android.tv.ui.GuidedActionsStylistWithDivider;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-
-import com.google.common.base.Optional;
-
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import javax.inject.Inject;
-
/** A fragment for channel source info/setup. */
public class SetupSourcesFragment extends SetupMultiPaneFragment {
/** The action category for the actions which is fired from this fragment. */
@@ -117,10 +106,9 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
private static final int PENDING_ACTION_INPUT_CHANGED = 1;
private static final int PENDING_ACTION_CHANNEL_CHANGED = 2;
- @Inject TvInputManagerHelper mInputManager;
- @Inject ChannelDataManager mChannelDataManager;
- @Inject SetupUtils mSetupUtils;
- @Inject Optional<BuiltInTunerManager> mBuiltInTunerManagerOptional;
+ private TvInputManagerHelper mInputManager;
+ private ChannelDataManager mChannelDataManager;
+ private SetupUtils mSetupUtils;
private List<TvInputInfo> mInputs;
private int mKnownInputStartIndex;
private int mDoneInputStartIndex;
@@ -199,38 +187,37 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mParentFragment = (SetupSourcesFragment) getParentFragment();
- }
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
+ Context context = getActivity();
+ TvSingletons singletons = TvSingletons.getSingletons(context);
+ mInputManager = singletons.getTvInputManagerHelper();
+ mChannelDataManager = singletons.getChannelDataManager();
+ mSetupUtils = singletons.getSetupUtils();
buildInputs();
mInputManager.addCallback(mInputCallback);
mChannelDataManager.addListener(mChannelDataManagerListener);
+ super.onCreate(savedInstanceState);
mParentFragment = (SetupSourcesFragment) getParentFragment();
- if (mBuiltInTunerManagerOptional.isPresent()) {
- mBuiltInTunerManagerOptional
+ if (singletons.getBuiltInTunerManager().isPresent()) {
+ singletons
+ .getBuiltInTunerManager()
.get()
.getTunerInputController()
- .executeNetworkTunerDiscoveryAsyncTask(activity);
+ .executeNetworkTunerDiscoveryAsyncTask(getContext());
}
}
@Override
- public void onDetach() {
+ public void onDestroy() {
+ super.onDestroy();
mChannelDataManager.removeListener(mChannelDataManagerListener);
mInputManager.removeCallback(mInputCallback);
- super.onDetach();
}
@NonNull
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
String title = getString(R.string.setup_sources_text);
- String description = getString(R.string.setup_sources_description2);
+ String description = getString(R.string.setup_sources_description);
return new Guidance(title, description, null, null);
}
@@ -417,13 +404,5 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
setAccessibilityDelegate(vh, action);
}
}
- /**
- * Exports {@link ContentFragment} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract ContentFragment contributesContentFragment();
- }
}
}
diff --git a/src/com/android/tv/onboarding/WelcomeFragment.java b/src/com/android/tv/onboarding/WelcomeFragment.java
index 667da058..8c119a8a 100644
--- a/src/com/android/tv/onboarding/WelcomeFragment.java
+++ b/src/com/android/tv/onboarding/WelcomeFragment.java
@@ -25,7 +25,7 @@ import android.animation.AnimatorSet;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.app.OnboardingFragment;
+import android.support.v17.leanback.app.OnboardingFragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
@@ -621,9 +621,9 @@ public class WelcomeFragment extends OnboardingFragment {
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
setLogoResourceId(R.drawable.splash_logo);
- mTitleView = view.findViewById(androidx.leanback.R.id.title);
- mPagingIndicator = view.findViewById(androidx.leanback.R.id.page_indicator);
- mStartButton = view.findViewById(androidx.leanback.R.id.button_start);
+ mTitleView = view.findViewById(android.support.v17.leanback.R.id.title);
+ mPagingIndicator = view.findViewById(android.support.v17.leanback.R.id.page_indicator);
+ mStartButton = view.findViewById(android.support.v17.leanback.R.id.button_start);
mStartButton.setAccessibilityDelegate(
new AccessibilityDelegate() {
diff --git a/src/com/android/tv/parental/ContentRatingsManager.java b/src/com/android/tv/parental/ContentRatingsManager.java
index 174039ba..32a1325b 100644
--- a/src/com/android/tv/parental/ContentRatingsManager.java
+++ b/src/com/android/tv/parental/ContentRatingsManager.java
@@ -22,7 +22,6 @@ import android.media.tv.TvContentRatingSystemInfo;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.android.tv.R;
-import com.android.tv.common.util.PermissionUtils;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import com.android.tv.util.TvInputManagerHelper;
@@ -43,14 +42,13 @@ public class ContentRatingsManager {
public void update() {
mContentRatingSystems.clear();
- if (PermissionUtils.hasReadContetnRatingSystem(mContext)) {
- ContentRatingsParser parser = new ContentRatingsParser(mContext);
- List<TvContentRatingSystemInfo> infos = mTvInputManager.getTvContentRatingSystemList();
- for (TvContentRatingSystemInfo info : infos) {
- List<ContentRatingSystem> list = parser.parse(info);
- if (list != null) {
- mContentRatingSystems.addAll(list);
- }
+ ContentRatingsParser parser = new ContentRatingsParser(mContext);
+
+ List<TvContentRatingSystemInfo> infos = mTvInputManager.getTvContentRatingSystemList();
+ for (TvContentRatingSystemInfo info : infos) {
+ List<ContentRatingSystem> list = parser.parse(info);
+ if (list != null) {
+ mContentRatingSystems.addAll(list);
}
}
}
diff --git a/src/com/android/tv/parental/ParentalControlSettings.java b/src/com/android/tv/parental/ParentalControlSettings.java
index 9990ae35..b41b160e 100644
--- a/src/com/android/tv/parental/ParentalControlSettings.java
+++ b/src/com/android/tv/parental/ParentalControlSettings.java
@@ -19,12 +19,12 @@ package com.android.tv.parental;
import android.content.Context;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvSettings.ContentRatingLevel;
import com.google.common.collect.ImmutableList;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.HashSet;
import java.util.Set;
@@ -40,16 +40,14 @@ public class ParentalControlSettings {
private final Context mContext;
private final TvInputManager mTvInputManager;
- private final LegacyFlags mLegacyFlags;
// mRatings is expected to be synchronized with mTvInputManager.getBlockedRatings().
private Set<TvContentRating> mRatings;
private Set<TvContentRating> mCustomRatings;
- public ParentalControlSettings(Context context, LegacyFlags legacyFlags) {
+ public ParentalControlSettings(Context context) {
mContext = context;
mTvInputManager = (TvInputManager) mContext.getSystemService(Context.TV_INPUT_SERVICE);
- mLegacyFlags = legacyFlags;
}
public boolean isParentalControlsEnabled() {
@@ -132,7 +130,7 @@ public class ParentalControlSettings {
} else {
mRatings = ContentRatingLevelPolicy.getRatingsForLevel(this, manager, level);
if (level != TvSettings.CONTENT_RATING_LEVEL_NONE
- && mLegacyFlags.enableUnratedContentSettings()) {
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
// UNRATED contents should be blocked unless the rating level is none or custom
mRatings.add(TvContentRating.UNRATED);
}
diff --git a/src/com/android/tv/perf/PerformanceMonitor.java b/src/com/android/tv/perf/PerformanceMonitor.java
index 30197c74..b1ae759d 100644
--- a/src/com/android/tv/perf/PerformanceMonitor.java
+++ b/src/com/android/tv/perf/PerformanceMonitor.java
@@ -96,14 +96,4 @@ public interface PerformanceMonitor {
* @return true if the activity is available to start
*/
boolean startPerformanceMonitorEventDebugActivity(Context context);
-
- /**
- * Initialize crash monitoring for an app by wrapping the default {@link
- * Thread.UncaughtExceptionHandler} with a handler that can report crashes to the performance
- * montitor and then delegate the handling of the UncaughtException to the original default
- * {@link Thread.UncaughtExceptionHandler}.
- *
- * <p>Note: This will override the current {@link Thread.UncaughtExceptionHandler}.
- */
- void startCrashMonitor();
}
diff --git a/src/com/android/tv/perf/PerformanceMonitorManager.java b/src/com/android/tv/perf/PerformanceMonitorManager.java
new file mode 100644
index 00000000..db6667d1
--- /dev/null
+++ b/src/com/android/tv/perf/PerformanceMonitorManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.perf;
+
+import android.app.Application;
+
+/** Manages the initialization of Performance Monitoring. */
+public interface PerformanceMonitorManager {
+
+ /**
+ * Initializes the {@link com.android.tv.perf.PerformanceMonitor}.
+ *
+ * <p>This should only be called once.
+ */
+ PerformanceMonitor initialize(Application app);
+
+ /**
+ * Returns a lightweight object to help measure both cold and warm startup latency.
+ *
+ * <p>This method is idempotent and lightweight. It can be called multiple times and does not
+ * need to be cached.
+ */
+ StartupMeasure getStartupMeasure();
+}
diff --git a/common/src/com/android/tv/common/buildtype/BuildTypeFactory.java b/src/com/android/tv/perf/PerformanceMonitorManagerFactory.java
index 706a6034..fe3ea14b 100644
--- a/common/src/com/android/tv/common/buildtype/BuildTypeFactory.java
+++ b/src/com/android/tv/perf/PerformanceMonitorManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,29 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tv.common.buildtype;
-
-import com.google.common.base.Supplier;
+package com.android.tv.perf;
+import com.android.tv.perf.stub.StubPerformanceMonitorManager;
import javax.inject.Inject;
-
-/** Factory for {@link HasBuildType.BuildType}.
- *
- * <p>Hardcoded to {@link HasBuildType.BuildType#AOSP}.
- */
-public class BuildTypeFactory implements Supplier<HasBuildType> {
- private static final HasBuildType INSTANCE = new AospBuildTypeProvider();
+public final class PerformanceMonitorManagerFactory {
+ private static final PerformanceMonitorManagerFactory INSTANCE =
+ new PerformanceMonitorManagerFactory();
@Inject
- public BuildTypeFactory() {}
+ public PerformanceMonitorManagerFactory() {}
- public static HasBuildType create() {
- return INSTANCE;
+ public static PerformanceMonitorManager create() {
+ return INSTANCE.get();
}
- @Override
- public HasBuildType get() {
- return INSTANCE;
+ public PerformanceMonitorManager get() {
+ return new StubPerformanceMonitorManager();
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/perf/StartupMeasure.java b/src/com/android/tv/perf/StartupMeasure.java
index c7fa50fe..5cf183ca 100644
--- a/src/com/android/tv/perf/StartupMeasure.java
+++ b/src/com/android/tv/perf/StartupMeasure.java
@@ -19,16 +19,8 @@ import android.app.Activity;
import android.app.Application;
/**
- * Measures App startup.
- *
- * <p>This interface is lightweight to help measure both cold and warm startup latency.
- * Implementations must not throw any Exception.
- *
- * <p>Because this class needs to be used in static initialization blocks, it can not be injected
- * via dagger.
- *
- * <p>Creating implementations of this interface must be idempotent and lightweight. It does not
- * need to be cached.
+ * Measures App startup. This interface is lightweight to help measure both cold and warm startup
+ * latency. Implementations must not throw any Exception.
*/
public interface StartupMeasure {
diff --git a/src/com/android/tv/perf/StartupMeasureFactory.java b/src/com/android/tv/perf/StartupMeasureFactory.java
deleted file mode 100644
index a99c88af..00000000
--- a/src/com/android/tv/perf/StartupMeasureFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.tv.perf;
-
-
-import com.android.tv.perf.stub.StubStartupMeasure;
-
-import com.google.common.base.Supplier;
-import java.lang.Override;
-import javax.inject.Inject;
-
-/** Factory for {@link StartupMeasure}.
- *
- * <p>Hardcoded to {@link StubStartupMeasure}.
- */
-public final class StartupMeasureFactory implements Supplier<StartupMeasure> {
- private static final StartupMeasureFactory INSTANCE = new StartupMeasureFactory();
-
- @Inject
- public StartupMeasureFactory() {}
-
- public static StartupMeasure create() {
- return INSTANCE.get();
- }
-
- @Override
- public StartupMeasure get() {
- return new StubStartupMeasure();
- }
-}
diff --git a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
index ac3dc250..80c2f6c5 100644
--- a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
+++ b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
@@ -56,6 +56,7 @@ public final class StubPerformanceMonitor implements PerformanceMonitor {
return false;
}
- @Override
- public void startCrashMonitor() {}
+ public static TimerEvent startBootstrapTimer() {
+ return new TimerEvent() {};
+ }
}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultSetupFlags.java b/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
index 3abe6627..0c268155 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultSetupFlags.java
+++ b/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,26 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tv.common.flags.impl;
-import com.android.tv.common.flags.proto.TypedFeatures.StringListParam;
+package com.android.tv.perf.stub;
-import com.android.tv.common.flags.SetupFlags;
+import android.app.Application;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.PerformanceMonitorManager;
+import com.android.tv.perf.StartupMeasure;
-/** Default {@link SetupFlags} */
-public class DefaultSetupFlags implements SetupFlags {
- @Override
- public boolean compiled() {
- return true;
- }
+/** Manages a stub implementation of Performance Monitoring. */
+public class StubPerformanceMonitorManager implements PerformanceMonitorManager {
@Override
- public StringListParam setupPassThroughPackageWhitelist() {
- return StringListParam.getDefaultInstance();
+ public PerformanceMonitor initialize(Application app) {
+ return new StubPerformanceMonitor();
}
@Override
- public boolean useWhitelistForSetupPassThrough() {
- return false;
+ public StartupMeasure getStartupMeasure() {
+ return new StubStartupMeasure();
}
}
diff --git a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
index 5fa7606d..3fb66245 100644
--- a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
+++ b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
@@ -42,7 +42,7 @@ public final class AudioCapabilitiesReceiver {
// AC3 capabilities stat is sent to Google Analytics just once in order to avoid
// duplicated stat reports since it doesn't change over time in most cases.
// Increase this revision when we should force the stat to be sent again.
- // TODO: Consider using custom metrics.
+ // TODO: Consier using custom metrics.
private static final int REPORT_REVISION = 1;
private final Context mContext;
diff --git a/src/com/android/tv/receiver/PackageIntentsReceiver.java b/src/com/android/tv/receiver/PackageIntentsReceiver.java
index 7ff67b50..5bc6d724 100644
--- a/src/com/android/tv/receiver/PackageIntentsReceiver.java
+++ b/src/com/android/tv/receiver/PackageIntentsReceiver.java
@@ -23,7 +23,9 @@ import android.net.Uri;
import android.util.Log;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
+import com.android.tv.features.TvFeatures;
import com.android.tv.util.Partner;
+import com.google.android.tv.partner.support.EpgContract;
/** A class for handling the broadcast intents from PackageManager. */
public class PackageIntentsReceiver extends BroadcastReceiver {
diff --git a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
index 61ebb2d0..2590a337 100644
--- a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
+++ b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
@@ -27,18 +27,15 @@ import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
-
import androidx.tvprovider.media.tv.TvContractCompat;
-
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.PreviewProgramContent;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
diff --git a/src/com/android/tv/recommendation/ChannelRecord.java b/src/com/android/tv/recommendation/ChannelRecord.java
index f047aac6..c7a7cb37 100644
--- a/src/com/android/tv/recommendation/ChannelRecord.java
+++ b/src/com/android/tv/recommendation/ChannelRecord.java
@@ -19,12 +19,10 @@ package com.android.tv.recommendation;
import android.content.Context;
import android.support.annotation.GuardedBy;
import android.support.annotation.VisibleForTesting;
-
import com.android.tv.TvSingletons;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.util.ArrayDeque;
import java.util.Deque;
diff --git a/src/com/android/tv/recommendation/NotificationService.java b/src/com/android/tv/recommendation/NotificationService.java
index 1652bd77..f40a0862 100644
--- a/src/com/android/tv/recommendation/NotificationService.java
+++ b/src/com/android/tv/recommendation/NotificationService.java
@@ -40,21 +40,19 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseLongArray;
import android.view.View;
-
import com.android.tv.MainActivityWrapper.OnCurrentChannelChangeListener;
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.WeakHandler;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.BitmapUtils;
import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
import com.android.tv.util.images.ImageLoader;
-
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/tv/recommendation/RecommendationDataManager.java b/src/com/android/tv/recommendation/RecommendationDataManager.java
index e254ba58..fc20031c 100644
--- a/src/com/android/tv/recommendation/RecommendationDataManager.java
+++ b/src/com/android/tv/recommendation/RecommendationDataManager.java
@@ -34,17 +34,14 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvUriMatcher;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -235,9 +232,6 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
@MainThread
private void stop() {
- if (mWatchedHistoryManager != null) {
- mWatchedHistoryManager.setListener(null);
- }
for (int what = MSG_FIRST; what <= MSG_LAST; ++what) {
mHandler.removeMessages(what);
}
@@ -365,7 +359,7 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
WatchedHistoryManager.WatchedRecord watchedRecord) {
long endTime = watchedRecord.watchedStartTime + watchedRecord.duration;
Program program =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setChannelId(watchedRecord.channelId)
.setTitle("")
.setStartTimeUtcMillis(watchedRecord.watchedStartTime)
@@ -417,7 +411,7 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
}
Program program =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setChannelId(cursor.getLong(mIndexWatchChannelId))
.setTitle(cursor.getString(mIndexProgramTitle))
.setStartTimeUtcMillis(cursor.getLong(mIndexProgramStartTime))
diff --git a/src/com/android/tv/recommendation/Recommender.java b/src/com/android/tv/recommendation/Recommender.java
index a8535a49..f350799f 100644
--- a/src/com/android/tv/recommendation/Recommender.java
+++ b/src/com/android/tv/recommendation/Recommender.java
@@ -20,9 +20,7 @@ import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Pair;
-
import com.android.tv.data.api.Channel;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -129,7 +127,7 @@ public class Recommender implements RecommendationDataManager.Listener {
}
}
if (!mIncludeRecommendedOnly || maxScore != Evaluator.NOT_RECOMMENDED) {
- records.add(Pair.create(cr.getChannel(), maxScore));
+ records.add(new Pair<>(cr.getChannel(), maxScore));
}
}
if (size > records.size()) {
diff --git a/src/com/android/tv/recommendation/RoutineWatchEvaluator.java b/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
index b3952c01..9240682a 100644
--- a/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
+++ b/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
@@ -19,9 +19,7 @@ package com.android.tv.recommendation;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
-
-import com.android.tv.data.api.Program;
-
+import com.android.tv.data.Program;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Calendar;
diff --git a/src/com/android/tv/recommendation/WatchedProgram.java b/src/com/android/tv/recommendation/WatchedProgram.java
index 0da9c620..239de1f2 100644
--- a/src/com/android/tv/recommendation/WatchedProgram.java
+++ b/src/com/android/tv/recommendation/WatchedProgram.java
@@ -16,7 +16,7 @@
package com.android.tv.recommendation;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
public final class WatchedProgram {
private final Program mProgram;
diff --git a/src/com/android/tv/search/DataManagerSearch.java b/src/com/android/tv/search/DataManagerSearch.java
index 1a0ada3a..a649c0ac 100644
--- a/src/com/android/tv/search/DataManagerSearch.java
+++ b/src/com/android/tv/search/DataManagerSearch.java
@@ -26,18 +26,15 @@ import android.os.SystemClock;
import android.support.annotation.MainThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.search.LocalSearchProvider.SearchResult;
import com.android.tv.util.MainThreadExecutor;
import com.android.tv.util.Utils;
-
import com.google.common.collect.ImmutableList;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
diff --git a/src/com/android/tv/search/LocalSearchProvider.java b/src/com/android/tv/search/LocalSearchProvider.java
index 86999560..5652c986 100644
--- a/src/com/android/tv/search/LocalSearchProvider.java
+++ b/src/com/android/tv/search/LocalSearchProvider.java
@@ -17,6 +17,7 @@
package com.android.tv.search;
import android.app.SearchManager;
+import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
@@ -27,30 +28,21 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
-
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.dagger.init.SafePreDaggerInitializer;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.TvUriMatcher;
-
import com.google.auto.value.AutoValue;
-
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerContentProvider;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import javax.inject.Inject;
-
-/** Content provider for local search */
-public class LocalSearchProvider extends DaggerContentProvider {
+public class LocalSearchProvider extends ContentProvider {
private static final String TAG = "LocalSearchProvider";
private static final boolean DEBUG = false;
@@ -87,18 +79,14 @@ public class LocalSearchProvider extends DaggerContentProvider {
private static final String NO_LIVE_CONTENTS = "0";
private static final String LIVE_CONTENTS = "1";
- @Inject PerformanceMonitor mPerformanceMonitor;
+ private PerformanceMonitor mPerformanceMonitor;
/** Used only for testing */
private SearchInterface mSearchInterface;
@Override
public boolean onCreate() {
- SafePreDaggerInitializer.init(getContext());
- if (!super.onCreate()) {
- Log.e(TAG, "LocalSearchProvider.onCreate() failed.");
- return false;
- }
+ mPerformanceMonitor = TvSingletons.getSingletons(getContext()).getPerformanceMonitor();
return true;
}
@@ -233,13 +221,6 @@ public class LocalSearchProvider extends DaggerContentProvider {
throw new UnsupportedOperationException();
}
- /** Module for {@link LocalSearchProvider} */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract LocalSearchProvider contributesLocalSearchProviderInjector();
- }
-
/** A placeholder to a search result. */
@AutoValue
public abstract static class SearchResult {
@@ -254,8 +235,6 @@ public class LocalSearchProvider extends DaggerContentProvider {
.setProgressPercentage(0);
}
- public abstract Builder toBuilder();
-
@AutoValue.Builder
abstract static class Builder {
abstract Builder setChannelId(long value);
diff --git a/src/com/android/tv/search/ProgramGuideSearchFragment.java b/src/com/android/tv/search/ProgramGuideSearchFragment.java
index fa2e4516..6c94bd33 100644
--- a/src/com/android/tv/search/ProgramGuideSearchFragment.java
+++ b/src/com/android/tv/search/ProgramGuideSearchFragment.java
@@ -21,18 +21,18 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.leanback.app.SearchFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ImageCardView;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.ListRowPresenter;
-import androidx.leanback.widget.ObjectAdapter;
-import androidx.leanback.widget.OnItemViewClickedListener;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.Row;
-import androidx.leanback.widget.RowPresenter;
-import androidx.leanback.widget.SearchBar;
+import android.support.v17.leanback.app.SearchFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ObjectAdapter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SearchBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/search/TvProviderSearch.java b/src/com/android/tv/search/TvProviderSearch.java
index c46938a9..8a1f51f9 100644
--- a/src/com/android/tv/search/TvProviderSearch.java
+++ b/src/com/android/tv/search/TvProviderSearch.java
@@ -308,7 +308,7 @@ public class TvProviderSearch implements SearchInterface {
if (c != null && c.moveToNext() && !isRatingBlocked(c.getString(2))) {
String channelName = result.getTitle();
String channelNumber = result.getChannelNumber();
- SearchResult.Builder builder = result.toBuilder();
+ SearchResult.Builder builder = SearchResult.builder();
long startUtcMillis = c.getLong(5);
long endUtcMillis = c.getLong(6);
builder.setTitle(c.getString(0));
diff --git a/src/com/android/tv/setup/SystemSetupActivity.java b/src/com/android/tv/setup/SystemSetupActivity.java
index 999b157a..b2160b3a 100644
--- a/src/com/android/tv/setup/SystemSetupActivity.java
+++ b/src/com/android/tv/setup/SystemSetupActivity.java
@@ -24,9 +24,9 @@ import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.widget.Toast;
-
import com.android.tv.R;
import com.android.tv.SetupPassthroughActivity;
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.ui.setup.SetupActivity;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
@@ -36,11 +36,6 @@ import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
-import javax.inject.Inject;
-
/** A activity to start input sources setup fragment for initial setup flow. */
public class SystemSetupActivity extends SetupActivity {
private static final String SYSTEM_SETUP =
@@ -48,17 +43,18 @@ public class SystemSetupActivity extends SetupActivity {
private static final int SHOW_RIPPLE_DURATION_MS = 266;
private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
- @Inject TvInputManagerHelper mInputManager;
+ private TvInputManagerHelper mInputManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
- AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (!SYSTEM_SETUP.equals(intent.getAction())) {
finish();
return;
}
+ TvSingletons singletons = TvSingletons.getSingletons(this);
+ mInputManager = singletons.getTvInputManagerHelper();
}
@Override
@@ -96,7 +92,7 @@ public class SystemSetupActivity extends SetupActivity {
}
// Even though other app can handle the intent, the setup launched by
// Live
- // channels should go through TV app SetupPassthroughActivity.
+ // channels should go through Live channels SetupPassthroughActivity.
intent.setComponent(
new ComponentName(this, SetupPassthroughActivity.class));
try {
@@ -128,13 +124,4 @@ public class SystemSetupActivity extends SetupActivity {
}
return false;
}
-
- /**
- * Exports {@link SystemSetupActivity} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract SystemSetupActivity contributeSystemSetupActivity();
- }
}
diff --git a/src/com/android/tv/ui/AppLayerTvView.java b/src/com/android/tv/ui/AppLayerTvView.java
index 4c54fb3c..e2b64a1e 100644
--- a/src/com/android/tv/ui/AppLayerTvView.java
+++ b/src/com/android/tv/ui/AppLayerTvView.java
@@ -21,6 +21,7 @@ import android.util.AttributeSet;
import android.view.SurfaceView;
import android.view.View;
import com.android.tv.common.compat.TvViewCompat;
+import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
/**
@@ -28,14 +29,9 @@ import com.android.tv.common.util.Debug;
*
* <p>Once an app starts using additional window like SubPanel and it gets window focus, the {@link
* android.media.tv.TvView#setMain()} does not work because its implementation assumes that the app
- * uses only application layer.
- *
- * <p>TODO: remove this class once the TvView.setMain() is revisited.
+ * uses only application layer. TODO: remove this class once the TvView.setMain() is revisited.
*/
public class AppLayerTvView extends TvViewCompat {
-
- boolean mUseSecureSurface = true;
-
public AppLayerTvView(Context context) {
super(context);
}
@@ -48,11 +44,6 @@ public class AppLayerTvView extends TvViewCompat {
super(context, attrs, defStyleAttr);
}
- /** Set the security of children {@link SurfaceView}s to {@code secure} */
- public void setUseSecureSurface(boolean secure) {
- mUseSecureSurface = secure;
- }
-
@Override
public boolean hasWindowFocus() {
return true;
@@ -62,7 +53,7 @@ public class AppLayerTvView extends TvViewCompat {
public void onViewAdded(View child) {
if (child instanceof SurfaceView) {
// Note: See b/29118070 for detail.
- ((SurfaceView) child).setSecure(mUseSecureSurface);
+ ((SurfaceView) child).setSecure(!CommonUtils.isDeveloper());
}
super.onViewAdded(child);
}
diff --git a/src/com/android/tv/ui/ChannelBannerView.java b/src/com/android/tv/ui/ChannelBannerView.java
index f0781214..00ac7e32 100644
--- a/src/com/android/tv/ui/ChannelBannerView.java
+++ b/src/com/android/tv/ui/ChannelBannerView.java
@@ -46,15 +46,13 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.singletons.HasSingletons;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.parental.ContentRatingsManager;
@@ -66,9 +64,7 @@ import com.android.tv.util.images.ImageCache;
import com.android.tv.util.images.ImageLoader;
import com.android.tv.util.images.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.images.ImageLoader.LoadTvInputLogoTask;
-
import com.google.common.collect.ImmutableList;
-
import javax.inject.Provider;
/** A view to render channel banner. */
@@ -122,7 +118,6 @@ public class ChannelBannerView extends FrameLayout
private final TvInputManagerHelper mTvInputManagerHelper;
// TvOverlayManager is always created after ChannelBannerView
private final Provider<TvOverlayManager> mTvOverlayManager;
- private final AccessibilityManager mAccessibilityManager;
private View mChannelView;
@@ -270,12 +265,12 @@ public class ChannelBannerView extends FrameLayout
mContentRatingsManager = mTvInputManagerHelper.getContentRatingsManager();
mNoProgram =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle(context.getString(R.string.channel_banner_no_title))
.setDescription(EMPTY_STRING)
.build();
mLockedChannelProgram =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle(context.getString(R.string.channel_banner_locked_channel_title))
.setDescription(EMPTY_STRING)
.build();
@@ -283,7 +278,8 @@ public class ChannelBannerView extends FrameLayout
sClosedCaptionMark = context.getString(R.string.closed_caption);
}
mAutoHideScheduler = new AutoHideScheduler(context, this::hide);
- mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ context.getSystemService(AccessibilityManager.class)
+ .addAccessibilityStateChangeListener(mAutoHideScheduler);
}
@Override
@@ -323,18 +319,6 @@ public class ChannelBannerView extends FrameLayout
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mAccessibilityManager.addAccessibilityStateChangeListener(mAutoHideScheduler);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- mAccessibilityManager.removeAccessibilityStateChangeListener(mAutoHideScheduler);
- super.onDetachedFromWindow();
- }
-
- @Override
public void onEnterAction(boolean fromEmptyScene) {
resetAnimationEffects();
if (fromEmptyScene) {
@@ -564,7 +548,7 @@ public class ChannelBannerView extends FrameLayout
return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
@Override
public void onBitmapLoaded(ChannelBannerView view, @Nullable Bitmap logo) {
- if (!channel.equals(view.mCurrentChannel)) {
+ if (channel.equals(view.mCurrentChannel)) {
// The logo is obsolete.
return;
}
@@ -751,23 +735,15 @@ public class ChannelBannerView extends FrameLayout
} else {
ImmutableList<TvContentRating> ratings =
(program == null) ? null : program.getContentRatings();
- int ratingsViewIndex = 0;
- if (ratings != null) {
- for (int i = 0; i < ratings.size(); i++) {
- if (ratingsViewIndex < DISPLAYED_CONTENT_RATINGS_COUNT
- && !TextUtils.isEmpty(
- mContentRatingsManager.getDisplayNameForRating(
- ratings.get(i)))) {
- mContentRatingsTextViews[ratingsViewIndex].setText(
- mContentRatingsManager.getDisplayNameForRating(ratings.get(i)));
- mContentRatingsTextViews[ratingsViewIndex].setVisibility(View.VISIBLE);
- ratingsViewIndex++;
- }
+ for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
+ if (ratings == null || ratings.size() <= i) {
+ mContentRatingsTextViews[i].setVisibility(View.GONE);
+ } else {
+ mContentRatingsTextViews[i].setText(
+ mContentRatingsManager.getDisplayNameForRating(ratings.get(i)));
+ mContentRatingsTextViews[i].setVisibility(View.VISIBLE);
}
}
- while (ratingsViewIndex < DISPLAYED_CONTENT_RATINGS_COUNT) {
- mContentRatingsTextViews[ratingsViewIndex++].setVisibility(View.GONE);
- }
}
}
diff --git a/src/com/android/tv/ui/DetailsActivity.java b/src/com/android/tv/ui/DetailsActivity.java
index 92c13f57..80c0f64b 100644
--- a/src/com/android/tv/ui/DetailsActivity.java
+++ b/src/com/android/tv/ui/DetailsActivity.java
@@ -16,11 +16,12 @@
package com.android.tv.ui;
+import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
-import androidx.leanback.app.DetailsFragment;
+import android.support.v17.leanback.app.DetailsFragment;
import android.transition.Transition;
import android.transition.Transition.TransitionListener;
import android.util.Log;
@@ -34,12 +35,9 @@ import com.android.tv.dvr.ui.browse.CurrentRecordingDetailsFragment;
import com.android.tv.dvr.ui.browse.RecordedProgramDetailsFragment;
import com.android.tv.dvr.ui.browse.ScheduledRecordingDetailsFragment;
import com.android.tv.dvr.ui.browse.SeriesRecordingDetailsFragment;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerActivity;
/** Activity to show details view. */
-public class DetailsActivity extends DaggerActivity
- implements PinDialogFragment.OnPinCheckedListener {
+public class DetailsActivity extends Activity implements PinDialogFragment.OnPinCheckedListener {
private static final String TAG = "DetailsActivity";
private static final long INVALID_RECORD_ID = -1;
@@ -208,15 +206,4 @@ public class DetailsActivity extends DaggerActivity
}
finish();
}
-
- /** Exports {@link DaggerActivity} for Dagger codegen to create the appropriate injector. */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract DetailsActivity contributesDetailsActivityInjector();
-
- @ContributesAndroidInjector
- abstract CurrentRecordingDetailsFragment
- contributesCurrentRecordingDetailsFragmentInjector();
- }
}
diff --git a/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java b/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
index 3aba5d1d..9685b04b 100644
--- a/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
+++ b/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
@@ -17,9 +17,9 @@
package com.android.tv.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import com.android.tv.R;
/** Extended stylist class used for {@link GuidedStepFragment} with divider support. */
diff --git a/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java b/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
index 703dc242..9b916afe 100644
--- a/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
+++ b/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
@@ -17,7 +17,7 @@ package com.android.tv.ui;
import android.os.Message;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
diff --git a/src/com/android/tv/ui/ProgramDetailsFragment.java b/src/com/android/tv/ui/ProgramDetailsFragment.java
index bfcebd7d..88a7b2ca 100644
--- a/src/com/android/tv/ui/ProgramDetailsFragment.java
+++ b/src/com/android/tv/ui/ProgramDetailsFragment.java
@@ -23,23 +23,21 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.text.TextUtils;
-
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -66,7 +64,7 @@ public class ProgramDetailsFragment extends DetailsFragment
protected DetailsViewBackgroundHelper mBackgroundHelper;
private ArrayObjectAdapter mRowsAdapter;
private DetailsOverviewRow mDetailsOverview;
- private ProgramImpl mProgram;
+ private Program mProgram;
private String mInputId;
private ScheduledRecording mScheduledRecording;
private DvrManager mDvrManager;
@@ -139,7 +137,7 @@ public class ProgramDetailsFragment extends DetailsFragment
* the detail activity and fragment will be ended.
*/
private boolean onLoadDetails(Bundle args) {
- ProgramImpl program = args.getParcelable(DetailsActivity.PROGRAM);
+ Program program = args.getParcelable(DetailsActivity.PROGRAM);
long channelId = args.getLong(DetailsActivity.CHANNEL_ID);
String inputId = args.getString(DetailsActivity.INPUT_ID);
if (program != null && channelId != Channel.INVALID_ID && !TextUtils.isEmpty(inputId)) {
diff --git a/src/com/android/tv/ui/SelectInputView.java b/src/com/android/tv/ui/SelectInputView.java
index a0cfad32..f4949f08 100644
--- a/src/com/android/tv/ui/SelectInputView.java
+++ b/src/com/android/tv/ui/SelectInputView.java
@@ -22,8 +22,8 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.VerticalGridView;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index a736e79d..5ac6bd83 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -54,13 +54,11 @@ import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
-import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.compat.TvInputConstantCompat;
import com.android.tv.common.compat.TvViewCompat.TvInputCallbackCompat;
@@ -69,11 +67,11 @@ import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
import com.android.tv.common.util.DurationTimer;
import com.android.tv.common.util.PermissionUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.features.TvFeatures;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
@@ -83,9 +81,6 @@ import com.android.tv.util.NetworkUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -290,12 +285,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
if (mVideoWidth <= 0 || mVideoHeight <= 0) {
mVideoDisplayAspectRatio = 0.0f;
} else {
- float videoPixelAspectRatio =
+ float VideoPixelAspectRatio =
track.getVideoPixelAspectRatio();
- mVideoDisplayAspectRatio = (float) mVideoWidth
- / mVideoHeight;
- mVideoDisplayAspectRatio *= videoPixelAspectRatio > 0 ?
- videoPixelAspectRatio : 1;
+ mVideoDisplayAspectRatio =
+ VideoPixelAspectRatio
+ * mVideoWidth
+ / mVideoHeight;
}
} else if (type == TvTrackInfo.TYPE_AUDIO) {
mAudioChannelCount = track.getAudioChannelCount();
@@ -322,7 +317,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
Debug.getTimer(Debug.TAG_START_UP_TIMER)
.log(
- "Start up of TV app ends,"
+ "Start up of Live TV ends,"
+ " TunableTvView.onVideoAvailable resets timer");
Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
Debug.removeTimer(Debug.TAG_START_UP_TIMER);
@@ -478,12 +473,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void initialize(
- ProgramDataManager programDataManager,
- TvInputManagerHelper tvInputManagerHelper,
- LegacyFlags mLegacyFlags) {
+ ProgramDataManager programDataManager, TvInputManagerHelper tvInputManagerHelper) {
mTvView = findViewById(R.id.tv_view);
- mTvView.setUseSecureSurface(!BuildConfig.ENG && !mLegacyFlags.enableDeveloperFeatures());
-
mProgramDataManager = programDataManager;
mInputManagerHelper = tvInputManagerHelper;
mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
@@ -562,9 +553,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void setMain() {
- if (PermissionUtils.hasChangeHdmiCecActiveSource(getContext())) {
- mTvView.setMain();
- }
+ mTvView.setMain();
}
public void setWatchedHistoryManager(WatchedHistoryManager watchedHistoryManager) {
@@ -664,22 +653,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
// To reduce the IPCs, unregister the callback here and register it when necessary.
mTvView.setTimeShiftPositionCallback(null);
setTimeShiftAvailable(false);
+ if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
+ // When the input is changed, TvView recreates its SurfaceView internally.
+ // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
+ getSurfaceView().getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
+ }
mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
if (mTvViewSession != null) {
mTvViewSession.tune(channel, params, listener);
} else {
mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params);
}
- if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
- // When the input is changed, TvView recreates its SurfaceView internally.
- // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
- SurfaceView surfaceView = getSurfaceView();
- if (surfaceView != null) {
- surfaceView.getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
- } else {
- Log.w(TAG, "Failed to set fixed size for surface view: Null surface view");
- }
- }
updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(this, true);
diff --git a/src/com/android/tv/ui/TvOverlayManager.java b/src/com/android/tv/ui/TvOverlayManager.java
index 0ab7c685..b2854a1f 100644
--- a/src/com/android/tv/ui/TvOverlayManager.java
+++ b/src/com/android/tv/ui/TvOverlayManager.java
@@ -33,7 +33,6 @@ import android.view.Gravity;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-
import com.android.tv.ChannelTuner;
import com.android.tv.MainActivity;
import com.android.tv.MainActivity.KeyHandlerResultType;
@@ -48,7 +47,6 @@ 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.data.ProgramDataManager;
import com.android.tv.dialog.DvrHistoryDialogFragment;
import com.android.tv.dialog.FullscreenDialogFragment;
import com.android.tv.dialog.HalfSizedDialogFragment;
@@ -70,12 +68,6 @@ import com.android.tv.ui.TvTransitionManager.SceneType;
import com.android.tv.ui.sidepanel.SideFragmentManager;
import com.android.tv.ui.sidepanel.parentalcontrols.RatingsFragment;
import com.android.tv.util.TvInputManagerHelper;
-
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -87,7 +79,6 @@ import java.util.Set;
/** A class responsible for the life cycle and event handling of the pop-ups over TV view. */
@UiThread
-@AutoFactory
public class TvOverlayManager implements AccessibilityStateChangeListener {
private static final String TAG = "TvOverlayManager";
private static final boolean DEBUG = false;
@@ -225,7 +216,6 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
private final List<Runnable> mPendingActions = new ArrayList<>();
private final Queue<PendingDialogAction> mPendingDialogActionQueue = new LinkedList<>();
- private final LegacyFlags mLegacyFlags;
private OnBackStackChangedListener mOnBackStackChangedListener;
@@ -239,17 +229,12 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
InputBannerView inputBannerView,
SelectInputView selectInputView,
ViewGroup sceneContainer,
- ProgramGuideSearchFragment searchFragment,
- @Provided LegacyFlags legacyFlags,
- @Provided ChannelDataManager channelDataManager,
- @Provided TvInputManagerHelper tvInputManager,
- @Provided ProgramDataManager programDataManager) {
+ ProgramGuideSearchFragment searchFragment) {
mMainActivity = mainActivity;
mChannelTuner = channelTuner;
TvSingletons singletons = TvSingletons.getSingletons(mainActivity);
- mLegacyFlags = legacyFlags;
- mChannelDataManager = channelDataManager;
- mInputManager = tvInputManager;
+ mChannelDataManager = singletons.getChannelDataManager();
+ mInputManager = singletons.getTvInputManagerHelper();
mTvView = tvView;
mChannelBannerView = channelBannerView;
mKeypadChannelSwitchView = keypadChannelSwitchView;
@@ -286,7 +271,7 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
tvView,
optionsManager,
menuView,
- new MenuRowFactory(mainActivity, tvView, this.mLegacyFlags),
+ new MenuRowFactory(mainActivity, tvView),
new Menu.OnMenuVisibilityChangeListener() {
@Override
public void onMenuVisibilityChange(boolean visible) {
@@ -319,9 +304,9 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
new ProgramGuide(
mainActivity,
channelTuner,
- mInputManager,
+ singletons.getTvInputManagerHelper(),
mChannelDataManager,
- programDataManager,
+ singletons.getProgramDataManager(),
dvrDataManager,
singletons.getDvrScheduleManager(),
singletons.getTracker(),
diff --git a/src/com/android/tv/ui/ViewUtils.java b/src/com/android/tv/ui/ViewUtils.java
index 431b3113..f64a70b2 100644
--- a/src/com/android/tv/ui/ViewUtils.java
+++ b/src/com/android/tv/ui/ViewUtils.java
@@ -18,11 +18,9 @@ package com.android.tv.ui;
import android.animation.Animator;
import android.animation.ValueAnimator;
-import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -35,9 +33,6 @@ public class ViewUtils {
}
public static void setTransitionAlpha(View v, float alpha) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- v.setTransitionAlpha(alpha);
- }
Method method;
try {
method = View.class.getDeclaredMethod("setTransitionAlpha", Float.TYPE);
diff --git a/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java b/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
index de3ae751..2726839c 100644
--- a/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
+++ b/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
@@ -19,14 +19,13 @@ package com.android.tv.ui.sidepanel;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelDataManager.ChannelListener;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
public abstract class ChannelCheckItem extends CompoundButtonItem {
private final ChannelDataManager mChannelDataManager;
diff --git a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
index b62a57ee..62130b64 100644
--- a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
+++ b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.media.tv.TvContract.Channels;
import android.os.Bundle;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
index e43568c9..36ee5a2d 100644
--- a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
+++ b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
@@ -16,38 +16,29 @@
package com.android.tv.ui.sidepanel;
+import android.accounts.Account;
import android.app.Activity;
-
-import com.android.tv.MainActivity;
+import android.support.annotation.NonNull;
+import android.util.Log;
+import android.widget.Toast;
import com.android.tv.R;
-import com.android.tv.common.BuildConfig;
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonPreferences;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.common.util.CommonUtils;
+
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.LegacyFlags;
-import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
/** Options for developers only */
public class DeveloperOptionFragment extends SideFragment {
+ private static final String TAG = "DeveloperOptionFragment";
private static final String TRACKER_LABEL = "debug options";
- @Inject Optional<AdditionalDeveloperItemsFactory> mAdditionalDeveloperItemsFactory;
- @Inject PerformanceMonitor mPerformanceMonitor;
- @Inject LegacyFlags mLegacyFlags;
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
- }
-
@Override
protected String getTitle() {
return getString(R.string.menu_developer_options);
@@ -59,15 +50,8 @@ public class DeveloperOptionFragment extends SideFragment {
}
@Override
- protected ImmutableList<Item> getItemList() {
- ImmutableList.Builder<Item> items = ImmutableList.builder();
- if (mAdditionalDeveloperItemsFactory.isPresent()) {
- items.addAll(
- mAdditionalDeveloperItemsFactory
- .get()
- .getAdditionalDevItems(getMainActivity()));
- items.add(new DividerItem());
- }
+ protected List<Item> getItemList() {
+ List<Item> items = new ArrayList<>();
if (CommonFeatures.DVR.isEnabled(getContext())) {
items.add(
new ActionItem(getString(R.string.dev_item_dvr_history)) {
@@ -77,7 +61,7 @@ public class DeveloperOptionFragment extends SideFragment {
}
});
}
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
items.add(
new ActionItem(getString(R.string.dev_item_watch_history)) {
@Override
@@ -103,21 +87,17 @@ public class DeveloperOptionFragment extends SideFragment {
CommonPreferences.setStoreTsStream(getContext(), isChecked());
}
});
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
items.add(
new ActionItem(getString(R.string.dev_item_show_performance_monitor_log)) {
@Override
protected void onSelected() {
- mPerformanceMonitor.startPerformanceMonitorEventDebugActivity(
- getContext());
+ TvSingletons.getSingletons(getContext())
+ .getPerformanceMonitor()
+ .startPerformanceMonitorEventDebugActivity(getContext());
}
});
}
- return items.build();
- }
-
- /** Factory to create additional items. */
- public interface AdditionalDeveloperItemsFactory {
- ImmutableList<Item> getAdditionalDevItems(MainActivity mainActivity);
+ return items;
}
}
diff --git a/src/com/android/tv/ui/sidepanel/SettingsFragment.java b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
index 1c03b6a9..aa71fb75 100644
--- a/src/com/android/tv/ui/sidepanel/SettingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
@@ -35,7 +35,7 @@ import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
-/** Shows TV app settings. */
+/** Shows Live TV settings. */
public class SettingsFragment extends SideFragment {
private static final String TRACKER_LABEL = "settings";
diff --git a/src/com/android/tv/ui/sidepanel/SideFragment.java b/src/com/android/tv/ui/sidepanel/SideFragment.java
index 703b1e43..590f1300 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragment.java
@@ -20,27 +20,24 @@ import android.app.Fragment;
import android.content.Context;
import android.graphics.drawable.RippleDrawable;
import android.os.Bundle;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
-
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.HasTrackerLabel;
import com.android.tv.analytics.Tracker;
-import com.android.tv.common.dev.DeveloperPreferences;
import com.android.tv.common.util.DurationTimer;
+import com.android.tv.common.util.SystemProperties;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.util.ViewCache;
-
import java.util.List;
public abstract class SideFragment<T extends Item> extends Fragment implements HasTrackerLabel {
@@ -59,7 +56,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
new RecyclerView.RecycledViewPool();
private VerticalGridView mListView;
- private ItemAdapter<T> mAdapter;
+ private ItemAdapter mAdapter;
private SideFragmentListener mListener;
private ChannelDataManager mChannelDataManager;
private ProgramDataManager mProgramDataManager;
@@ -68,7 +65,6 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
private final int mHideKey;
private final int mDebugHideKey;
- private Context mContext;
public SideFragment() {
this(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.KEYCODE_UNKNOWN);
@@ -77,7 +73,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
/**
* @param hideKey the KeyCode used to hide the fragment
* @param debugHideKey the KeyCode used to hide the fragment if {@link
- * DeveloperPreferences#USE_DEBUG_KEYS}.
+ * SystemProperties#USE_DEBUG_KEYS}.
*/
public SideFragment(int hideKey, int debugHideKey) {
mHideKey = hideKey;
@@ -87,7 +83,6 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
@Override
public void onAttach(Context context) {
super.onAttach(context);
- mContext = context;
mChannelDataManager = getMainActivity().getChannelDataManager();
mProgramDataManager = getMainActivity().getProgramDataManager();
mTracker = TvSingletons.getSingletons(context).getTracker();
@@ -134,8 +129,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
}
public final boolean isHideKeyForThisPanel(int keyCode) {
- boolean debugKeysEnabled =
- DeveloperPreferences.USE_DEBUG_KEYS.getDefaultIfContextNull(mContext);
+ boolean debugKeysEnabled = SystemProperties.USE_DEBUG_KEYS.getValue();
return mHideKey != KeyEvent.KEYCODE_UNKNOWN
&& (mHideKey == keyCode || (debugKeysEnabled && mDebugHideKey == keyCode));
}
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
index 620b7017..b14bf78d 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
@@ -23,7 +23,7 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
index 60f8425f..d1ae4423 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
@@ -16,7 +16,6 @@
package com.android.tv.ui.sidepanel.parentalcontrols;
-import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.tv.TvContentRating;
import android.os.Bundle;
@@ -25,9 +24,9 @@ import android.util.SparseIntArray;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.dialog.WebDialogFragment;
import com.android.tv.license.LicenseUtils;
import com.android.tv.parental.ContentRatingSystem;
@@ -40,28 +39,18 @@ import com.android.tv.ui.sidepanel.RadioButtonItem;
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvSettings.ContentRatingLevel;
-
import com.google.common.collect.ImmutableList;
-
-import dagger.android.AndroidInjection;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import javax.inject.Inject;
-
public class RatingsFragment extends SideFragment {
private static final SparseIntArray sLevelResourceIdMap;
private static final SparseIntArray sDescriptionResourceIdMap;
private static final String TRACKER_LABEL = "Ratings";
private int mItemsSize;
- @Inject LegacyFlags mLegacyFlags;
-
static {
sLevelResourceIdMap = new SparseIntArray(5);
sLevelResourceIdMap.put(TvSettings.CONTENT_RATING_LEVEL_NONE, R.string.option_rating_none);
@@ -112,7 +101,8 @@ public class RatingsFragment extends SideFragment {
protected List<Item> getItemList() {
List<Item> items = new ArrayList<>();
- if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
items.add(mBlockUnratedItem);
items.add(new DividerItem());
}
@@ -168,13 +158,7 @@ public class RatingsFragment extends SideFragment {
super.onCreate(savedInstanceState);
mParentalControlSettings = getMainActivity().getParentalControlSettings();
mParentalControlSettings.loadRatings();
- }
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
- if (mLegacyFlags.enableUnratedContentSettings()) {
+ if (Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
mBlockUnratedItem =
new CheckBoxItem(
getResources().getString(R.string.option_block_unrated_programs)) {
@@ -195,8 +179,6 @@ public class RatingsFragment extends SideFragment {
}
}
};
- } else {
- mBlockUnratedItem = null;
}
}
@@ -253,7 +235,8 @@ public class RatingsFragment extends SideFragment {
super.onSelected();
mParentalControlSettings.setContentRatingLevel(
getMainActivity().getContentRatingsManager(), mRatingLevel);
- if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
// set checked if UNRATED is blocked, and set unchecked otherwise.
mBlockUnratedItem.setChecked(
mParentalControlSettings.isRatingBlocked(
diff --git a/src/com/android/tv/util/AsyncDbTask.java b/src/com/android/tv/util/AsyncDbTask.java
index 2e9a1ea8..b3523952 100644
--- a/src/com/android/tv/util/AsyncDbTask.java
+++ b/src/com/android/tv/util/AsyncDbTask.java
@@ -28,23 +28,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.ChannelImpl;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
-
import com.google.common.base.Predicate;
-
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
-
import javax.inject.Qualifier;
/**
@@ -128,7 +123,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
return null;
}
if (Utils.isProgramsUri(mUri)
- && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
+ && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
mProjection =
TvProviderUtils.addExtraColumnsToProjection(
mProjection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
@@ -328,19 +323,10 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
}
- /**
- * Gets an {@link List} of {@link ProgramImpl}s from {@link TvContract.Programs#CONTENT_URI}.
- */
+ /** Gets an {@link List} of {@link Program}s from {@link TvContract.Programs#CONTENT_URI}. */
public abstract static class AsyncProgramQueryTask extends AsyncQueryListTask<Program> {
public AsyncProgramQueryTask(Executor executor, Context context) {
- super(
- executor,
- context,
- Programs.CONTENT_URI,
- ProgramImpl.PROJECTION,
- null,
- null,
- null);
+ super(executor, context, Programs.CONTENT_URI, Program.PROJECTION, null, null, null);
}
public AsyncProgramQueryTask(
@@ -355,7 +341,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
executor,
context,
uri,
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
selection,
selectionArgs,
sortOrder,
@@ -364,7 +350,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
@Override
protected final Program fromCursor(Cursor c) {
- return ProgramImpl.fromCursor(c);
+ return Program.fromCursor(c);
}
}
@@ -390,7 +376,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
/**
- * Gets an {@link List} of {@link ProgramImpl}s for a given channel and period {@link
+ * Gets an {@link List} of {@link Program}s for a given channel and period {@link
* TvContract#buildProgramsUriForChannel(long, long, long)}. If the {@code period} is {@code
* null}, then all the programs is queried.
*/
@@ -424,7 +410,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
}
- /** Gets a single {@link ProgramImpl} from {@link TvContract.Programs#CONTENT_URI}. */
+ /** Gets a single {@link Program} from {@link TvContract.Programs#CONTENT_URI}. */
public static class AsyncQueryProgramTask extends AsyncQueryItemTask<Program> {
public AsyncQueryProgramTask(Executor executor, Context context, long programId) {
@@ -432,7 +418,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
executor,
context,
TvContract.buildProgramUri(programId),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
null);
@@ -440,7 +426,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
@Override
protected Program fromCursor(Cursor c) {
- return ProgramImpl.fromCursor(c);
+ return Program.fromCursor(c);
}
}
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 4fae2f00..3b72e091 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -27,9 +27,7 @@ public final class OnboardingUtils {
private static final String PREF_KEY_ONBOARDING_VERSION_CODE = "pref_onbaording_versionCode";
private static final int ONBOARDING_VERSION = 1;
- // Replace as needed
- private static final String MERCHANT_COLLECTION_URL_STRING =
- "https://play.google.com/store/apps/collection/promotion_3001bf9_ATV_livechannels";
+ private static final String MERCHANT_COLLECTION_URL_STRING = getMerchantCollectionUrl();
/** Intent to show merchant collection in online store. */
public static final Intent ONLINE_STORE_INTENT =
@@ -71,5 +69,10 @@ public final class OnboardingUtils {
.apply();
}
+ /** Returns merchant collection URL. */
+ private static String getMerchantCollectionUrl() {
+ return "TODO: add a merchant collection url";
+ }
+
private OnboardingUtils() {}
}
diff --git a/src/com/android/tv/util/SetupUtils.java b/src/com/android/tv/util/SetupUtils.java
index 52b3e3e8..a9b67fa8 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -307,7 +307,8 @@ public class SetupUtils {
}
/**
- * Called when TV app is launched. Once it is called, {@link #isFirstTune} will return false.
+ * Called when Live channels app is launched. Once it is called, {@link #isFirstTune} will
+ * return false.
*/
public void onTuned() {
if (!mIsFirstTune) {
diff --git a/common/src/com/android/tv/common/util/sql/SqlParams.java b/src/com/android/tv/util/SqlParams.java
index 87fcabdb..fa557ba2 100644
--- a/common/src/com/android/tv/common/util/sql/SqlParams.java
+++ b/src/com/android/tv/util/SqlParams.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.common.util.sql;
+package com.android.tv.util;
import android.database.DatabaseUtils;
import android.support.annotation.Nullable;
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index 23c9b494..cb7d9854 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -46,8 +46,6 @@ import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.images.ImageCache;
import com.android.tv.util.images.ImageLoader;
-import com.google.common.collect.Ordering;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -129,7 +127,6 @@ public class TvInputManagerHelper {
private static final String PERMISSION_ACCESS_ALL_EPG_DATA =
"com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA";
private static final String[] mPhysicalTunerBlackList = {
- "com.google.android.videos", // Play Movies
};
private static final String META_LABEL_SORT_KEY = "input_sort_key";
@@ -161,10 +158,6 @@ public class TvInputManagerHelper {
}
private static final String[] PARTNER_TUNER_INPUT_PREFIX_BLACKLIST = {
- /* Begin_AOSP_Comment_Out
- // Disabled partner's tuner input prefix list.
- "com.mediatek.tvinput/.dtv"
- End_AOSP_Comment_Out */
};
private static final String[] TESTABLE_INPUTS = {
@@ -299,8 +292,8 @@ public class TvInputManagerHelper {
private boolean mAllow3rdPartyInputs;
@Inject
- public TvInputManagerHelper(@ApplicationContext Context context, LegacyFlags legacyFlags) {
- this(context, createTvInputManagerWrapper(context), legacyFlags);
+ public TvInputManagerHelper(@ApplicationContext Context context) {
+ this(context, createTvInputManagerWrapper(context));
}
@Nullable
@@ -312,14 +305,12 @@ public class TvInputManagerHelper {
@VisibleForTesting
protected TvInputManagerHelper(
- Context context,
- @Nullable TvInputManagerInterface tvInputManager,
- LegacyFlags legacyFlags) {
+ Context context, @Nullable TvInputManagerInterface tvInputManager) {
mContext = context.getApplicationContext();
mPackageManager = context.getPackageManager();
mTvInputManager = tvInputManager;
mContentRatingsManager = new ContentRatingsManager(context, tvInputManager);
- mParentalControlSettings = new ParentalControlSettings(context, legacyFlags);
+ mParentalControlSettings = new ParentalControlSettings(context);
mTvInputInfoComparator = new InputComparatorInternal(this);
mContentObserver =
new ContentObserver(mHandler) {
@@ -357,6 +348,7 @@ public class TvInputManagerHelper {
updateAllow3rdPartyInputs();
mTvInputManager.registerCallback(mInternalCallback, mHandler);
initInputMaps();
+ mContentRatingsManager.update();
}
public void stop() {
@@ -454,12 +446,10 @@ public class TvInputManagerHelper {
}
/** Loads label of {@code info}. */
- @Nullable
public String loadLabel(TvInputInfo info) {
String label = mTvInputLabels.get(info.getId());
if (label == null) {
- CharSequence labelSequence = info.loadLabel(mContext);
- label = labelSequence == null ? null : labelSequence.toString();
+ label = info.loadLabel(mContext).toString();
mTvInputLabels.put(info.getId(), label);
}
return label;
@@ -713,8 +703,6 @@ public class TvInputManagerHelper {
@VisibleForTesting
static class InputComparatorInternal implements Comparator<TvInputInfo> {
private final TvInputManagerHelper mInputManager;
- private static final Ordering<Comparable> NULL_FIRST_STRING_ORDERING =
- Ordering.natural().nullsFirst();
public InputComparatorInternal(TvInputManagerHelper inputManager) {
mInputManager = inputManager;
@@ -725,8 +713,7 @@ public class TvInputManagerHelper {
if (mInputManager.isPartnerInput(lhs) != mInputManager.isPartnerInput(rhs)) {
return mInputManager.isPartnerInput(lhs) ? -1 : 1;
}
- return NULL_FIRST_STRING_ORDERING.compare(
- mInputManager.loadLabel(lhs), mInputManager.loadLabel(rhs));
+ return mInputManager.loadLabel(lhs).compareTo(mInputManager.loadLabel(rhs));
}
}
@@ -808,7 +795,7 @@ public class TvInputManagerHelper {
if (TextUtils.isEmpty(label)) {
label = mTvInputManagerHelper.loadLabel(input);
}
- return label == null ? "" : label;
+ return label;
}
private int getPriority(TvInputInfo info) {
diff --git a/src/com/android/tv/util/TvProviderUtils.java b/src/com/android/tv/util/TvProviderUtils.java
index d931dcd5..6b5aaecc 100644
--- a/src/com/android/tv/util/TvProviderUtils.java
+++ b/src/com/android/tv/util/TvProviderUtils.java
@@ -27,7 +27,7 @@ import android.support.annotation.StringDef;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.util.Log;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
import com.android.tv.features.PartnerFeatures;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -67,9 +67,6 @@ public final class TvProviderUtils {
@WorkerThread
public static synchronized boolean checkSeriesIdColumn(Context context, Uri uri) {
boolean canCreateColumn = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O);
- canCreateColumn =
- (canCreateColumn
- || PartnerFeatures.TVPROVIDER_ALLOWS_COLUMN_CREATION.isEnabled(context));
if (!canCreateColumn) {
return false;
}
@@ -115,9 +112,6 @@ public final class TvProviderUtils {
@WorkerThread
public static synchronized boolean checkStateColumn(Context context, Uri uri) {
boolean canCreateColumn = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O);
- canCreateColumn =
- (canCreateColumn
- || PartnerFeatures.TVPROVIDER_ALLOWS_COLUMN_CREATION.isEnabled(context));
if (!canCreateColumn) {
return false;
}
@@ -150,8 +144,8 @@ public final class TvProviderUtils {
return TRUE.equals(sRecordedProgramHasStateColumn);
}
- public static String[] addExtraColumnsToProjection(
- String[] projection, @TvProviderExtraColumn String column) {
+ public static String[] addExtraColumnsToProjection(String[] projection,
+ @TvProviderExtraColumn String column) {
List<String> projectionList = new ArrayList<>(Arrays.asList(projection));
if (!projectionList.contains(column)) {
projectionList.add(column);
diff --git a/src/com/android/tv/util/TvTrackInfoUtils.java b/src/com/android/tv/util/TvTrackInfoUtils.java
index ae30df11..4ec96c62 100644
--- a/src/com/android/tv/util/TvTrackInfoUtils.java
+++ b/src/com/android/tv/util/TvTrackInfoUtils.java
@@ -17,16 +17,9 @@ package com.android.tv.util;
import android.content.Context;
import android.media.tv.TvTrackInfo;
-import android.os.Build;
-import android.os.LocaleList;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.R;
-
-import com.google.common.collect.Iterables;
-
-import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
@@ -45,19 +38,17 @@ public class TvTrackInfoUtils {
private static final int AUDIO_CHANNEL_SURROUND_8 = 8;
/**
- * Compares how closely two {@link android.media.tv.TvTrackInfo}s match {@code languages},
- * {@code channelCount} and {@code id} in that precedence. A listed sorted with this comparator
- * has the worst matches first.
+ * Compares how closely two {@link android.media.tv.TvTrackInfo}s match {@code language}, {@code
+ * channelCount} and {@code id} in that precedence.
*
* @param id The track id to match.
- * @param languages The prioritized list of languages. Languages earlier in the list are a
- * better match.
+ * @param language The language to match.
* @param channelCount The channel count to match.
* @return -1 if lhs is a worse match, 0 if lhs and rhs match equally and 1 if lhs is a better
* match.
*/
public static Comparator<TvTrackInfo> createComparator(
- final String id, final List<String> languages, final int channelCount) {
+ final String id, final String language, final int channelCount) {
return (TvTrackInfo lhs, TvTrackInfo rhs) -> {
if (Objects.equals(lhs, rhs)) {
return 0;
@@ -68,35 +59,26 @@ public class TvTrackInfoUtils {
if (rhs == null) {
return 1;
}
- // Find the first language that matches the lhs and rhs tracks. The earlier match is
- // better. If there is no match set the index to the size of the language list since
- // its the worst match.
- int lhsLangIndex =
- Iterables.indexOf(languages, s -> Utils.isEqualLanguage(lhs.getLanguage(), s));
- if (lhsLangIndex == -1) {
- lhsLangIndex = languages.size();
- }
- int rhsLangIndex =
- Iterables.indexOf(languages, s -> Utils.isEqualLanguage(rhs.getLanguage(), s));
- if (rhsLangIndex == -1) {
- rhsLangIndex = languages.size();
- }
- if (lhsLangIndex != rhsLangIndex) {
- // Return the track with lower index as best
- return Integer.compare(rhsLangIndex, lhsLangIndex);
- }
- boolean lhsCountMatch =
- lhs.getType() != TvTrackInfo.TYPE_AUDIO
- || lhs.getAudioChannelCount() == channelCount;
- boolean rhsCountMatch =
- rhs.getType() != TvTrackInfo.TYPE_AUDIO
- || rhs.getAudioChannelCount() == channelCount;
- if (lhsCountMatch && rhsCountMatch) {
- return Boolean.compare(lhs.getId().equals(id), rhs.getId().equals(id));
- } else if (lhsCountMatch || rhsCountMatch) {
- return Boolean.compare(lhsCountMatch, rhsCountMatch);
+ // Assumes {@code null} language matches to any language since it means user hasn't
+ // selected any track before or selected a track without language information.
+ boolean lhsLangMatch =
+ language == null || Utils.isEqualLanguage(lhs.getLanguage(), language);
+ boolean rhsLangMatch =
+ language == null || Utils.isEqualLanguage(rhs.getLanguage(), language);
+ if (lhsLangMatch && rhsLangMatch) {
+ boolean lhsCountMatch =
+ lhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || lhs.getAudioChannelCount() == channelCount;
+ boolean rhsCountMatch =
+ rhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || rhs.getAudioChannelCount() == channelCount;
+ if (lhsCountMatch && rhsCountMatch) {
+ return Boolean.compare(lhs.getId().equals(id), rhs.getId().equals(id));
+ } else {
+ return Boolean.compare(lhsCountMatch, rhsCountMatch);
+ }
} else {
- return Integer.compare(lhs.getAudioChannelCount(), rhs.getAudioChannelCount());
+ return Boolean.compare(lhsLangMatch, rhsLangMatch);
}
};
}
@@ -115,20 +97,7 @@ public class TvTrackInfoUtils {
if (tracks == null) {
return null;
}
- List<String> languages = new ArrayList<>();
- if (language == null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- LocaleList locales = LocaleList.getDefault();
- for (int i = 0; i < locales.size(); i++) {
- languages.add(locales.get(i).getLanguage());
- }
- } else {
- languages.add(Locale.getDefault().getLanguage());
- }
- } else {
- languages.add(language);
- }
- Comparator<TvTrackInfo> comparator = createComparator(id, languages, channelCount);
+ Comparator<TvTrackInfo> comparator = createComparator(id, language, channelCount);
TvTrackInfo best = null;
for (TvTrackInfo track : tracks) {
if (comparator.compare(track, best) > 0) {
@@ -159,7 +128,11 @@ public class TvTrackInfoUtils {
if (!TextUtils.isEmpty(track.getLanguage())) {
language = new Locale(track.getLanguage()).getDisplayName();
} else {
- Log.d(TAG, "No language information found for the audio track: " + toString(track));
+ Log.d(
+ TAG,
+ "No language information found for the audio track: "
+ + toString(track)
+ );
}
StringBuilder metadata = new StringBuilder();
@@ -234,31 +207,31 @@ public class TvTrackInfoUtils {
public static String toString(TvTrackInfo info) {
int trackType = info.getType();
return "TvTrackInfo{"
- + "type="
- + trackTypeToString(trackType)
- + ", id="
- + info.getId()
- + ", language="
- + info.getLanguage()
- + ", description="
- + info.getDescription()
- + (trackType == TvTrackInfo.TYPE_AUDIO
- ? (", audioChannelCount="
- + info.getAudioChannelCount()
- + ", audioSampleRate="
- + info.getAudioSampleRate())
- : "")
- + (trackType == TvTrackInfo.TYPE_VIDEO
- ? (", videoWidth="
- + info.getVideoWidth()
- + ", videoHeight="
- + info.getVideoHeight()
- + ", videoFrameRate="
- + info.getVideoFrameRate()
- + ", videoPixelAspectRatio="
- + info.getVideoPixelAspectRatio())
- : "")
- + "}";
+ + "type="
+ + trackTypeToString(trackType)
+ + ", id="
+ + info.getId()
+ + ", language="
+ + info.getLanguage()
+ + ", description="
+ + info.getDescription()
+ + (trackType == TvTrackInfo.TYPE_AUDIO
+ ?
+ (", audioChannelCount="
+ + info.getAudioChannelCount()
+ + ", audioSampleRate="
+ + info.getAudioSampleRate()) : "")
+ + (trackType == TvTrackInfo.TYPE_VIDEO
+ ?
+ (", videoWidth="
+ + info.getVideoWidth()
+ + ", videoHeight="
+ + info.getVideoHeight()
+ + ", videoFrameRate="
+ + info.getVideoFrameRate()
+ + ", videoPixelAspectRatio="
+ + info.getVideoPixelAspectRatio()) : "")
+ + "}";
}
private TvTrackInfoUtils() {}
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index c1f9e935..51173739 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -39,19 +39,17 @@ import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.BaseSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.Clock;
import com.android.tv.data.GenreItems;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@@ -326,7 +324,7 @@ public class Utils {
TvContract.buildChannelUri(channelId), timeMs, timeMs);
ContentResolver resolver = context.getContentResolver();
- String[] projection = ProgramImpl.PROJECTION;
+ String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, TvContract.Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
projection =
@@ -336,7 +334,7 @@ public class Utils {
}
try (Cursor cursor = resolver.query(uri, projection, null, null, null)) {
if (cursor != null && cursor.moveToNext()) {
- return ProgramImpl.fromCursor(cursor);
+ return Program.fromCursor(cursor);
}
}
return null;
@@ -605,7 +603,6 @@ public class Utils {
}
/** Returns the label for a given input. Returns the custom label, if any. */
- @Nullable
public static String loadLabel(Context context, TvInputInfo input) {
if (input == null) {
return null;
@@ -615,7 +612,7 @@ public class Utils {
CharSequence customLabel = inputManager.loadCustomLabel(input);
String label = (customLabel == null) ? null : customLabel.toString();
if (TextUtils.isEmpty(label)) {
- label = inputManager.loadLabel(input);
+ label = inputManager.loadLabel(input).toString();
}
return label;
}
@@ -717,6 +714,33 @@ public class Utils {
return context.createConfigurationContext(config).getText(resourceId);
}
+ /** Checks where there is any internal TV input. */
+ public static boolean hasInternalTvInputs(Context context, boolean tunerInputOnly) {
+ for (TvInputInfo input :
+ TvSingletons.getSingletons(context)
+ .getTvInputManagerHelper()
+ .getTvInputInfos(true, tunerInputOnly)) {
+ if (isInternalTvInput(context, input.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Returns the internal TV inputs. */
+ public static List<TvInputInfo> getInternalTvInputs(Context context, boolean tunerInputOnly) {
+ List<TvInputInfo> inputs = new ArrayList<>();
+ for (TvInputInfo input :
+ TvSingletons.getSingletons(context)
+ .getTvInputManagerHelper()
+ .getTvInputInfos(true, tunerInputOnly)) {
+ if (isInternalTvInput(context, input.getId())) {
+ inputs.add(input);
+ }
+ }
+ return inputs;
+ }
+
/** Checks whether the input is internal or not. */
public static boolean isInternalTvInput(Context context, String inputId) {
ComponentName unflattenInputId = ComponentName.unflattenFromString(inputId);
diff --git a/src/com/android/tv/util/account/AccountHelper.java b/src/com/android/tv/util/account/AccountHelper.java
index d54c2f56..e98b42ec 100644
--- a/src/com/android/tv/util/account/AccountHelper.java
+++ b/src/com/android/tv/util/account/AccountHelper.java
@@ -35,11 +35,4 @@ public interface AccountHelper {
/** Returns all eligible accounts . */
@Nullable
Account getFirstEligibleAccount();
-
- /**
- * Initialize the account helper.
- *
- * <p>This method is a no op if called more than once.
- */
- void init();
}
diff --git a/src/com/android/tv/util/account/AccountHelperImpl.java b/src/com/android/tv/util/account/AccountHelperImpl.java
index e97cc3f2..58fbd27e 100644
--- a/src/com/android/tv/util/account/AccountHelperImpl.java
+++ b/src/com/android/tv/util/account/AccountHelperImpl.java
@@ -21,12 +21,8 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
-import javax.inject.Inject;
-import javax.inject.Singleton;
/** Helper methods for getting and selecting a user account. */
-@Singleton
public class AccountHelperImpl implements com.android.tv.util.account.AccountHelper {
private static final String SELECTED_ACCOUNT = "android.tv.livechannels.selected_account";
@@ -35,8 +31,7 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
@Nullable private Account mSelectedAccount;
- @Inject
- public AccountHelperImpl(@ApplicationContext Context context) {
+ public AccountHelperImpl(Context context) {
mContext = context.getApplicationContext();
mDefaultPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
}
@@ -103,9 +98,4 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
PreferenceManager.getDefaultSharedPreferences(mContext);
defaultPreferences.edit().putString(SELECTED_ACCOUNT, account.name).commit();
}
-
- @Override
- public void init() {
- // do nothing.
- }
}
diff --git a/src/com/android/tv/util/images/ImageLoader.java b/src/com/android/tv/util/images/ImageLoader.java
index e026f26a..d2ad0eb1 100644
--- a/src/com/android/tv/util/images/ImageLoader.java
+++ b/src/com/android/tv/util/images/ImageLoader.java
@@ -29,13 +29,9 @@ import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.util.ArraySet;
import android.util.Log;
-
-import androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms;
-
import com.android.tv.R;
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
-
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
@@ -168,8 +164,8 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
- Context context, String uriString, ImageLoaderCallback<T> callback) {
+ public static boolean loadBitmap(
+ Context context, String uriString, ImageLoaderCallback callback) {
return loadBitmap(context, uriString, Integer.MAX_VALUE, Integer.MAX_VALUE, callback);
}
@@ -182,12 +178,12 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
+ public static boolean loadBitmap(
Context context,
String uriString,
int maxWidth,
int maxHeight,
- ImageLoaderCallback<T> callback) {
+ ImageLoaderCallback callback) {
if (DEBUG) {
Log.d(TAG, "loadBitmap() " + uriString);
}
@@ -195,12 +191,12 @@ public final class ImageLoader {
context, uriString, maxWidth, maxHeight, callback, IMAGE_THREAD_POOL_EXECUTOR);
}
- private static <T> boolean doLoadBitmap(
+ private static boolean doLoadBitmap(
Context context,
String uriString,
int maxWidth,
int maxHeight,
- ImageLoaderCallback<T> callback,
+ ImageLoaderCallback callback,
Executor executor) {
// Check the cache before creating a Task. The cache will be checked again in doLoadBitmap
// but checking a cache is much cheaper than creating an new task.
@@ -226,8 +222,7 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
- ImageLoaderCallback<T> callback, LoadBitmapTask<T> loadBitmapTask) {
+ public static boolean loadBitmap(ImageLoaderCallback callback, LoadBitmapTask loadBitmapTask) {
if (DEBUG) {
Log.d(TAG, "loadBitmap() " + loadBitmapTask);
}
@@ -236,8 +231,8 @@ public final class ImageLoader {
/** @return {@code true} if the load is complete and the callback is executed. */
@UiThread
- private static <T> boolean doLoadBitmap(
- ImageLoaderCallback<T> callback, Executor executor, LoadBitmapTask<T> loadBitmapTask) {
+ private static boolean doLoadBitmap(
+ ImageLoaderCallback callback, Executor executor, LoadBitmapTask loadBitmapTask) {
ScaledBitmapInfo bitmapInfo = loadBitmapTask.getFromCache();
boolean needToReload = loadBitmapTask.isReloadNeeded();
if (bitmapInfo != null && !needToReload) {
@@ -272,11 +267,11 @@ public final class ImageLoader {
*
* <p>Implement {@link #doGetBitmapInBackground} to do the actual loading.
*/
- public abstract static class LoadBitmapTask<T> extends AsyncTask<Void, Void, ScaledBitmapInfo> {
+ public abstract static class LoadBitmapTask extends AsyncTask<Void, Void, ScaledBitmapInfo> {
protected final Context mAppContext;
protected final int mMaxWidth;
protected final int mMaxHeight;
- private final Set<ImageLoaderCallback<T>> mCallbacks = new ArraySet<>();
+ private final Set<ImageLoaderCallback> mCallbacks = new ArraySet<>();
private final ImageCache mImageCache;
private final String mKey;
@@ -358,7 +353,7 @@ public final class ImageLoader {
public final void onPostExecute(ScaledBitmapInfo scaledBitmapInfo) {
if (DEBUG) Log.d(ImageLoader.TAG, "Bitmap is loaded " + mKey);
- for (ImageLoader.ImageLoaderCallback<T> callback : mCallbacks) {
+ for (ImageLoader.ImageLoaderCallback callback : mCallbacks) {
callback.onBitmapLoaded(scaledBitmapInfo == null ? null : scaledBitmapInfo.bitmap);
}
ImageLoader.sPendingListMap.remove(mKey);
@@ -381,7 +376,7 @@ public final class ImageLoader {
}
}
- private static final class LoadBitmapFromUriTask<T> extends LoadBitmapTask<T> {
+ private static final class LoadBitmapFromUriTask extends LoadBitmapTask {
private LoadBitmapFromUriTask(
Context context,
ImageCache imageCache,
@@ -400,7 +395,7 @@ public final class ImageLoader {
}
/** Loads and caches the logo for a given {@link TvInputInfo} */
- public static final class LoadTvInputLogoTask<T> extends LoadBitmapTask<T> {
+ public static final class LoadTvInputLogoTask extends LoadBitmapTask {
private final TvInputInfo mInfo;
public LoadTvInputLogoTask(Context context, ImageCache cache, TvInputInfo info) {
@@ -419,10 +414,9 @@ public final class ImageLoader {
@Override
public ScaledBitmapInfo doGetBitmapInBackground() {
Drawable drawable = mInfo.loadIcon(mAppContext);
- Bitmap bm =
- drawable instanceof BitmapDrawable
- ? ((BitmapDrawable) drawable).getBitmap()
- : BitmapUtils.drawableToBitmap(drawable);
+ Bitmap bm = drawable instanceof BitmapDrawable
+ ? ((BitmapDrawable) drawable).getBitmap()
+ : BitmapUtils.drawableToBitmap(drawable);
return bm == null
? null
: BitmapUtils.createScaledBitmapInfo(getKey(), bm, mMaxWidth, mMaxHeight);
@@ -434,46 +428,6 @@ public final class ImageLoader {
}
}
- /**
- * Calculates Aspect Ratio of Poster Art from Uri.
- *
- * <p><b>Note</b> the function will check the cache before loading the bitmap
- *
- * @return the Aspect Ratio of the Poster Art.
- */
- public static int getAspectRatioFromPosterArtUri(Context context, String uriString) {
- // Check the cache before loading the bitmap.
- ImageCache imageCache = ImageCache.getInstance();
- ScaledBitmapInfo bitmapInfo = imageCache.get(uriString);
- int bitmapWidth;
- int bitmapHeight;
- float bitmapAspectRatio;
- int aspectRatio;
- if (bitmapInfo == null) {
- bitmapInfo =
- BitmapUtils.decodeSampledBitmapFromUriString(
- context, uriString, Integer.MAX_VALUE, Integer.MAX_VALUE);
- }
- bitmapWidth = bitmapInfo.bitmap.getWidth();
- bitmapHeight = bitmapInfo.bitmap.getHeight();
- bitmapAspectRatio = (float) bitmapWidth / bitmapHeight;
- /* Assign nearest aspect ratio from the defined values in Preview Programs */
- if (bitmapAspectRatio > 0 && bitmapAspectRatio <= 0.6803) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_2_3;
- } else if (bitmapAspectRatio > 0.6803 && bitmapAspectRatio <= 0.8469) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_MOVIE_POSTER;
- } else if (bitmapAspectRatio > 0.8469 && bitmapAspectRatio <= 1.1667) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_1_1;
- } else if (bitmapAspectRatio > 1.1667 && bitmapAspectRatio <= 1.4167) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_4_3;
- } else if (bitmapAspectRatio > 1.4167 && bitmapAspectRatio <= 1.6389) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_3_2;
- } else {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_16_9;
- }
- return aspectRatio;
- }
-
private static synchronized Handler getMainHandler() {
if (sMainHandler == null) {
sMainHandler = new Handler(Looper.getMainLooper());
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
deleted file mode 100644
index 1abaaf76..00000000
--- a/tests/common/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-android_library {
- name: "tv-test-common",
-
- // Include all test java files.
- srcs: [
- "src/**/*.java",
- "src/**/I*.aidl",
- ],
-
- static_libs: [
- "android-support-annotations",
- "androidx.test.runner",
- "androidx.test.rules",
- "tv-guava-android-jar",
- "mockito-robolectric-prebuilt",
- "tv-lib-truth",
- "ub-uiautomator",
- "Robolectric_all-target",
- ],
-
- // Link tv-common as shared library to avoid the problem of initialization of the constants
- libs: [
- "tv-common",
- "LiveTv",
- ],
-
- sdk_version: "system_current",
-
- resource_dirs: ["res"],
- aidl: {
- local_include_dirs: ["src"],
- },
-
-}
diff --git a/tests/common/Android.mk b/tests/common/Android.mk
index e434e124..7a111d0c 100644
--- a/tests/common/Android.mk
+++ b/tests/common/Android.mk
@@ -1,23 +1,29 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := tv-test-common-robo
-
+# Include all test java files.
LOCAL_SRC_FILES := \
- $(call all-java-files-under, src/com/android/tv/testing/robo) \
- $(call all-java-files-under, src/com/android/tv/testing/shadows)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+ $(call all-java-files-under, src) \
+ $(call all-Iaidl-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- robolectric_android-all-stub \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- tv-test-common \
+ android-support-annotations \
+ androidx.test.runner \
+ androidx.test.rules \
+ tv-guava-android-jar \
+ mockito-target \
+ tv-lib-truth \
+ ub-uiautomator \
-LOCAL_INSTRUMENTATION_FOR := LiveTv
+# Link tv-common as shared library to avoid the problem of initialization of the constants
+LOCAL_JAVA_LIBRARIES := tv-common
+LOCAL_INSTRUMENTATION_FOR := LiveTv
+LOCAL_MODULE := tv-test-common
LOCAL_MODULE_TAGS := optional
LOCAL_SDK_VERSION := system_current
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/src
+
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/common/AndroidManifest.xml b/tests/common/AndroidManifest.xml
index ec9614da..3a769a8d 100644
--- a/tests/common/AndroidManifest.xml
+++ b/tests/common/AndroidManifest.xml
@@ -18,6 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.testing"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application />
</manifest>
diff --git a/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java b/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java
index 1592897c..ba4662ee 100644
--- a/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java
+++ b/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java
@@ -16,8 +16,6 @@
package com.android.tv.testing;
-import static com.google.common.truth.Fact.simpleFact;
-
import android.support.annotation.Nullable;
import com.android.tv.data.ChannelNumber;
import com.google.common.truth.ComparableSubject;
@@ -26,7 +24,8 @@ import com.google.common.truth.Subject;
import com.google.common.truth.Truth;
/** Propositions for {@link ChannelNumber} subjects. */
-public final class ChannelNumberSubject extends ComparableSubject {
+public final class ChannelNumberSubject
+ extends ComparableSubject<ChannelNumberSubject, ChannelNumber> {
private static final Subject.Factory<ChannelNumberSubject, ChannelNumber> FACTORY =
ChannelNumberSubject::new;
@@ -38,30 +37,30 @@ public final class ChannelNumberSubject extends ComparableSubject {
return Truth.assertAbout(channelNumbers()).that(actual);
}
- private final ChannelNumber actual;
-
- public ChannelNumberSubject(FailureMetadata failureMetadata, @Nullable ChannelNumber subject) {
- super(failureMetadata, subject);
- this.actual = subject;
+ public ChannelNumberSubject(FailureMetadata failureMetadata, @Nullable ChannelNumber subject) {
+ super(failureMetadata, subject);
}
public void displaysAs(int major) {
- if (!actual.majorNumber.equals(Integer.toString(major)) || actual.hasDelimiter) {
- failWithActual("expected to display as", major);
+ if (!getSubject().majorNumber.equals(Integer.toString(major))
+ || getSubject().hasDelimiter) {
+ fail("displaysAs", major);
}
}
public void displaysAs(int major, int minor) {
- if (!actual.majorNumber.equals(Integer.toString(major))
- || !actual.minorNumber.equals(Integer.toString(minor))
- || !actual.hasDelimiter) {
- failWithActual("expected to display as", major + "-" + minor);
+ if (!getSubject().majorNumber.equals(Integer.toString(major))
+ || !getSubject().minorNumber.equals(Integer.toString(minor))
+ || !getSubject().hasDelimiter) {
+ fail("displaysAs", major + "-" + minor);
}
}
public void isEmpty() {
- if (!actual.majorNumber.isEmpty() || !actual.minorNumber.isEmpty() || actual.hasDelimiter) {
- failWithActual(simpleFact("expected to be empty"));
+ if (!getSubject().majorNumber.isEmpty()
+ || !getSubject().minorNumber.isEmpty()
+ || getSubject().hasDelimiter) {
+ fail("isEmpty");
}
}
}
diff --git a/tests/common/src/com/android/tv/testing/ComparatorTester.java b/tests/common/src/com/android/tv/testing/ComparatorTester.java
index 01c3964d..6ebd8b4e 100644
--- a/tests/common/src/com/android/tv/testing/ComparatorTester.java
+++ b/tests/common/src/com/android/tv/testing/ComparatorTester.java
@@ -16,198 +16,128 @@
package com.android.tv.testing;
-import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
-
-import android.support.annotation.Nullable;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.primitives.Ints;
+import static junit.framework.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.List;
/**
- * Tests that a given {@link Comparator} (or the implementation of {@link Comparable}) is correct.
- * To use, repeatedly call {@link #addEqualityGroup(Object...)} with sets of objects that should be
- * equal. The calls to {@link #addEqualityGroup(Object...)} must be made in sorted order. Then call
- * {@link #testCompare()} to test the comparison. For example:
- *
- * <pre>{@code
- * new ComparatorTester()
- * .addEqualityGroup(1)
- * .addEqualityGroup(2)
- * .addEqualityGroup(3)
- * .testCompare();
- * }</pre>
+ * Tester for {@link Comparator} relationships between groups of T.
*
- * <p>By default, a {@code Comparator} is not tested for compatibility with {@link
- * Object#equals(Object)}. If that is desired, use the {link #requireConsistencyWithEquals()} to
- * explicitly activate the check. For example:
+ * <p>To use, create a new {@link ComparatorTester} and add comparable groups where each group
+ * contains objects that are {@link Comparator#compare(Object, Object)} == 0 to each other. Groups
+ * are added in order asserting that all earlier groups have compare < 0 for all later groups.
*
* <pre>{@code
- * new ComparatorTester(Comparator.naturalOrder())
- * .requireConsistencyWithEquals()
- * .addEqualityGroup(1)
- * .addEqualityGroup(2)
- * .addEqualityGroup(3)
- * .testCompare();
+ * ComparatorTester
+ * .withoutEqualsTest(String.CASE_INSENSITIVE_ORDER)
+ * .addComparableGroup("Hello", "HELLO")
+ * .addComparableGroup("World", "wORLD")
+ * .addComparableGroup("ZEBRA")
+ * .test();
* }</pre>
*
- * <p>If for some reason you need to suppress the compatibility check when testing a {@code
- * Comparable}, use the {link #permitInconsistencyWithEquals()} to explicitly deactivate the check.
- * For example:
- *
- * <pre>{@code
- * new ComparatorTester()
- * .permitInconsistencyWithEquals()
- * .addEqualityGroup(1)
- * .addEqualityGroup(2)
- * .addEqualityGroup(3)
- * .testCompare();
- * }</pre>
+ * @param <T> the type of objects to compare.
*/
-public class ComparatorTester {
- @SuppressWarnings({"unchecked", "rawtypes"})
- @Nullable
- private final Comparator comparator;
+public class ComparatorTester<T> {
- /** The items that we are checking, stored as a sorted set of equivalence classes. */
- private final List<List<Object>> equalityGroups;
+ private final List<List<T>> listOfGroups = new ArrayList<>();
- /** Whether to enforce a.equals(b) == (a.compareTo(b) == 0) */
- private boolean testForEqualsCompatibility;
+ private final Comparator<T> comparator;
- /**
- * Creates a new instance that tests the order of objects using the natural order (as defined by
- * {@link Comparable}).
- */
- public ComparatorTester() {
- this(null);
+ public static <T> ComparatorTester<T> withoutEqualsTest(Comparator<T> comparator) {
+ return new ComparatorTester<>(comparator);
}
- /**
- * Creates a new instance that tests the order of objects using the given comparator. Or, if the
- * comparator is {@code null}, the natural ordering (as defined by {@link Comparable})
- */
- public ComparatorTester(@Nullable Comparator<?> comparator) {
- this.equalityGroups = Lists.newArrayList();
+ private ComparatorTester(Comparator<T> comparator) {
this.comparator = comparator;
- this.testForEqualsCompatibility = (this.comparator == null);
- }
-
- /**
- * Activates enforcement of {@code a.equals(b) == (a.compareTo(b) == 0)}. This is off by default
- * when testing {@link Comparator}s, but can be turned on if required.
- */
- public ComparatorTester requireConsistencyWithEquals() {
- testForEqualsCompatibility = true;
- return this;
}
- /**
- * Deactivates enforcement of {@code a.equals(b) == (a.compareTo(b) == 0)}. This is on by
- * default when testing {@link Comparable}s, but can be turned off if required.
- */
- public ComparatorTester permitInconsistencyWithEquals() {
- testForEqualsCompatibility = false;
+ @SafeVarargs
+ public final ComparatorTester<T> addComparableGroup(T... items) {
+ listOfGroups.add(Arrays.asList(items));
return this;
}
- /**
- * Adds a set of objects to the test which should all compare as equal. All of the elements in
- * {@code objects} must be greater than any element of {@code objects} in a previous call to
- * {@link #addEqualityGroup(Object...)}.
- *
- * @return {@code this} (to allow chaining of calls)
- */
- public ComparatorTester addEqualityGroup(Object... objects) {
- Preconditions.checkNotNull(objects);
- Preconditions.checkArgument(objects.length > 0, "Array must not be empty");
- equalityGroups.add(ImmutableList.copyOf(objects));
- return this;
- }
-
- @SuppressWarnings({"unchecked"})
- private int compare(Object a, Object b) {
- int compareValue;
- if (comparator == null) {
- compareValue = ((Comparable<Object>) a).compareTo(b);
- } else {
- compareValue = comparator.compare(a, b);
- }
- return compareValue;
- }
-
- public final void testCompare() {
- doTestEquivalanceGroupOrdering();
- if (testForEqualsCompatibility) {
- doTestEqualsCompatibility();
+ public void test() {
+ for (int i = 0; i < listOfGroups.size(); i++) {
+ List<T> currentGroup = listOfGroups.get(i);
+ for (int j = 0; j < i; j++) {
+ List<T> lhs = listOfGroups.get(j);
+ assertOrder(i, j, lhs, currentGroup);
+ }
+ assertZero(currentGroup);
+ for (int j = i + 1; j < listOfGroups.size(); j++) {
+ List<T> rhs = listOfGroups.get(j);
+ assertOrder(i, j, currentGroup, rhs);
+ }
}
+ // TODO: also test equals
}
- private final void doTestEquivalanceGroupOrdering() {
- for (int referenceIndex = 0; referenceIndex < equalityGroups.size(); referenceIndex++) {
- for (Object reference : equalityGroups.get(referenceIndex)) {
- testNullCompare(reference);
- testClassCast(reference);
- for (int otherIndex = 0; otherIndex < equalityGroups.size(); otherIndex++) {
- for (Object other : equalityGroups.get(otherIndex)) {
- assertWithMessage("compare(%s, %s)", reference, other)
- .that(Integer.signum(compare(reference, other)))
- .isEqualTo(
- Integer.signum(Ints.compare(referenceIndex, otherIndex)));
- }
- }
- }
- }
+ private void assertOrder(int less, int more, List<T> lessGroup, List<T> moreGroup) {
+ assertLess(less, more, lessGroup, moreGroup);
+ assertMore(more, less, moreGroup, lessGroup);
}
- private final void doTestEqualsCompatibility() {
- for (List<Object> referenceGroup : equalityGroups) {
- for (Object reference : referenceGroup) {
- for (List<Object> otherGroup : equalityGroups) {
- for (Object other : otherGroup) {
- assertWithMessage(
- "Testing equals() for compatibility with"
- + " compare()/compareTo(), add a call to"
- + " doNotRequireEqualsCompatibility() if this is not"
- + " required")
- .withMessage("%s.equals(%s)", reference, other)
- .that(reference.equals(other))
- .isEqualTo(compare(reference, other) == 0);
- }
- }
+ private void assertLess(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
+ int leftSub = 0;
+ for (T leftItem : leftGroup) {
+ int rightSub = 0;
+ for (T rightItem : rightGroup) {
+ String leftName = "Item[" + left + "," + (leftSub++) + "]";
+ String rName = "Item[" + right + "," + (rightSub++) + "]";
+ assertEquals(
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rName
+ + " "
+ + rightItem
+ + " is <0",
+ true,
+ comparator.compare(leftItem, rightItem) < 0);
}
}
}
- private void testNullCompare(Object obj) {
- // Comparator does not require any specific behavior for null.
- if (comparator == null) {
- try {
- compare(obj, null);
- assert_().fail("Expected NullPointerException in %s.compare(null)", obj);
- } catch (NullPointerException expected) {
- // TODO(cpovirk): Consider accepting JavaScriptException under GWT
+ private void assertMore(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
+ int leftSub = 0;
+ for (T leftItem : leftGroup) {
+ int rightSub = 0;
+ for (T rightItem : rightGroup) {
+ String leftName = "Item[" + left + "," + (leftSub++) + "]";
+ String rName = "Item[" + right + "," + (rightSub++) + "]";
+ assertEquals(
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rName
+ + " "
+ + rightItem
+ + " is >0",
+ true,
+ comparator.compare(leftItem, rightItem) > 0);
}
}
}
- @SuppressWarnings("unchecked")
- private void testClassCast(Object obj) {
- if (comparator == null) {
- try {
- compare(obj, ICanNotBeCompared.INSTANCE);
- assert_().fail("Expected ClassCastException in %s.compareTo(otherObject)", obj);
- } catch (ClassCastException expected) {
+ private void assertZero(Collection<T> group) {
+ // Test everything against everything in both directions, including against itself.
+ for (T leftItem : group) {
+ for (T rightItem : group) {
+ assertEquals(
+ leftItem + " compareTo " + rightItem,
+ 0,
+ comparator.compare(leftItem, rightItem));
}
}
}
-
- private static final class ICanNotBeCompared {
- static final ComparatorTester.ICanNotBeCompared INSTANCE = new ICanNotBeCompared();
- }
}
diff --git a/tests/common/src/com/android/tv/testing/EpgTestData.java b/tests/common/src/com/android/tv/testing/EpgTestData.java
index d22bd283..362f336a 100644
--- a/tests/common/src/com/android/tv/testing/EpgTestData.java
+++ b/tests/common/src/com/android/tv/testing/EpgTestData.java
@@ -18,17 +18,13 @@ package com.android.tv.testing;
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.Lineup;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.testing.fakes.FakeClock;
-
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
-
import java.util.concurrent.TimeUnit;
/** EPG data for use in tests. */
@@ -79,14 +75,14 @@ public abstract class EpgTestData {
// Start and end time may be negative meaning they happen before "now".
public static final Program PROGRAM_1 =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle("Program 1")
.setStartTimeUtcMillis(0)
.setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
.build();
public static final Program PROGRAM_2 =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle("Program 2")
.setStartTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
.setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(60))
@@ -195,7 +191,7 @@ public abstract class EpgTestData {
new Function<Program, Program>() {
@Override
public Program apply(Program p) {
- return new ProgramImpl.Builder(p)
+ return new Program.Builder(p)
.setStartTimeUtcMillis(p.getStartTimeUtcMillis() + time)
.setEndTimeUtcMillis(p.getEndTimeUtcMillis() + time)
.build();
diff --git a/tests/common/src/com/android/tv/testing/fakes/FakeClock.java b/tests/common/src/com/android/tv/testing/FakeClock.java
index adef3cd3..f5941939 100644
--- a/tests/common/src/com/android/tv/testing/fakes/FakeClock.java
+++ b/tests/common/src/com/android/tv/testing/FakeClock.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.testing.fakes;
+package com.android.tv.testing;
import com.android.tv.common.util.Clock;
import java.util.concurrent.TimeUnit;
diff --git a/tests/common/src/com/android/tv/testing/FakeEpgReader.java b/tests/common/src/com/android/tv/testing/FakeEpgReader.java
index 24afe8eb..fb35c652 100644
--- a/tests/common/src/com/android/tv/testing/FakeEpgReader.java
+++ b/tests/common/src/com/android/tv/testing/FakeEpgReader.java
@@ -19,17 +19,13 @@ package com.android.tv.testing;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Range;
-
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.ChannelNumber;
import com.android.tv.data.Lineup;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.data.SeriesInfo;
-import com.android.tv.testing.fakes.FakeClock;
-
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
@@ -37,7 +33,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
-
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -149,7 +144,7 @@ public final class FakeEpgReader implements EpgReader {
@Nullable
@Override
public Program apply(@Nullable Program program) {
- return new ProgramImpl.Builder(program)
+ return new Program.Builder(program)
.setChannelId(channel.getChannel().getId())
.setPackageName(channel.getChannel().getPackageName())
.build();
diff --git a/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java b/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java
index be083856..85bdcf04 100644
--- a/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java
+++ b/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java
@@ -17,14 +17,13 @@
package com.android.tv.testing;
import android.content.Context;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
import com.android.tv.util.TvInputManagerHelper;
/** Fake TvInputManagerHelper. */
public class FakeTvInputManagerHelper extends TvInputManagerHelper {
public FakeTvInputManagerHelper(Context context) {
- super(context, new FakeTvInputManager(), DefaultLegacyFlags.DEFAULT);
+ super(context, new FakeTvInputManager());
}
public FakeTvInputManager getFakeTvInputManager() {
diff --git a/tests/common/src/com/android/tv/testing/fakes/FakeTvProvider.java b/tests/common/src/com/android/tv/testing/FakeTvProvider.java
index 36e97bcc..20903c60 100644
--- a/tests/common/src/com/android/tv/testing/fakes/FakeTvProvider.java
+++ b/tests/common/src/com/android/tv/testing/FakeTvProvider.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.testing.fakes;
+package com.android.tv.testing;
import android.annotation.SuppressLint;
import android.content.ContentProvider;
@@ -54,7 +54,7 @@ import androidx.tvprovider.media.tv.TvContractCompat.Programs;
import androidx.tvprovider.media.tv.TvContractCompat.Programs.Genres;
import androidx.tvprovider.media.tv.TvContractCompat.RecordedPrograms;
import androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms;
-import com.android.tv.common.util.sql.SqlParams;
+import com.android.tv.util.SqlParams;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
diff --git a/tests/common/src/com/android/tv/testing/TestSingletonApp.java b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
index e233d95d..f1a98ff5 100644
--- a/tests/common/src/com/android/tv/testing/TestSingletonApp.java
+++ b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
@@ -19,23 +19,25 @@ package com.android.tv.testing;
import android.app.Application;
import android.media.tv.TvInputManager;
import android.os.AsyncTask;
-
import com.android.tv.InputSessionManager;
import com.android.tv.MainActivityWrapper;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BaseApplication;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
+import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
+import com.android.tv.common.flags.impl.DefaultTunerFlags;
import com.android.tv.common.flags.impl.DefaultUiFlags;
-import com.android.tv.common.flags.impl.SettableFlagsModule;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.common.util.Clock;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -45,38 +47,47 @@ import com.android.tv.dvr.recorder.RecordingScheduler;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.stub.StubPerformanceMonitor;
import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.fakes.FakeClock;
import com.android.tv.testing.testdata.TestData;
import com.android.tv.tuner.singletons.TunerSingletons;
+import com.android.tv.tuner.source.TsDataSourceManager;
+import com.android.tv.tuner.source.TunerTsStreamerManager;
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactoryImpl;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-
+import com.android.tv.util.account.AccountHelper;
import com.google.common.base.Optional;
-
-import dagger.Lazy;
-
import java.util.concurrent.Executor;
+import javax.inject.Provider;
-/** Test application for TV app. */
+/** Test application for Live TV. */
public class TestSingletonApp extends Application
implements TvSingletons, TunerSingletons, HasSingletons<TvSingletons> {
public final FakeClock fakeClock = FakeClock.createWithCurrentTime();
public final FakeEpgReader epgReader = new FakeEpgReader(fakeClock);
public final FakeEpgFetcher epgFetcher = new FakeEpgFetcher();
- public final SettableFlagsModule flagsModule = new SettableFlagsModule();
public FakeTvInputManagerHelper tvInputManagerHelper;
public SetupUtils setupUtils;
public DvrManager dvrManager;
public DvrDataManager mDvrDataManager;
- @DbExecutor public Executor dbExecutor = AsyncTask.SERIAL_EXECUTOR;
- private final Lazy<EpgReader> mEpgReaderProvider = () -> epgReader;
+ private final Provider<EpgReader> mEpgReaderProvider = SingletonProvider.create(epgReader);
private final Optional<BuiltInTunerManager> mBuiltInTunerManagerOptional = Optional.absent();
-
- private final PerformanceMonitor mPerformanceMonitor = new StubPerformanceMonitor();
+ private final DefaultBackendKnobsFlags mBackendKnobs = new DefaultBackendKnobsFlags();
+ private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
+ private final DefaultUiFlags mUiFlags = new DefaultUiFlags();
+ private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
+ new DefaultConcurrentDvrPlaybackFlags();
+ private final TsDataSourceManager.Factory mTsDataSourceManagerFactory =
+ new TsDataSourceManager.Factory(() -> new TunerTsStreamerManager(null));
+ private final TunerSessionFactoryImpl mTunerSessionFactory =
+ new TunerSessionFactoryImpl(
+ new DefaultTunerFlags(),
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
+ private PerformanceMonitor mPerformanceMonitor;
private ChannelDataManager mChannelDataManager;
@Override
@@ -85,9 +96,7 @@ public class TestSingletonApp extends Application
tvInputManagerHelper = new FakeTvInputManagerHelper(this);
setupUtils = new SetupUtils(this, mBuiltInTunerManagerOptional);
tvInputManagerHelper.start();
- mChannelDataManager =
- new ChannelDataManager(
- this, tvInputManagerHelper, dbExecutor, getContentResolver());
+ mChannelDataManager = new ChannelDataManager(this, tvInputManagerHelper);
mChannelDataManager.start();
mDvrDataManager = new DvrDataManagerInMemoryImpl(this, fakeClock);
// HACK reset the singleton for tests
@@ -115,11 +124,21 @@ public class TestSingletonApp extends Application
}
@Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return false;
+ }
+
+ @Override
public ProgramDataManager getProgramDataManager() {
return null;
}
@Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return false;
+ }
+
+ @Override
public PreviewDataManager getPreviewDataManager() {
return null;
}
@@ -165,11 +184,16 @@ public class TestSingletonApp extends Application
}
@Override
- public Lazy<EpgReader> providesEpgReader() {
+ public Provider<EpgReader> providesEpgReader() {
return mEpgReaderProvider;
}
@Override
+ public EpgFetcher getEpgFetcher() {
+ return epgFetcher;
+ }
+
+ @Override
public SetupUtils getSetupUtils() {
return setupUtils;
}
@@ -180,11 +204,21 @@ public class TestSingletonApp extends Application
}
@Override
+ public ExperimentLoader getExperimentLoader() {
+ return new ExperimentLoader();
+ }
+
+ @Override
public MainActivityWrapper getMainActivityWrapper() {
return null;
}
@Override
+ public AccountHelper getAccountHelper() {
+ return null;
+ }
+
+ @Override
public Clock getClock() {
return fakeClock;
}
@@ -201,6 +235,9 @@ public class TestSingletonApp extends Application
@Override
public PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = new StubPerformanceMonitor();
+ }
return mPerformanceMonitor;
}
@@ -211,22 +248,22 @@ public class TestSingletonApp extends Application
@Override
public Executor getDbExecutor() {
- return dbExecutor;
+ return AsyncTask.SERIAL_EXECUTOR;
}
@Override
public DefaultBackendKnobsFlags getBackendKnobs() {
- return flagsModule.backendKnobsFlags;
+ return mBackendKnobs;
}
@Override
public DefaultCloudEpgFlags getCloudEpgFlags() {
- return flagsModule.cloudEpgFlags;
+ return mCloudEpgFlags;
}
@Override
public DefaultUiFlags getUiFlags() {
- return flagsModule.uiFlags;
+ return mUiFlags;
}
@Override
@@ -235,6 +272,15 @@ public class TestSingletonApp extends Application
}
@Override
+ public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ public TunerSessionFactory getTunerSessionFactory() {
+ return mTunerSessionFactory;
+ }
+
+ @Override
public TvSingletons singletons() {
return this;
}
diff --git a/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java b/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java
index 944d5395..890c51e0 100644
--- a/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java
+++ b/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java
@@ -23,8 +23,6 @@ public final class ConfigConstants {
public static final String MANIFEST = "vendor/unbundled_google/packages/TV/AndroidManifest.xml";
public static final int SDK = Build.VERSION_CODES.M;
- public static final int MIN_SDK = Build.VERSION_CODES.M;
- public static final int MAX_SDK = Build.VERSION_CODES.P;
private ConfigConstants() {}
}
diff --git a/tests/common/src/com/android/tv/testing/robo/ContentProviders.java b/tests/common/src/com/android/tv/testing/robo/ContentProviders.java
deleted file mode 100644
index aaaa11df..00000000
--- a/tests/common/src/com/android/tv/testing/robo/ContentProviders.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.testing.robo;
-
-import android.content.ContentProvider;
-import android.content.pm.ProviderInfo;
-import org.robolectric.Robolectric;
-import org.robolectric.android.controller.ContentProviderController;
-import org.robolectric.shadows.ShadowContentResolver;
-
-/** Static utilities for using content providers in tests. */
-public final class ContentProviders {
-
- /** Builds creates and register a ContentProvider with the given authority. */
- public static <T extends ContentProvider> T register(Class<T> providerClass, String authority) {
- ProviderInfo info = new ProviderInfo();
- info.authority = authority;
- ContentProviderController<T> contentProviderController =
- Robolectric.buildContentProvider(providerClass);
- T provider = contentProviderController.create(info).get();
- provider.onCreate();
- ShadowContentResolver.registerProviderInternal(authority, provider);
- return provider;
- }
-
- private ContentProviders() {}
-}
diff --git a/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java b/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
deleted file mode 100644
index ad91f3d9..00000000
--- a/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.testing.robo;
-
-import android.media.tv.TvContract;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.fakes.FakeTvProvider;
-import com.android.tv.testing.testdata.TestData;
-import java.util.concurrent.TimeUnit;
-import org.robolectric.Robolectric;
-
-/** Static utilities for using {@link TestSingletonApp} in roboletric tests. */
-public final class RobotTestAppHelper {
-
- public static void loadTestData(TestSingletonApp app, TestData testData) {
- ContentProviders.register(FakeTvProvider.class, TvContract.AUTHORITY);
- app.loadTestData(testData, TimeUnit.DAYS.toMillis(1));
- Robolectric.flushBackgroundThreadScheduler();
- Robolectric.flushForegroundThreadScheduler();
- }
-
- private RobotTestAppHelper() {}
-}
diff --git a/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java b/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java
deleted file mode 100644
index 5a2c41e6..00000000
--- a/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.testing.shadows;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.media.MediaMetadata;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-/** Shadow {@link MediaSession}. */
-@Implements(MediaSession.class)
-public class ShadowMediaSession {
-
- public MediaSession.Callback mCallback;
- public PendingIntent mMediaButtonReceiver;
- public PendingIntent mSessionActivity;
- public PlaybackState mPlaybackState;
- public MediaMetadata mMediaMetadata;
- public int mFlags;
- public boolean mActive;
- public boolean mReleased;
-
- /** Stand-in for the MediaSession constructor with the same parameters. */
- public void __constructor__(Context context, String tag, int userID) {
- // This empty method prevents the real MediaSession constructor from being called.
- }
-
- @Implementation
- public void setCallback(MediaSession.Callback callback) {
- mCallback = callback;
- }
-
- @Implementation
- public void setMediaButtonReceiver(PendingIntent mbr) {
- mMediaButtonReceiver = mbr;
- }
-
- @Implementation
- public void setSessionActivity(PendingIntent activity) {
- mSessionActivity = activity;
- }
-
- @Implementation
- public void setPlaybackState(PlaybackState state) {
- mPlaybackState = state;
- }
-
- @Implementation
- public void setMetadata(MediaMetadata metadata) {
- mMediaMetadata = metadata;
- }
-
- @Implementation
- public void setFlags(int flags) {
- mFlags = flags;
- }
-
- @Implementation
- public boolean isActive() {
- return mActive;
- }
-
- @Implementation
- public void setActive(boolean active) {
- mActive = active;
- }
-
- @Implementation
- public void release() {
- mReleased = true;
- }
-}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
index 30fbf371..4b7c1f89 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
@@ -30,7 +30,7 @@ import com.android.tv.common.CommonConstants;
import com.android.tv.testing.utils.Utils;
import junit.framework.Assert;
-/** Helper for testing the TV application. */
+/** Helper for testing the Live TV Application. */
public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
private static final String TAG = "LiveChannelsUiDevice";
private static final int APPLICATION_START_TIMEOUT_MSEC = 5000;
@@ -56,7 +56,7 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
waitForCondition(mUiDevice, Until.hasObject(Constants.TV_VIEW));
Assert.assertTrue(
- Constants.TV_APP_PACKAGE + " did not start",
+ Constants.TV_APP_PACKAGE + " did not start",
mUiDevice.wait(
Until.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0)),
APPLICATION_START_TIMEOUT_MSEC));
diff --git a/tests/func/AndroidManifest.xml b/tests/func/AndroidManifest.xml
index e60773fc..3d7d775f 100644
--- a/tests/func/AndroidManifest.xml
+++ b/tests/func/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests.ui" >
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23" />
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
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 e24c72fa..efc7ecf4 100644
--- a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
@@ -135,7 +135,7 @@ public class PlayControlsRowViewTest {
controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
- // Press HOME twice to visit the home screen and return to TV app.
+ // Press HOME twice to visit the home screen and return to Live TV.
controller.pressHome();
// Wait until home screen is shown.
controller.waitForIdle();
diff --git a/tests/input/AndroidManifest.xml b/tests/input/AndroidManifest.xml
index 564323ad..fa52946e 100644
--- a/tests/input/AndroidManifest.xml
+++ b/tests/input/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.testinput">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<!-- Required to update or read existing channel and program information in TvProvider. -->
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputService.java b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
index d19f4558..840587c9 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputService.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
@@ -53,7 +53,7 @@ public class TestTvInputService extends TvInputService {
private static final int REFRESH_DELAY_MS = 1000 / 5;
private static final boolean DEBUG = false;
- // Consider the command delivering time from TV app.
+ // Consider the command delivering time from Live TV.
private static final long MAX_COMMAND_DELAY = TimeUnit.SECONDS.toMillis(3);
private final TestInputControl mBackend = TestInputControl.getInstance();
diff --git a/tests/jank/AndroidManifest.xml b/tests/jank/AndroidManifest.xml
index 15388514..7c0997ac 100644
--- a/tests/jank/AndroidManifest.xml
+++ b/tests/jank/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests.jank" >
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23" />
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/jank/src/com/android/tv/tests/jank/Utils.java b/tests/jank/src/com/android/tv/tests/jank/Utils.java
index 57e5f100..4ad0f643 100644
--- a/tests/jank/src/com/android/tv/tests/jank/Utils.java
+++ b/tests/jank/src/com/android/tv/tests/jank/Utils.java
@@ -19,7 +19,7 @@ import android.support.test.uiautomator.UiDevice;
import com.android.tv.testing.uihelper.UiDeviceUtils;
public final class Utils {
- /** TV app process name */
+ /** Live TV process name */
public static final String LIVE_CHANNELS_PROCESS_NAME = "com.android.tv";
private Utils() {}
diff --git a/tests/robotests/Android.mk b/tests/robotests/Android.mk
deleted file mode 100644
index d5c51b57..00000000
--- a/tests/robotests/Android.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#############################################################
-# Tv Robolectric test target. #
-#############################################################
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := TvRoboTests
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-BASE_DIR = src/com/android/tv
-EXCLUDE_FILES := \
- $(BASE_DIR)/TvActivityTest.java \
- $(BASE_DIR)/data/epg/EpgFetcherImplTest.java \
- $(BASE_DIR)/guide/ProgramItemViewTest.java \
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES := $(filter-out $(EXCLUDE_FILES),$(LOCAL_SRC_FILES))
-
-LOCAL_JAVA_LIBRARIES := \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- robolectric_android-all-stub \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- tv-lib-dagger
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- androidx.test.core \
- tv-lib-dagger-android \
- tv-test-common \
- tv-test-common-robo \
-
-LOCAL_ANNOTATION_PROCESSORS := \
- tv-lib-dagger-android-processor \
- tv-lib-dagger-compiler \
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := \
- dagger.internal.codegen.ComponentProcessor,dagger.android.processor.AndroidProcessor
-
-LOCAL_INSTRUMENTATION_FOR := LiveTv
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-#############################################################
-# Tv runner target to run the previous target. #
-#############################################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := RunTvRoboTests
-
-BASE_DIR = com/android/tv
-EXCLUDE_FILES := \
- $(BASE_DIR)/MainActivityRoboTest.java \
- $(BASE_DIR)/TvActivityTest.java \
- $(BASE_DIR)/data/epg/EpgFetcherImplTest.java \
- $(BASE_DIR)/guide/ProgramItemViewTest.java \
- $(BASE_DIR)/guide/ProgramTableAdapterTest.java \
-
-LOCAL_ROBOTEST_FILES := $(call find-files-in-subdirs,$(LOCAL_PATH)/src,*Test.java,.)
-LOCAL_ROBOTEST_FILES := $(filter-out $(EXCLUDE_FILES),$(LOCAL_ROBOTEST_FILES))
-
-LOCAL_JAVA_LIBRARIES := \
- Robolectric_all-target \
- TvRoboTests \
- mockito-robolectric-prebuilt \
- robolectric_android-all-stub \
- tv-lib-truth \
- tv-test-common \
- tv-test-common-robo \
-
-LOCAL_TEST_PACKAGE := LiveTv
-
-LOCAL_ROBOTEST_TIMEOUT := 36000
-
-include external/robolectric-shadows/run_robotests.mk
diff --git a/tests/robotests/README.md b/tests/robotests/README.md
deleted file mode 100644
index 8e4bcb5a..00000000
--- a/tests/robotests/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Unit test suite for Live Channels using Robolectric.
-
-```
-$ m -j96 RunTvRoboTests
-``` \ No newline at end of file
diff --git a/tests/robotests/src/com/android/tv/MainActivityRoboTest.java b/tests/robotests/src/com/android/tv/MainActivityRoboTest.java
deleted file mode 100644
index be7ae06b..00000000
--- a/tests/robotests/src/com/android/tv/MainActivityRoboTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvTrackInfo;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.StreamInfo;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.ui.TunableTvView;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-
-import java.util.Arrays;
-
-/** Tests for {@link TunableTvView} */
-@RunWith(RobolectricTestRunner.class)
-@Config(
- sdk = ConfigConstants.SDK,
- application = TestSingletonApp.class,
- shadows = {ShadowTvView.class})
-public class MainActivityRoboTest {
- private ShadowTvView mShadowTvView;
- private FakeMainActivity mMainActivity;
-
- @Before
- public void setUp() {
- mMainActivity = Robolectric.buildActivity(FakeMainActivity.class).create().get();
- mShadowTvView = Shadow.extract(mMainActivity.getTvView().getTvView());
- mShadowTvView.listener = mMainActivity.getListener();
- }
-
- @Test
- public void testSelectAudioTrack_autoSelect() {
- mShadowTvView.mAudioTrackCountChanged = false;
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR"));
- mMainActivity.selectAudioTrack("FR audio 1");
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1");
-
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR"));
- mMainActivity.applyMultiAudio(null);
- // FR audio 2 is selected according the previously selected track.
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 2");
- }
-
- @Test
- public void testSelectAudioTrack_audioTrackCountChanged() {
- mShadowTvView.mAudioTrackCountChanged = true;
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR"));
- mMainActivity.selectAudioTrack("FR audio 1");
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1");
-
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR"));
- mMainActivity.selectAudioTrack("FR audio 3");
- // FR audio 3 is selected even if the track info has been changed
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 3");
- }
-
- @Test
- public void testSelectAudioTrack_audioTrackCountNotChanged() {
- mShadowTvView.mAudioTrackCountChanged = false;
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR"));
- mMainActivity.selectAudioTrack("FR audio 1");
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1");
-
- setTracks(
- TvTrackInfo.TYPE_AUDIO,
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"),
- buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR"));
- mMainActivity.selectAudioTrack("FR audio 3");
- assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 3");
- }
-
- private void setTracks(int type, TvTrackInfo... tracks) {
- mShadowTvView.mTracks.put(type, Arrays.asList(tracks));
- mShadowTvView.mSelectedTracks.put(type, null);
- }
-
- private TvTrackInfo buildTrackForTesting(int type, String id, String language) {
- return new TvTrackInfo.Builder(type, id)
- .setLanguage(language)
- .setAudioChannelCount(0)
- .build();
- }
-
- /** A {@link MainActivity} class for tests */
- public static class FakeMainActivity extends MainActivity {
- private MyOnTuneListener mListener;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // Override onCreate() to omit unnecessary member variables
- mTvView =
- (TunableTvView)
- LayoutInflater.from(RuntimeEnvironment.application)
- .inflate(R.layout.activity_tv, null)
- .findViewById(R.id.main_tunable_tv_view);
- DefaultLegacyFlags legacyFlags = DefaultLegacyFlags.DEFAULT;
- mTvView.initialize(
- new ProgramDataManager(RuntimeEnvironment.application),
- new TvInputManagerHelper(RuntimeEnvironment.application, legacyFlags),
- legacyFlags);
- mTvView.start();
- mListener =
- new MyOnTuneListener() {
- @Override
- public void onStreamInfoChanged(
- StreamInfo info, boolean allowAutoSelectionOfTrack) {
- applyMultiAudio(
- allowAutoSelectionOfTrack
- ? null
- : getSelectedTrack(TvTrackInfo.TYPE_AUDIO));
- }
- };
- mTvView.setOnTuneListener(mListener);
- }
-
- public TunableTvView getTvView() {
- return mTvView;
- }
-
- public MyOnTuneListener getListener() {
- return mListener;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/MediaSessionWrapperTest.java b/tests/robotests/src/com/android/tv/MediaSessionWrapperTest.java
deleted file mode 100644
index 5be62acb..00000000
--- a/tests/robotests/src/com/android/tv/MediaSessionWrapperTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.media.MediaMetadata;
-import android.media.session.PlaybackState;
-
-import com.android.tv.testing.EpgTestData;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.shadows.ShadowMediaSession;
-
-import com.google.common.collect.Maps;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-
-import java.util.Map;
-
-/** Tests fpr {@link MediaSessionWrapper}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(
- sdk = ConfigConstants.SDK,
- application = TestSingletonApp.class,
- shadows = {ShadowMediaSession.class})
-public class MediaSessionWrapperTest {
-
- private static final int TEST_REQUEST_CODE = 1337;
-
- private ShadowMediaSession mediaSession;
- private MediaSessionWrapper mediaSessionWrapper;
- private PendingIntent pendingIntent;
-
- @Before
- public void setUp() {
- pendingIntent =
- PendingIntent.getActivity(
- RuntimeEnvironment.application, TEST_REQUEST_CODE, new Intent(), 0);
- mediaSessionWrapper =
- new MediaSessionWrapper(RuntimeEnvironment.application, pendingIntent) {
- @Override
- void initMediaController() {
- // Not use MediaController for tests here because:
- // 1. it's not allow to shadow MediaController
- // 2. The Context TestSingletonApp is not an instance of Activity so
- // Activity.setMediaController cannot be called.
- // onPlaybackStateChanged() is called in #setPlaybackState instead.
- }
-
- @Override
- void unregisterMediaControllerCallback() {}
- };
- mediaSession = Shadow.extract(mediaSessionWrapper.getMediaSession());
- }
-
- @Test
- public void setSessionActivity() {
- assertThat(mediaSession.mSessionActivity).isEqualTo(this.pendingIntent);
- }
-
- @Test
- public void setPlaybackState_true() {
- setPlaybackState(true);
- assertThat(mediaSession.mActive).isTrue();
- assertThat(mediaSession.mPlaybackState.getState()).isEqualTo(PlaybackState.STATE_PLAYING);
- }
-
- @Test
- public void setPlaybackState_false() {
- setPlaybackState(false);
- assertThat(mediaSession.mActive).isFalse();
- assertThat(mediaSession.mPlaybackState).isNull();
- }
-
- @Test
- public void setPlaybackState_trueThenFalse() {
- setPlaybackState(true);
- setPlaybackState(false);
- assertThat(mediaSession.mActive).isFalse();
- assertThat(mediaSession.mPlaybackState.getState()).isEqualTo(PlaybackState.STATE_STOPPED);
- }
-
- @Test
- public void update_channel10() {
-
- mediaSessionWrapper.update(false, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), null);
- assertThat(asMap(mediaSession.mMediaMetadata))
- .containsExactly(MediaMetadata.METADATA_KEY_TITLE, "Channel TEN");
- }
-
- @Test
- public void update_blockedChannel10() {
- mediaSessionWrapper.update(true, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), null);
- assertThat(asMap(mediaSession.mMediaMetadata))
- .containsExactly(
- MediaMetadata.METADATA_KEY_TITLE,
- "Channel blocked",
- MediaMetadata.METADATA_KEY_ART,
- null);
- }
-
- @Test
- public void update_channel10Program2() {
- mediaSessionWrapper.update(
- false, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), EpgTestData.PROGRAM_2);
- assertThat(asMap(mediaSession.mMediaMetadata))
- .containsExactly(MediaMetadata.METADATA_KEY_TITLE, "Program 2");
- }
-
- @Test
- public void update_blockedChannel10Program2() {
- mediaSessionWrapper.update(
- true, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), EpgTestData.PROGRAM_2);
- assertThat(asMap(mediaSession.mMediaMetadata))
- .containsExactly(
- MediaMetadata.METADATA_KEY_TITLE,
- "Channel blocked",
- MediaMetadata.METADATA_KEY_ART,
- null);
- // TODO(b/70559407): test async loading of images.
- }
-
- @Test
- public void release() {
- mediaSessionWrapper.release();
- assertThat(mediaSession.mReleased).isTrue();
- }
-
- private Map<String, Object> asMap(MediaMetadata mediaMetadata) {
- return Maps.asMap(mediaMetadata.keySet(), key -> mediaMetadata.getString(key));
- }
-
- private void setPlaybackState(boolean isPlaying) {
- mediaSessionWrapper.setPlaybackState(isPlaying);
- mediaSessionWrapper
- .getMediaControllerCallback()
- .onPlaybackStateChanged(
- isPlaying
- ? MediaSessionWrapper.MEDIA_SESSION_STATE_PLAYING
- : MediaSessionWrapper.MEDIA_SESSION_STATE_STOPPED);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/SetupPassthroughActivityTest.java b/tests/robotests/src/com/android/tv/SetupPassthroughActivityTest.java
deleted file mode 100644
index 76037b49..00000000
--- a/tests/robotests/src/com/android/tv/SetupPassthroughActivityTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.robolectric.Shadows.shadowOf;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ServiceInfo;
-import android.media.tv.TvInputInfo;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.support.annotation.Nullable;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.tv.common.CommonConstants;
-import com.android.tv.common.dagger.ApplicationModule;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.common.flags.impl.SettableFlagsModule;
-import com.android.tv.common.util.CommonUtils;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.features.TvFeatures;
-import com.android.tv.modules.TvSingletonsModule;
-import com.android.tv.testing.FakeTvInputManager;
-import com.android.tv.testing.FakeTvInputManagerHelper;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
-import com.android.tv.util.SetupUtils;
-import com.android.tv.util.TvInputManagerHelper;
-
-import com.google.android.tv.partner.support.EpgContract;
-import com.google.common.base.Optional;
-import com.android.tv.common.flags.proto.TypedFeatures.StringListParam;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mockito;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.android.util.concurrent.RoboExecutorService;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowActivity;
-
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/** Tests for {@link SetupPassthroughActivity}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = SetupPassthroughActivityTest.MyTestApp.class)
-public class SetupPassthroughActivityTest {
-
- private static final int REQUEST_START_SETUP_ACTIVITY = 200;
-
- private MyTestApp testSingletonApp;
-
- private TvInputInfo testInput;
-
- @Before
- public void setup() {
- testInput = createMockInput("com.example/.Input");
- testSingletonApp = (MyTestApp) ApplicationProvider.getApplicationContext();
- testSingletonApp.flagsModule.legacyFlags =
- DefaultLegacyFlags.builder().enableQaFeatures(true).build();
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager();
- }
-
- @After
- public void after() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.resetForTests();
- }
-
- @Test
- public void create_emptyIntent() {
- SetupPassthroughActivity activity =
- Robolectric.buildActivity(SetupPassthroughActivity.class, new Intent())
- .create()
- .get();
- ShadowActivity.IntentForResult shadowIntent =
- shadowOf(activity).getNextStartedActivityForResult();
- // Since there is no inputs, the next activity should not be started.
- assertThat(shadowIntent).isNull();
- assertThat(activity.isFinishing()).isTrue();
- }
-
- @Test
- public void create_noInputs() {
- SetupPassthroughActivity activity = createSetupActivityFor("com.example/.Input");
- ShadowActivity.IntentForResult shadowIntent =
- shadowOf(activity).getNextStartedActivityForResult();
- // Since there is no inputs, the next activity should not be started.
- assertThat(shadowIntent).isNull();
- assertThat(activity.isFinishing()).isTrue();
- }
-
- @Test
- public void create_inputNotFound() {
- testSingletonApp.tvInputManagerHelper = new FakeTvInputManagerHelper(testSingletonApp);
- testSingletonApp.tvInputManagerHelper.start();
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- SetupPassthroughActivity activity = createSetupActivityFor("com.example/.Other");
- ShadowActivity.IntentForResult shadowIntent =
- shadowOf(activity).getNextStartedActivityForResult();
- // Since the input is not found, the next activity should not be started.
- assertThat(shadowIntent).isNull();
- assertThat(activity.isFinishing()).isTrue();
- }
-
- @Test
- public void create_validInput() {
- testSingletonApp.tvInputManagerHelper.start();
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
-
- ShadowActivity.IntentForResult shadowIntent =
- shadowOf(activity).getNextStartedActivityForResult();
- assertThat(shadowIntent).isNotNull();
- assertThat(shadowIntent.options).isNull();
- assertThat(shadowIntent.intent.getExtras()).isNotNull();
- assertThat(shadowIntent.requestCode).isEqualTo(REQUEST_START_SETUP_ACTIVITY);
- assertThat(activity.isFinishing()).isFalse();
- }
-
- @Test
- public void create_trustedCallingPackage() {
- testSingletonApp.tvInputManagerHelper.start();
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
-
- ActivityController<SetupPassthroughActivity> activityController =
- Robolectric.buildActivity(
- SetupPassthroughActivity.class,
- CommonUtils.createSetupIntent(new Intent(), testInput.getId()));
- SetupPassthroughActivity activity = activityController.get();
- ShadowActivity shadowActivity = shadowOf(activity);
- shadowActivity.setCallingActivity(
- new ComponentName(CommonConstants.BASE_PACKAGE, "com.example.MyClass"));
- activityController.create();
-
- ShadowActivity.IntentForResult shadowIntent =
- shadowActivity.getNextStartedActivityForResult();
- assertThat(shadowIntent).isNotNull();
- assertThat(shadowIntent.options).isNull();
- assertThat(shadowIntent.intent.getExtras()).isNotNull();
- assertThat(shadowIntent.requestCode).isEqualTo(REQUEST_START_SETUP_ACTIVITY);
- assertThat(activity.isFinishing()).isFalse();
- }
-
- @Test
- public void create_nonTrustedCallingPackage() {
- testSingletonApp.tvInputManagerHelper.start();
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
-
- ActivityController<SetupPassthroughActivity> activityController =
- Robolectric.buildActivity(
- SetupPassthroughActivity.class,
- CommonUtils.createSetupIntent(new Intent(), testInput.getId()));
- SetupPassthroughActivity activity = activityController.get();
- ShadowActivity shadowActivity = shadowOf(activity);
- shadowActivity.setCallingActivity(
- new ComponentName("com.notTrusted", "com.notTrusted.MyClass"));
- activityController.create();
-
- ShadowActivity.IntentForResult shadowIntent =
- shadowActivity.getNextStartedActivityForResult();
- // Since the calling activity is not trusted, the next activity should not be started.
- assertThat(shadowIntent).isNull();
- assertThat(activity.isFinishing()).isTrue();
- }
-
- @Test
- public void onActivityResult_canceled() {
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
-
- activity.onActivityResult(0, Activity.RESULT_CANCELED, null);
- assertThat(activity.isFinishing()).isTrue();
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
- }
-
- @Test
- public void onActivityResult_ok() {
- TestSetupUtils setupUtils = new TestSetupUtils(RuntimeEnvironment.application);
- testSingletonApp.setupUtils = setupUtils;
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
- activity.onActivityResult(REQUEST_START_SETUP_ACTIVITY, Activity.RESULT_OK, null);
-
- assertThat(testSingletonApp.epgFetcher.fetchStarted).isFalse();
- assertThat(setupUtils.finishedId).isEqualTo("com.example/.Input");
- assertThat(activity.isFinishing()).isFalse();
-
- setupUtils.finishedRunnable.run();
- assertThat(activity.isFinishing()).isTrue();
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_OK);
- }
-
- @Test
- public void onActivityResult_3rdPartyEpg_ok() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.enableForTest();
- TestSetupUtils setupUtils = new TestSetupUtils(RuntimeEnvironment.application);
- testSingletonApp.setupUtils = setupUtils;
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- testSingletonApp.getCloudEpgFlags().setThirdPartyEpgInputCsv(testInput.getId());
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
- Intent data = new Intent();
- data.putExtra(EpgContract.EXTRA_USE_CLOUD_EPG, true);
- data.putExtra(TvInputInfo.EXTRA_INPUT_ID, testInput.getId());
- activity.onActivityResult(REQUEST_START_SETUP_ACTIVITY, Activity.RESULT_OK, data);
-
- assertThat(testSingletonApp.epgFetcher.fetchStarted).isTrue();
- assertThat(setupUtils.finishedId).isEqualTo("com.example/.Input");
- assertThat(activity.isFinishing()).isFalse();
-
- setupUtils.finishedRunnable.run();
- assertThat(activity.isFinishing()).isTrue();
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_OK);
- }
-
- @Test
- public void onActivityResult_3rdPartyEpg_notWhiteListed() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.enableForTest();
- TestSetupUtils setupUtils = new TestSetupUtils(RuntimeEnvironment.application);
- testSingletonApp.setupUtils = setupUtils;
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
- Intent data = new Intent();
- data.putExtra(EpgContract.EXTRA_USE_CLOUD_EPG, true);
- data.putExtra(TvInputInfo.EXTRA_INPUT_ID, testInput.getId());
- activity.onActivityResult(REQUEST_START_SETUP_ACTIVITY, Activity.RESULT_OK, data);
-
- assertThat(testSingletonApp.epgFetcher.fetchStarted).isFalse();
- assertThat(setupUtils.finishedId).isEqualTo("com.example/.Input");
- assertThat(activity.isFinishing()).isFalse();
-
- setupUtils.finishedRunnable.run();
- assertThat(activity.isFinishing()).isTrue();
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_OK);
- }
-
- @Test
- public void onActivityResult_3rdPartyEpg_disabled() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.disableForTests();
- TestSetupUtils setupUtils = new TestSetupUtils(RuntimeEnvironment.application);
- testSingletonApp.setupUtils = setupUtils;
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager().add(testInput, -1);
- testSingletonApp.getCloudEpgFlags().setThirdPartyEpgInputCsv(testInput.getId());
- testSingletonApp.dbExecutor = new RoboExecutorService();
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
- Intent data = new Intent();
- data.putExtra(EpgContract.EXTRA_USE_CLOUD_EPG, true);
- data.putExtra(TvInputInfo.EXTRA_INPUT_ID, testInput.getId());
- activity.onActivityResult(REQUEST_START_SETUP_ACTIVITY, Activity.RESULT_OK, data);
-
- assertThat(testSingletonApp.epgFetcher.fetchStarted).isFalse();
- assertThat(setupUtils.finishedId).isEqualTo("com.example/.Input");
- assertThat(activity.isFinishing()).isFalse();
-
- setupUtils.finishedRunnable.run();
- assertThat(activity.isFinishing()).isTrue();
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_OK);
- }
-
- @Test
- public void onActivityResult_ok_tvInputInfo_null() {
- TestSetupUtils setupUtils = new TestSetupUtils(RuntimeEnvironment.application);
- testSingletonApp.setupUtils = setupUtils;
- FakeTvInputManager tvInputManager =
- testSingletonApp.tvInputManagerHelper.getFakeTvInputManager();
- SetupPassthroughActivity activity = createSetupActivityFor(testInput.getId());
- activity.onActivityResult(REQUEST_START_SETUP_ACTIVITY, Activity.RESULT_OK, null);
-
- assertThat(tvInputManager.getTvInputInfo(testInput.getId())).isEqualTo(null);
- assertThat(testSingletonApp.epgFetcher.fetchStarted).isFalse();
- assertThat(activity.isFinishing()).isTrue();
-
- assertThat(shadowOf(activity).getResultCode()).isEqualTo(Activity.RESULT_OK);
- }
-
- private SetupPassthroughActivity createSetupActivityFor(String inputId) {
- return Robolectric.buildActivity(
- SetupPassthroughActivity.class,
- CommonUtils.createSetupIntent(new Intent(), inputId))
- .create()
- .get();
- }
-
- private TvInputInfo createMockInput(String inputId) {
- TvInputInfo tvInputInfo = Mockito.mock(TvInputInfo.class);
- ServiceInfo serviceInfo = new ServiceInfo();
- ApplicationInfo applicationInfo = new ApplicationInfo();
- Mockito.when(tvInputInfo.getId()).thenReturn(inputId);
- serviceInfo.packageName = inputId.substring(0, inputId.indexOf('/'));
- serviceInfo.applicationInfo = applicationInfo;
- applicationInfo.flags = 0;
- Mockito.when(tvInputInfo.getServiceInfo()).thenReturn(serviceInfo);
- Mockito.when(tvInputInfo.loadLabel(ArgumentMatchers.any())).thenReturn("testLabel");
- if (VERSION.SDK_INT >= VERSION_CODES.N) {
- Mockito.when(tvInputInfo.loadCustomLabel(ArgumentMatchers.any()))
- .thenReturn("testCustomLabel");
- }
- return tvInputInfo;
- }
-
- /**
- * Test SetupUtils.
- *
- * <p>SetupUtils has lots of DB and threading interactions, that make it hard to test. This
- * bypasses all of that.
- */
- private static class TestSetupUtils extends SetupUtils {
- public String finishedId;
- public Runnable finishedRunnable;
-
- private TestSetupUtils(Context context) {
- super(context, Optional.absent());
- }
-
- @Override
- public void onTvInputSetupFinished(String inputId, @Nullable Runnable postRunnable) {
- finishedId = inputId;
- finishedRunnable = postRunnable;
- }
- }
-
- /** Test app for {@link SetupPassthroughActivityTest} */
- public static class MyTestApp extends TestSingletonApp implements HasAndroidInjector {
-
- @Inject DispatchingAndroidInjector<Object> dispatchingAndroidInjector;
-
- @Override
- public void onCreate() {
-
- super.onCreate();
- // Inject afterwards so we can use objects created in super.
- // Note TestSingletonApp does not do injection so it is safe
- applicationInjector().inject(this);
- }
-
- @Override
- public AndroidInjector<Object> androidInjector() {
- return dispatchingAndroidInjector;
- }
-
- protected AndroidInjector<MyTestApp> applicationInjector() {
-
- return DaggerSetupPassthroughActivityTest_TestComponent.builder()
- .applicationModule(new ApplicationModule(this))
- .tvSingletonsModule(new TvSingletonsModule(this))
- .testModule(new TestModule(this))
- .settableFlagsModule(flagsModule)
- .build();
- }
- }
-
- /** Dagger component for {@link SetupPassthroughActivityTest}. */
- @Singleton
- @Component(
- modules = {
- AndroidInjectionModule.class,
- TestModule.class,
- })
- interface TestComponent extends AndroidInjector<MyTestApp> {}
-
- @Module(
- includes = {
- SetupPassthroughActivity.Module.class,
- ApplicationModule.class,
- TvSingletonsModule.class,
- SettableFlagsModule.class,
- })
- /** Module for {@link MyTestApp} */
- static class TestModule {
- private final MyTestApp myTestApp;
-
- TestModule(MyTestApp test) {
- myTestApp = test;
- }
-
- @Provides
- Optional<BuiltInTunerManager> providesBuiltInTunerManager() {
- return Optional.absent();
- }
-
- @Provides
- TvInputManagerHelper providesTvInputManagerHelper() {
- return myTestApp.tvInputManagerHelper;
- }
-
- @Provides
- SetupUtils providesTestSetupUtils() {
- return myTestApp.setupUtils;
- }
-
- @Provides
- @DbExecutor
- Executor providesDbExecutor() {
- return myTestApp.dbExecutor;
- }
-
- @Provides
- ChannelDataManager providesChannelDataManager() {
- return myTestApp.getChannelDataManager();
- }
-
- @Provides
- EpgFetcher providesEpgFetcher() {
- return myTestApp.epgFetcher;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/ShadowTvView.java b/tests/robotests/src/com/android/tv/ShadowTvView.java
deleted file mode 100644
index 8aad9f00..00000000
--- a/tests/robotests/src/com/android/tv/ShadowTvView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv;
-
-import android.content.Context;
-import android.media.tv.TvTrackInfo;
-import android.media.tv.TvView;
-import android.util.AttributeSet;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowView;
-
-// TODO(b/78304522): move this class to robolectric
-/** Shadow class of {@link TvView}. */
-@Implements(TvView.class)
-public class ShadowTvView extends ShadowView {
- public Map<Integer, String> mSelectedTracks = new HashMap<>();
- public Map<Integer, List<TvTrackInfo>> mTracks = new HashMap<>();
- public MainActivity.MyOnTuneListener listener;
- public TvView.TvInputCallback mCallback;
- public boolean mAudioTrackCountChanged;
-
- @Implementation
- public void __constructor__(Context context) {
- }
-
- @Implementation
- public void __constructor__(Context context, AttributeSet attrs) {
- }
-
- @Override
- public void __constructor__(Context context, AttributeSet attrs, int defStyleAttr) {
- }
-
- @Implementation
- public List<TvTrackInfo> getTracks(int type) {
- return mTracks.get(type);
- }
-
- @Implementation
- public void selectTrack(int type, String trackId) {
- mSelectedTracks.put(type, trackId);
- int infoIndex = findTrackIndex(type, trackId);
- // for some drivers, audio track count is set to 0 until the corresponding track is
- // selected. Here we replace the track with another one whose audio track count is non-zero
- // to test this case.
- if (mAudioTrackCountChanged) {
- replaceTrack(type, infoIndex);
- }
- mCallback.onTrackSelected("fakeInputId", type, trackId);
- }
-
- @Implementation
- public String getSelectedTrack(int type) {
- return mSelectedTracks.get(type);
- }
-
- @Implementation
- public void setCallback(TvView.TvInputCallback callback) {
- mCallback = callback;
- }
-
- private int findTrackIndex(int type, String trackId) {
- List<TvTrackInfo> tracks = mTracks.get(type);
- if (tracks == null) {
- return -1;
- }
- for (int i = 0; i < tracks.size(); i++) {
- TvTrackInfo info = tracks.get(i);
- if (info.getId().equals(trackId)) {
- return i;
- }
- }
- return -1;
- }
-
- private void replaceTrack(int type, int trackIndex) {
- if (trackIndex >= 0) {
- TvTrackInfo info = mTracks.get(type).get(trackIndex);
- info = new TvTrackInfo
- .Builder(info.getType(), info.getId())
- .setLanguage(info.getLanguage())
- .setAudioChannelCount(info.getAudioChannelCount() + 2)
- .build();
- mTracks.get(type).set(trackIndex, info);
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/TvActivityTest.java b/tests/robotests/src/com/android/tv/TvActivityTest.java
deleted file mode 100644
index c153de8a..00000000
--- a/tests/robotests/src/com/android/tv/TvActivityTest.java
+++ /dev/null
@@ -1,48 +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;
-
-import android.content.Intent;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.util.Utils;
-
-import com.google.android.libraries.testing.truth.IntentSubject;
-import com.google.common.truth.Truth;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowApplication;
-
-/** Test for {@link TvActivity}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvActivityTest {
-
- @Test
- public void testLifeCycle() {
- TvActivity activity = Robolectric.setupActivity(TvActivity.class);
- Truth.assertThat(activity.isFinishing()).isTrue();
-
- Intent nextStartedActivity = ShadowApplication.getInstance().getNextStartedActivity();
- IntentSubject.assertThat(nextStartedActivity).hasComponentClass(MainActivity.class);
- IntentSubject.assertThat(nextStartedActivity).hasExtra(Utils.EXTRA_KEY_FROM_LAUNCHER, true);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/audio/AudioManagerHelperTest.java b/tests/robotests/src/com/android/tv/audio/AudioManagerHelperTest.java
deleted file mode 100644
index e71b5620..00000000
--- a/tests/robotests/src/com/android/tv/audio/AudioManagerHelperTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.audio;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Activity;
-import android.media.AudioManager;
-import android.os.Build;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.ui.api.TunableTvViewPlayingApi;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link AudioManagerHelper}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class AudioManagerHelperTest {
-
- private AudioManagerHelper mAudioManagerHelper;
- private TestTvView mTvView;
- private AudioManager mAudioManager;
-
- @Before
- public void setup() {
- Activity testActivity = Robolectric.buildActivity(Activity.class).get();
- mTvView = new TestTvView();
- mAudioManager = RuntimeEnvironment.application.getSystemService(AudioManager.class);
-
- mAudioManagerHelper = new AudioManagerHelper(testActivity, mTvView);
- }
-
- @Test
- public void onAudioFocusChange_none_noTimeShift() {
- mTvView.mTimeShiftAvailable = false;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_NONE);
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isZero();
- }
-
- @Test
- public void onAudioFocusChange_none_TimeShift() {
- mTvView.mTimeShiftAvailable = true;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_NONE);
-
- assertThat(mTvView.mPaused).isTrue();
- assertThat(mTvView.mVolume).isNull();
- }
-
- @Test
- public void onAudioFocusChange_gain_noTimeShift() {
- mTvView.mTimeShiftAvailable = false;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN);
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isEqualTo(1.0f);
- }
-
- @Test
- public void onAudioFocusChange_gain_timeShift() {
- mTvView.mTimeShiftAvailable = true;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN);
-
- assertThat(mTvView.mPaused).isFalse();
- assertThat(mTvView.mVolume).isNull();
- }
-
- @Test
- public void onAudioFocusChange_loss_noTimeShift() {
- mTvView.mTimeShiftAvailable = false;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS);
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isEqualTo(0.0f);
- }
-
- @Test
- public void onAudioFocusChange_loss_timeShift() {
- mTvView.mTimeShiftAvailable = true;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS);
-
- assertThat(mTvView.mPaused).isTrue();
- assertThat(mTvView.mVolume).isNull();
- }
-
- @Test
- public void onAudioFocusChange_lossTransient_noTimeShift() {
- mTvView.mTimeShiftAvailable = false;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isEqualTo(0.0f);
- }
-
- @Test
- public void onAudioFocusChange_lossTransient_timeShift() {
- mTvView.mTimeShiftAvailable = true;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
-
- assertThat(mTvView.mPaused).isTrue();
- assertThat(mTvView.mVolume).isNull();
- }
-
- @Test
- public void onAudioFocusChange_lossTransientCanDuck_noTimeShift() {
- mTvView.mTimeShiftAvailable = false;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isEqualTo(0.3f);
- }
-
- @Test
- public void onAudioFocusChange_lossTransientCanDuck_timeShift() {
- mTvView.mTimeShiftAvailable = true;
-
- mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
-
- assertThat(mTvView.mPaused).isTrue();
- assertThat(mTvView.mVolume).isNull();
- }
-
- @Test
- @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O})
- public void requestAudioFocus_granted() {
- Shadows.shadowOf(mAudioManager)
- .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
- mAudioManagerHelper.requestAudioFocus();
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isEqualTo(1.0f);
- }
-
- @Test
- @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O})
- public void requestAudioFocus_failed() {
- Shadows.shadowOf(mAudioManager)
- .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_FAILED);
-
- mAudioManagerHelper.requestAudioFocus();
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isZero();
- }
-
- @Test
- @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O})
- public void requestAudioFocus_delayed() {
- Shadows.shadowOf(mAudioManager)
- .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_DELAYED);
-
- mAudioManagerHelper.requestAudioFocus();
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isZero();
- }
-
- @Test
- public void setVolumeByAudioFocusStatus_started() {
- mAudioManagerHelper.setVolumeByAudioFocusStatus();
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isZero();
- }
-
- @Test
- public void setVolumeByAudioFocusStatus_notStarted() {
- mTvView.mStarted = false;
- mAudioManagerHelper.setVolumeByAudioFocusStatus();
-
- assertThat(mTvView.mPaused).isNull();
- assertThat(mTvView.mVolume).isNull();
- }
-
- private static class TestTvView implements TunableTvViewPlayingApi {
- private boolean mStarted = true;
- private boolean mTimeShiftAvailable = false;
- private Float mVolume = null;
- private Boolean mPaused = null;
-
- @Override
- public boolean isPlaying() {
- return mStarted;
- }
-
- @Override
- public void setStreamVolume(float volume) {
- mVolume = volume;
- }
-
- @Override
- public void setTimeShiftListener(TimeShiftListener listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isTimeShiftAvailable() {
- return mTimeShiftAvailable;
- }
-
- @Override
- public void timeShiftPlay() {
- mPaused = false;
- }
-
- @Override
- public void timeShiftPause() {
- mPaused = true;
- }
-
- @Override
- public void timeShiftRewind(int speed) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void timeShiftFastForward(int speed) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void timeShiftSeekTo(long timeMs) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long timeShiftGetCurrentPositionMs() {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/ChannelNumberTest.java b/tests/robotests/src/com/android/tv/data/ChannelNumberTest.java
deleted file mode 100644
index de051cf5..00000000
--- a/tests/robotests/src/com/android/tv/data/ChannelNumberTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.tv.data;
-
-import static com.android.tv.data.ChannelNumber.parseChannelNumber;
-import static com.android.tv.testing.ChannelNumberSubject.assertThat;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.testing.ComparableTester;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link ChannelNumber}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class ChannelNumberTest {
-
- @Test
- public void newChannelNumber() {
- assertThat(new ChannelNumber()).isEmpty();
- }
-
- @Test
- public void parseChannelNumber_empty() {
- assertThat(parseChannelNumber("")).isNull();
- }
-
- @Test
- public void parseChannelNumber_dash() {
- assertThat(parseChannelNumber("-")).isNull();
- }
-
- @Test
- public void parseChannelNumber_abcd12() {
- assertThat(parseChannelNumber("abcd12")).isNull();
- }
-
- @Test
- public void parseChannelNumber_12abcd() {
- assertThat(parseChannelNumber("12abcd")).isNull();
- }
-
- @Test
- public void parseChannelNumber_dash12() {
- assertThat(parseChannelNumber("-12")).isNull();
- }
-
- @Test
- public void parseChannelNumber_1() {
- assertThat(parseChannelNumber("1")).displaysAs(1);
- }
-
- @Test
- public void parseChannelNumber_1234dash4321() {
- assertThat(parseChannelNumber("1234-4321")).displaysAs(1234, 4321);
- }
-
- @Test
- public void parseChannelNumber_3dash4() {
- assertThat(parseChannelNumber("3-4")).displaysAs(3, 4);
- }
-
- @Test
- public void parseChannelNumber_5dash6() {
- assertThat(parseChannelNumber("5-6")).displaysAs(5, 6);
- }
-
- @Test
- public void compareTo() {
- new ComparableTester<ChannelNumber>()
- .addEquivalentGroup(parseChannelNumber("1"), parseChannelNumber("1"))
- .addEquivalentGroup(parseChannelNumber("2"))
- .addEquivalentGroup(parseChannelNumber("2-1"))
- .addEquivalentGroup(parseChannelNumber("2-2"))
- .addEquivalentGroup(parseChannelNumber("2-10"))
- .addEquivalentGroup(parseChannelNumber("3"))
- .addEquivalentGroup(parseChannelNumber("4"), parseChannelNumber("4-0"))
- .addEquivalentGroup(parseChannelNumber("10"))
- .addEquivalentGroup(parseChannelNumber("100"))
- .test();
- }
-
- @Test
- public void compare_null_null() {
- assertThat(ChannelNumber.compare(null, null)).isEqualTo(0);
- }
-
- @Test
- public void compare_1_1() {
- assertThat(ChannelNumber.compare("1", "1")).isEqualTo(0);
- ;
- }
-
- @Test
- public void compare_null_1() {
- assertThat(ChannelNumber.compare(null, "1")).isLessThan(0);
- }
-
- @Test
- public void compare_abcd_1() {
- assertThat(ChannelNumber.compare("abcd", "1")).isLessThan(0);
- }
-
- @Test
- public void compare_dash1_1() {
- assertThat(ChannelNumber.compare(".4", "1")).isLessThan(0);
- }
-
- @Test
- public void compare_1_null() {
- assertThat(ChannelNumber.compare("1", null)).isGreaterThan(0);
- }
-
- @Test
- public void equivalent_null_to_null() {
- assertThat(ChannelNumber.equivalent(null, null)).isTrue();
- }
-
- @Test
- public void equivalent_1_to_1() {
- assertThat(ChannelNumber.equivalent("1", "1")).isTrue();
- }
-
- @Test
- public void equivalent_1d2_to_1() {
- assertThat(ChannelNumber.equivalent("1-2", "1")).isTrue();
- }
-
- @Test
- public void equivalent_1_to_1d2() {
- assertThat(ChannelNumber.equivalent("1", "1-2")).isTrue();
- }
-
- @Test
- public void equivalent_1_to_2_isFalse() {
- assertThat(ChannelNumber.equivalent("1", "2")).isFalse();
- }
-
- @Test
- public void equivalent_1d1_to_1d1() {
- assertThat(ChannelNumber.equivalent("1-1", "1-1")).isTrue();
- }
-
- @Test
- public void equivalent_1d1_to_1d2_isFalse() {
- assertThat(ChannelNumber.equivalent("1-1", "1-2")).isFalse();
- }
-
- @Test
- public void equivalent_1_to_null_isFalse() {
- assertThat(ChannelNumber.equivalent("1", null)).isFalse();
- }
-
- @Test
- public void equivalent_null_to_1_isFalse() {
- assertThat(ChannelNumber.equivalent(null, "1")).isFalse();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/GenreItemTest.java b/tests/robotests/src/com/android/tv/data/GenreItemTest.java
deleted file mode 100644
index b19dc0d1..00000000
--- a/tests/robotests/src/com/android/tv/data/GenreItemTest.java
+++ /dev/null
@@ -1,95 +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.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvContract.Programs.Genres;
-import android.os.Build;
-
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link GenreItems}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class GenreItemTest {
- private static final String INVALID_GENRE = "INVALID GENRE";
-
- @Test
- public void testGetLabels() {
- // Checks if no exception is thrown.
- GenreItems.getLabels(RuntimeEnvironment.application);
- }
-
- @Test
- public void testGetCanonicalGenre() {
- int count = GenreItems.getGenreCount();
- assertThat(GenreItems.getCanonicalGenre(GenreItems.ID_ALL_CHANNELS)).isNull();
- for (int i = 1; i < count; ++i) {
- assertThat(GenreItems.getCanonicalGenre(i)).isNotNull();
- }
- }
-
- @Test
- public void testGetId_base() {
- int count = GenreItems.getGenreCount();
- assertThat(GenreItems.getId(null)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(INVALID_GENRE)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertInRange(GenreItems.getId(Genres.FAMILY_KIDS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.SPORTS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.SHOPPING), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.MOVIES), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.COMEDY), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.TRAVEL), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.DRAMA), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.EDUCATION), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.ANIMAL_WILDLIFE), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.NEWS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.GAMING), 1, count - 1);
- }
-
- @Test
- public void testGetId_lmp_mr1() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
- assertThat(GenreItems.getId(Genres.ARTS)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(Genres.ENTERTAINMENT))
- .isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(Genres.LIFE_STYLE)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(Genres.MUSIC)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(Genres.PREMIER)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- assertThat(GenreItems.getId(Genres.TECH_SCIENCE)).isEqualTo(GenreItems.ID_ALL_CHANNELS);
- } else {
- int count = GenreItems.getGenreCount();
- assertInRange(GenreItems.getId(Genres.ARTS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.ENTERTAINMENT), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.LIFE_STYLE), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.MUSIC), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.PREMIER), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.TECH_SCIENCE), 1, count - 1);
- }
- }
-
- private void assertInRange(int value, int lower, int upper) {
- assertThat(value >= lower && value <= upper).isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/PreviewDataManagerTest.java b/tests/robotests/src/com/android/tv/data/PreviewDataManagerTest.java
deleted file mode 100644
index b341abf4..00000000
--- a/tests/robotests/src/com/android/tv/data/PreviewDataManagerTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.pm.ProviderInfo;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.tvprovider.media.tv.PreviewProgram;
-import androidx.tvprovider.media.tv.TvContractCompat;
-
-import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowContentResolver;
-import org.robolectric.shadows.ShadowLog;
-
-import java.util.List;
-
-/** Tests for {@link PreviewDataManager}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class PreviewDataManagerTest {
- private static final long FAKE_PREVIEW_CHANNEL_ID = 2002;
- private static final long FAKE_PROGRAM_ID = 1001;
- private static final String FAKE_PROGRAM_TITLE = "test program";
- private static final String FAKE_PROGRAM_POSTER_URI = "http://fake.uri/poster.jpg";
- private static final long FAKE_CHANNEL_ID = 1002;
- private static final String FAKE_CHANNEL_DISPLAY_NAME = "test channel";
- private static final String FAKE_INPUT_ID = "test input";
-
- private static class QueryExceptionProvider extends ContentProvider {
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Nullable
- @Override
- public Cursor query(
- @NonNull Uri uri,
- @Nullable String[] projection,
- @Nullable String selection,
- @Nullable String[] selectionArgs,
- @Nullable String sortOrder) {
- throw new SQLException("Testing " + uri);
- }
-
- @Nullable
- @Override
- public String getType(@NonNull Uri uri) {
- return null;
- }
-
- @Nullable
- @Override
- public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(
- @NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(
- @NonNull Uri uri,
- @Nullable ContentValues values,
- @Nullable String selection,
- @Nullable String[] selectionArgs) {
- return 0;
- }
- }
-
- @Test
- public void start() {
- PreviewDataManager previewDataManager =
- new PreviewDataManager(RuntimeEnvironment.application);
- assertThat(previewDataManager.isLoadFinished()).isFalse();
- previewDataManager.start();
- assertThat(previewDataManager.isLoadFinished()).isTrue();
- }
-
- @Test
- public void queryPreviewData_sqlexception() {
- ProviderInfo info = new ProviderInfo();
- info.authority = TvContractCompat.AUTHORITY;
- QueryExceptionProvider provider =
- Robolectric.buildContentProvider(QueryExceptionProvider.class).create(info).get();
- ShadowContentResolver.registerProviderInternal(TvContractCompat.AUTHORITY, provider);
-
- PreviewDataManager previewDataManager =
- new PreviewDataManager(RuntimeEnvironment.application);
- assertThat(previewDataManager.isLoadFinished()).isFalse();
- previewDataManager.start();
- List<ShadowLog.LogItem> logs = ShadowLog.getLogsForTag("PreviewDataManager");
- // The only warning should be the test one
- // NOTE: I am not using hamcrest matchers because of weird class loading issues
- // TODO: use truth
- for (ShadowLog.LogItem log : logs) {
- if (log.type == Log.WARN) {
- assertThat(log.msg).isEqualTo("Unable to get preview data");
- assertThat(log.throwable).isInstanceOf(SQLException.class);
- assertThat(log.throwable)
- .hasMessageThat()
- .isEqualTo("Testing content://android.media.tv/channel?preview=true");
- }
- }
- }
-
- @Test
- public void createPreviewProgram_fromProgram() {
- Program program =
- new ProgramImpl.Builder()
- .setId(FAKE_PROGRAM_ID)
- .setTitle(FAKE_PROGRAM_TITLE)
- .setPosterArtUri(FAKE_PROGRAM_POSTER_URI)
- .build();
- Channel channel =
- new ChannelImpl.Builder()
- .setId(FAKE_CHANNEL_ID)
- .setDisplayName(FAKE_CHANNEL_DISPLAY_NAME)
- .setInputId(FAKE_INPUT_ID)
- .build();
-
- PreviewProgram previewProgram =
- PreviewDataManager.PreviewDataUtils.createPreviewProgramFromContent(
- PreviewProgramContent.createFromProgram(
- FAKE_PREVIEW_CHANNEL_ID, program, channel),
- 0);
-
- assertThat(previewProgram.getChannelId()).isEqualTo(FAKE_PREVIEW_CHANNEL_ID);
- assertThat(previewProgram.getType())
- .isEqualTo(TvContractCompat.PreviewPrograms.TYPE_CHANNEL);
- assertThat(previewProgram.isLive()).isTrue();
- assertThat(previewProgram.getTitle()).isEqualTo(FAKE_PROGRAM_TITLE);
- assertThat(previewProgram.getDescription()).isEqualTo(FAKE_CHANNEL_DISPLAY_NAME);
- assertThat(previewProgram.getPosterArtUri().toString()).isEqualTo(FAKE_PROGRAM_POSTER_URI);
- assertThat(previewProgram.getIntentUri()).isEqualTo(channel.getUri());
- assertThat(previewProgram.getPreviewVideoUri())
- .isEqualTo(
- PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
- channel.getUri(),
- Pair.create(PreviewProgramContent.PARAM_INPUT, FAKE_INPUT_ID)));
- assertThat(previewProgram.getInternalProviderId())
- .isEqualTo(Long.toString(FAKE_PROGRAM_ID));
- assertThat(previewProgram.getContentId()).isEqualTo(channel.getUri().toString());
- }
-
- @Test
- public void createPreviewProgram_fromRecordedProgram() {
- RecordedProgram program =
- RecordedProgram.builder()
- .setId(FAKE_PROGRAM_ID)
- .setTitle(FAKE_PROGRAM_TITLE)
- .setPosterArtUri(FAKE_PROGRAM_POSTER_URI)
- .setInputId(FAKE_INPUT_ID)
- .build();
- Uri recordedProgramUri = TvContractCompat.buildRecordedProgramUri(FAKE_PROGRAM_ID);
-
- PreviewProgram previewProgram =
- PreviewDataManager.PreviewDataUtils.createPreviewProgramFromContent(
- PreviewProgramContent.createFromRecordedProgram(
- FAKE_PREVIEW_CHANNEL_ID, program, null),
- 0);
-
- assertThat(previewProgram.getChannelId()).isEqualTo(FAKE_PREVIEW_CHANNEL_ID);
- assertThat(previewProgram.getType()).isEqualTo(TvContractCompat.PreviewPrograms.TYPE_CLIP);
- assertThat(previewProgram.isLive()).isFalse();
- assertThat(previewProgram.getTitle()).isEqualTo(FAKE_PROGRAM_TITLE);
- assertThat(previewProgram.getDescription()).isEmpty();
- assertThat(previewProgram.getPosterArtUri().toString()).isEqualTo(FAKE_PROGRAM_POSTER_URI);
- assertThat(previewProgram.getIntentUri()).isEqualTo(recordedProgramUri);
- assertThat(previewProgram.getPreviewVideoUri())
- .isEqualTo(
- PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
- recordedProgramUri,
- Pair.create(PreviewProgramContent.PARAM_INPUT, FAKE_INPUT_ID)));
- assertThat(previewProgram.getContentId()).isEqualTo(recordedProgramUri.toString());
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/ProgramDataManagerTest.java b/tests/robotests/src/com/android/tv/data/ProgramDataManagerTest.java
deleted file mode 100644
index 2176aa98..00000000
--- a/tests/robotests/src/com/android/tv/data/ProgramDataManagerTest.java
+++ /dev/null
@@ -1,316 +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.data;
-
-import static android.os.Looper.getMainLooper;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.robolectric.Shadows.shadowOf;
-
-import android.content.ContentResolver;
-import android.media.tv.TvContract;
-
-import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
-import com.android.tv.data.api.Program;
-import com.android.tv.perf.stub.StubPerformanceMonitor;
-import com.android.tv.testing.FakeTvInputManagerHelper;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.constants.Constants;
-import com.android.tv.testing.data.ProgramInfo;
-import com.android.tv.testing.data.ProgramUtils;
-import com.android.tv.testing.fakes.FakeClock;
-import com.android.tv.testing.fakes.FakeTvProvider;
-import com.android.tv.testing.robo.ContentProviders;
-import com.android.tv.testing.testdata.TestData;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.util.concurrent.RoboExecutorService;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/** Test for {@link ProgramDataManager} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class ProgramDataManagerTest {
-
- // Wait time for expected success.
- private static final long WAIT_TIME_OUT_MS = 1000L;
- // Wait time for expected failure.
- private static final long FAILURE_TIME_OUT_MS = 300L;
-
- private ProgramDataManager mProgramDataManager;
- private FakeClock mClock;
- private TestProgramDataManagerCallback mCallback;
-
- @Before
- public void setUp() {
- mClock = FakeClock.createWithCurrentTime();
- mCallback = new TestProgramDataManagerCallback();
- ContentProviders.register(FakeTvProvider.class, TvContract.AUTHORITY);
- TestData.DEFAULT_10_CHANNELS.init(
- RuntimeEnvironment.application, mClock, TimeUnit.DAYS.toMillis(1));
- FakeTvInputManagerHelper tvInputManagerHelper =
- new FakeTvInputManagerHelper(RuntimeEnvironment.application);
- RoboExecutorService executor = new RoboExecutorService();
- ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
- ChannelDataManager channelDataManager =
- new ChannelDataManager(
- RuntimeEnvironment.application,
- tvInputManagerHelper,
- executor,
- contentResolver);
- mProgramDataManager =
- new ProgramDataManager(
- RuntimeEnvironment.application,
- executor,
- RuntimeEnvironment.application.getContentResolver(),
- mClock,
- getMainLooper(),
- new DefaultBackendKnobsFlags(),
- new StubPerformanceMonitor(),
- channelDataManager,
- tvInputManagerHelper);
-
- mProgramDataManager.setPrefetchEnabled(true);
- mProgramDataManager.addCallback(mCallback);
- }
-
- @After
- public void tearDown() {
- mProgramDataManager.stop();
- }
-
- private void startAndWaitForComplete() throws InterruptedException {
- mProgramDataManager.start();
- shadowOf(getMainLooper()).idle();
- assertThat(mCallback.channelUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
- .isTrue();
- }
-
- /** Test for {@link ProgramInfo#getIndex} and {@link ProgramInfo#getStartTimeMs}. */
- @Test
- public void testProgramUtils() {
- ProgramInfo stub = ProgramInfo.create();
- for (long channelId = 1; channelId < Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) {
- int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
- long startTimeMs = stub.getStartTimeMs(index, channelId);
- ProgramInfo programAt = stub.build(RuntimeEnvironment.application, index);
- assertThat(startTimeMs).isAtMost(mClock.currentTimeMillis());
- assertThat(mClock.currentTimeMillis()).isLessThan(startTimeMs + programAt.durationMs);
- }
- }
-
- /**
- * Test for following methods.
- *
- * <p>{@link ProgramDataManager#getCurrentProgram(long)}, {@link
- * ProgramDataManager#getPrograms(long, long)}, {@link
- * ProgramDataManager#setPrefetchTimeRange(long)}.
- */
- @Test
- public void testGetPrograms() throws InterruptedException {
- // Initial setup to test {@link ProgramDataManager#setPrefetchTimeRange(long)}.
- long preventSnapDelayMs = ProgramDataManager.PROGRAM_GUIDE_SNAP_TIME_MS * 2;
- long prefetchTimeRangeStartMs = System.currentTimeMillis() + preventSnapDelayMs;
- mClock.setCurrentTimeMillis(prefetchTimeRangeStartMs + preventSnapDelayMs);
- mProgramDataManager.setPrefetchTimeRange(prefetchTimeRangeStartMs);
-
- startAndWaitForComplete();
-
- for (long channelId = 1; channelId <= Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) {
- Program currentProgram = mProgramDataManager.getCurrentProgram(channelId);
- // Test {@link ProgramDataManager#getCurrentProgram(long)}.
- assertThat(currentProgram).isNotNull();
- assertWithMessage("currentProgramStartTime")
- .that(currentProgram.getStartTimeUtcMillis())
- .isLessThan(mClock.currentTimeMillis());
- assertWithMessage("currentProgramEndTime")
- .that(currentProgram.getEndTimeUtcMillis())
- .isGreaterThan(mClock.currentTimeMillis());
-
- // Test {@link ProgramDataManager#getPrograms(long)}.
- // Case #1: Normal case
- List<Program> programs =
- mProgramDataManager.getPrograms(channelId, mClock.currentTimeMillis());
- ProgramInfo stub = ProgramInfo.create();
- int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
- for (Program program : programs) {
- ProgramInfo programInfoAt = stub.build(RuntimeEnvironment.application, index);
- long startTimeMs = stub.getStartTimeMs(index, channelId);
- assertProgramEquals(startTimeMs, programInfoAt, program);
- index++;
- }
- // Case #2: Corner cases where there's a program that starts at the start of the range.
- long startTimeMs = programs.get(0).getStartTimeUtcMillis();
- programs = mProgramDataManager.getPrograms(channelId, startTimeMs);
- assertThat(programs.get(0).getStartTimeUtcMillis()).isEqualTo(startTimeMs);
-
- // Test {@link ProgramDataManager#setPrefetchTimeRange(long)}.
- programs =
- mProgramDataManager.getPrograms(
- channelId, prefetchTimeRangeStartMs - TimeUnit.HOURS.toMillis(1));
- for (Program program : programs) {
- assertThat(program.getEndTimeUtcMillis()).isAtLeast(prefetchTimeRangeStartMs);
- }
- }
- }
-
- /**
- * Test for following methods.
- *
- * <p>{@link ProgramDataManager#addOnCurrentProgramUpdatedListener}, {@link
- * ProgramDataManager#removeOnCurrentProgramUpdatedListener}.
- */
- @Test
- public void testCurrentProgramListener() throws InterruptedException {
- final long testChannelId = 1;
- ProgramInfo stub = ProgramInfo.create();
- int index = stub.getIndex(mClock.currentTimeMillis(), testChannelId);
- // Set current time to few seconds before the current program ends,
- // so we can see if callback is called as expected.
- long nextProgramStartTimeMs = stub.getStartTimeMs(index + 1, testChannelId);
- ProgramInfo nextProgramInfo = stub.build(RuntimeEnvironment.application, index + 1);
- mClock.setCurrentTimeMillis(nextProgramStartTimeMs - (WAIT_TIME_OUT_MS / 2));
-
- startAndWaitForComplete();
- // Note that changing current time doesn't affect the current program
- // because current program is updated after waiting for the program's duration.
- // See {@link ProgramDataManager#updateCurrentProgram}.
- TestProgramDataManagerOnCurrentProgramUpdatedListener listener =
- new TestProgramDataManagerOnCurrentProgramUpdatedListener();
- mClock.setCurrentTimeMillis(mClock.currentTimeMillis() + WAIT_TIME_OUT_MS);
- mProgramDataManager.addOnCurrentProgramUpdatedListener(testChannelId, listener);
- shadowOf(getMainLooper()).runToEndOfTasks();
- assertThat(
- listener.currentProgramUpdatedLatch.await(
- WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
- .isTrue();
- assertThat(listener.updatedChannelId).isEqualTo(testChannelId);
- Program currentProgram = mProgramDataManager.getCurrentProgram(testChannelId);
- assertProgramEquals(nextProgramStartTimeMs, nextProgramInfo, currentProgram);
- assertThat(currentProgram).isEqualTo(listener.updatedProgram);
- }
-
- /** Test if program data is refreshed after the program insertion. */
- @Test
- public void testContentProviderUpdate() throws InterruptedException {
- final long testChannelId = 1;
- startAndWaitForComplete();
- // Force program data manager to update program data whenever it's changes.
- mProgramDataManager.setProgramPrefetchUpdateWait(0);
- mCallback.reset();
- List<Program> programList =
- mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis());
- assertThat(programList).isNotNull();
- long lastProgramEndTime = programList.get(programList.size() - 1).getEndTimeUtcMillis();
- // Make change in content provider
- ProgramUtils.populatePrograms(
- RuntimeEnvironment.application,
- TvContract.buildChannelUri(testChannelId),
- ProgramInfo.create(),
- mClock,
- TimeUnit.DAYS.toMillis(2));
- shadowOf(getMainLooper()).runToEndOfTasks();
- assertThat(mCallback.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
- .isTrue();
- programList = mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis());
- assertThat(lastProgramEndTime)
- .isLessThan(programList.get(programList.size() - 1).getEndTimeUtcMillis());
- }
-
- /** Test for {@link ProgramDataManager#setPauseProgramUpdate(boolean)}. */
- @Test
- public void testSetPauseProgramUpdate() throws InterruptedException {
- final long testChannelId = 1;
- startAndWaitForComplete();
- // Force program data manager to update program data whenever it's changes.
- mProgramDataManager.setProgramPrefetchUpdateWait(0);
- mCallback.reset();
- mProgramDataManager.setPauseProgramUpdate(true);
- ProgramUtils.populatePrograms(
- RuntimeEnvironment.application,
- TvContract.buildChannelUri(testChannelId),
- ProgramInfo.create(),
- mClock,
- TimeUnit.DAYS.toMillis(2));
- shadowOf(getMainLooper()).runToEndOfTasks();
- assertThat(mCallback.programUpdatedLatch.await(FAILURE_TIME_OUT_MS, TimeUnit.MILLISECONDS))
- .isFalse();
- }
-
- public static void assertProgramEquals(
- long expectedStartTime, ProgramInfo expectedInfo, Program actualProgram) {
- assertWithMessage("title").that(actualProgram.getTitle()).isEqualTo(expectedInfo.title);
- assertWithMessage("episode")
- .that(actualProgram.getEpisodeTitle())
- .isEqualTo(expectedInfo.episode);
- assertWithMessage("description")
- .that(actualProgram.getDescription())
- .isEqualTo(expectedInfo.description);
- assertWithMessage("startTime")
- .that(actualProgram.getStartTimeUtcMillis())
- .isEqualTo(expectedStartTime);
- assertWithMessage("endTime")
- .that(actualProgram.getEndTimeUtcMillis())
- .isEqualTo(expectedStartTime + expectedInfo.durationMs);
- }
-
- private static class TestProgramDataManagerCallback implements ProgramDataManager.Callback {
- public CountDownLatch programUpdatedLatch = new CountDownLatch(1);
- public CountDownLatch channelUpdatedLatch = new CountDownLatch(1);
-
- @Override
- public void onProgramUpdated() {
- programUpdatedLatch.countDown();
- }
-
- @Override
- public void onChannelUpdated() {
- channelUpdatedLatch.countDown();
- }
-
- public void reset() {
- programUpdatedLatch = new CountDownLatch(1);
- channelUpdatedLatch = new CountDownLatch(1);
- }
- }
-
- private static class TestProgramDataManagerOnCurrentProgramUpdatedListener
- implements OnCurrentProgramUpdatedListener {
- public final CountDownLatch currentProgramUpdatedLatch = new CountDownLatch(1);
- public long updatedChannelId = -1;
- public Program updatedProgram = null;
-
- @Override
- public void onCurrentProgramUpdated(long channelId, Program program) {
- updatedChannelId = channelId;
- updatedProgram = program;
- currentProgramUpdatedLatch.countDown();
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/ProgramTest.java b/tests/robotests/src/com/android/tv/data/ProgramTest.java
deleted file mode 100644
index 407cca97..00000000
--- a/tests/robotests/src/com/android/tv/data/ProgramTest.java
+++ /dev/null
@@ -1,276 +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.data;
-
-import static android.media.tv.TvContract.Programs.Genres.COMEDY;
-import static android.media.tv.TvContract.Programs.Genres.FAMILY_KIDS;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.media.tv.TvContentRating;
-import android.media.tv.TvContract.Programs.Genres;
-import android.os.Parcel;
-
-import com.android.tv.data.api.Program;
-import com.android.tv.data.api.Program.CriticScore;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/** Tests for {@link ProgramImpl}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class ProgramTest {
- private static final int NOT_FOUND_GENRE = 987;
-
- private static final int FAMILY_GENRE_ID = GenreItems.getId(FAMILY_KIDS);
-
- private static final int COMEDY_GENRE_ID = GenreItems.getId(COMEDY);
-
- @Test
- public void testBuild() {
- Program program = new ProgramImpl.Builder().build();
- assertWithMessage("isValid").that(program.isValid()).isFalse();
- }
-
- @Test
- public void testNoGenres() {
- Program program = new ProgramImpl.Builder().setCanonicalGenres("").build();
- assertNullCanonicalGenres(program);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, false);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testFamilyGenre() {
- Program program = new ProgramImpl.Builder().setCanonicalGenres(FAMILY_KIDS).build();
- assertCanonicalGenres(program, FAMILY_KIDS);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, true);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testFamilyComedyGenre() {
- Program program =
- new ProgramImpl.Builder().setCanonicalGenres(FAMILY_KIDS + ", " + COMEDY).build();
- assertCanonicalGenres(program, FAMILY_KIDS, COMEDY);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, true);
- assertHasGenre(program, COMEDY_GENRE_ID, true);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testOtherGenre() {
- Program program = new ProgramImpl.Builder().setCanonicalGenres("other").build();
- assertCanonicalGenres(program);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, false);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testParcelable() {
- List<CriticScore> criticScores = new ArrayList<>();
- criticScores.add(new CriticScore("1", "2", "3"));
- criticScores.add(new CriticScore("4", "5", "6"));
- ImmutableList<TvContentRating> ratings =
- ImmutableList.of(
- TvContentRating.unflattenFromString("1/2/3"),
- TvContentRating.unflattenFromString("4/5/6"));
- ProgramImpl p =
- new ProgramImpl.Builder()
- .setId(1)
- .setPackageName("2")
- .setChannelId(3)
- .setTitle("4")
- .setSeriesId("5")
- .setEpisodeTitle("6")
- .setSeasonNumber("7")
- .setSeasonTitle("8")
- .setEpisodeNumber("9")
- .setStartTimeUtcMillis(10)
- .setEndTimeUtcMillis(11)
- .setDescription("12")
- .setLongDescription("12-long")
- .setVideoWidth(13)
- .setVideoHeight(14)
- .setCriticScores(criticScores)
- .setPosterArtUri("15")
- .setThumbnailUri("16")
- .setCanonicalGenres(Genres.encode(Genres.SPORTS, Genres.SHOPPING))
- .setContentRatings(ratings)
- .setRecordingProhibited(true)
- .build();
- Parcel p1 = Parcel.obtain();
- Parcel p2 = Parcel.obtain();
- try {
- p.writeToParcel(p1, 0);
- byte[] bytes = p1.marshall();
- p2.unmarshall(bytes, 0, bytes.length);
- p2.setDataPosition(0);
- ProgramImpl r2 = ProgramImpl.fromParcel(p2);
- assertThat(r2).isEqualTo(p);
- } finally {
- p1.recycle();
- p2.recycle();
- }
- }
-
- @Test
- public void testParcelableWithCriticScore() {
- ProgramImpl program =
- new ProgramImpl.Builder()
- .setTitle("MyTitle")
- .addCriticScore(
- new CriticScore(
- "default source", "5/10", "http://testurl/testimage.jpg"))
- .build();
- Parcel parcel = Parcel.obtain();
- program.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- Program programFromParcel = ProgramImpl.CREATOR.createFromParcel(parcel);
-
- assertThat(programFromParcel.getCriticScores()).isNotNull();
- assertThat(programFromParcel.getCriticScores().get(0).source).isEqualTo("default source");
- assertThat(programFromParcel.getCriticScores().get(0).score).isEqualTo("5/10");
- assertThat(programFromParcel.getCriticScores().get(0).logoUrl)
- .isEqualTo("http://testurl/testimage.jpg");
- }
-
- @Test
- public void getEpisodeContentDescription_blank() {
- Program program = new ProgramImpl.Builder().build();
- assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application)).isNull();
- }
-
- @Test
- public void getEpisodeContentDescription_seasonEpisodeAndTitle() {
- Program program =
- new ProgramImpl.Builder()
- .setSeasonNumber("1")
- .setEpisodeNumber("2")
- .setEpisodeTitle("The second one")
- .build();
- assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
- .isEqualTo("Season 1 Episode 2 The second one");
- }
-
- @Test
- public void getEpisodeContentDescription_EpisodeAndTitle() {
- Program program =
- new ProgramImpl.Builder()
- .setEpisodeNumber("2")
- .setEpisodeTitle("The second one")
- .build();
- assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
- .isEqualTo("Episode 2 The second one");
- }
-
- @Test
- public void getEpisodeContentDescription_seasonEpisode() {
- Program program =
- new ProgramImpl.Builder().setSeasonNumber("1").setEpisodeNumber("2").build();
- assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
- .isEqualTo("Season 1 Episode 2 ");
- }
-
- @Test
- public void getEpisodeContentDescription_EpisodeTitle() {
- Program program = new ProgramImpl.Builder().setEpisodeTitle("The second one").build();
- assertThat(program.getEpisodeContentDescription(RuntimeEnvironment.application))
- .isEqualTo("The second one");
- }
-
- @Test
- public void getEpisodeDisplayTitle_blank() {
- Program program = new ProgramImpl.Builder().build();
- assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application)).isNull();
- }
-
- @Test
- public void getEpisodeDisplayTitle_seasonEpisodeAndTitle() {
- Program program =
- new ProgramImpl.Builder()
- .setSeasonNumber("1")
- .setEpisodeNumber("2")
- .setEpisodeTitle("The second one")
- .build();
- assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
- .isEqualTo("S1: Ep. 2 The second one");
- }
-
- @Test
- public void getEpisodeDisplayTitle_EpisodeTitle() {
- Program program =
- new ProgramImpl.Builder()
- .setEpisodeNumber("2")
- .setEpisodeTitle("The second one")
- .build();
- assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
- .isEqualTo("Ep. 2 The second one");
- }
-
- @Test
- public void getEpisodeDisplayTitle_seasonEpisode() {
- Program program =
- new ProgramImpl.Builder().setSeasonNumber("1").setEpisodeNumber("2").build();
- assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
- .isEqualTo("S1: Ep. 2 ");
- }
-
- @Test
- public void getEpisodeDisplayTitle_episode() {
- Program program = new ProgramImpl.Builder().setEpisodeTitle("The second one").build();
- assertThat(program.getEpisodeDisplayTitle(RuntimeEnvironment.application))
- .isEqualTo("The second one");
- }
-
- private static void assertNullCanonicalGenres(Program program) {
- String[] actual = program.getCanonicalGenres();
- assertWithMessage("Expected null canonical genres but was " + Arrays.toString(actual))
- .that(actual)
- .isNull();
- }
-
- private static void assertCanonicalGenres(Program program, String... expected) {
- assertWithMessage("canonical genres")
- .that(Arrays.asList(program.getCanonicalGenres()))
- .isEqualTo(Arrays.asList(expected));
- }
-
- private static void assertHasGenre(Program program, int genreId, boolean expected) {
- assertWithMessage("hasGenre(" + genreId + ")")
- .that(program.hasGenre(genreId))
- .isEqualTo(expected);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/TvInputNewComparatorTest.java b/tests/robotests/src/com/android/tv/data/TvInputNewComparatorTest.java
deleted file mode 100644
index 201fa03d..00000000
--- a/tests/robotests/src/com/android/tv/data/TvInputNewComparatorTest.java
+++ /dev/null
@@ -1,102 +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.data;
-
-import android.content.pm.ResolveInfo;
-import android.media.tv.TvInputInfo;
-import android.util.Pair;
-
-import com.android.tv.testing.ComparatorTester;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.utils.TestUtils;
-import com.android.tv.util.SetupUtils;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-
-/** Test for {@link TvInputNewComparator} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvInputNewComparatorTest {
- @Test
- public void testComparator() throws Exception {
- LinkedHashMap<String, Pair<Boolean, Boolean>> inputIdToNewInput = new LinkedHashMap<>();
- inputIdToNewInput.put("2_new_input", Pair.create(true, false));
- inputIdToNewInput.put("4_new_input", Pair.create(true, false));
- inputIdToNewInput.put("4_old_input", Pair.create(false, false));
- inputIdToNewInput.put("0_old_input", Pair.create(false, true));
- inputIdToNewInput.put("1_old_input", Pair.create(false, true));
- inputIdToNewInput.put("3_old_input", Pair.create(false, true));
-
- SetupUtils setupUtils = Mockito.mock(SetupUtils.class);
- Mockito.when(setupUtils.isNewInput(ArgumentMatchers.anyString()))
- .thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return inputIdToNewInput.get(inputId).first;
- }
- });
- Mockito.when(setupUtils.isSetupDone(ArgumentMatchers.anyString()))
- .thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return inputIdToNewInput.get(inputId).second;
- }
- });
- TvInputManagerHelper inputManager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(inputManager.getDefaultTvInputInfoComparator())
- .thenReturn(
- new Comparator<TvInputInfo>() {
- @Override
- public int compare(TvInputInfo lhs, TvInputInfo rhs) {
- return lhs.getId().compareTo(rhs.getId());
- }
- });
- TvInputNewComparator comparator = new TvInputNewComparator(setupUtils, inputManager);
- ComparatorTester comparatorTester =
- new ComparatorTester(comparator).permitInconsistencyWithEquals();
- ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
- for (String id : inputIdToNewInput.keySet()) {
- // Put mock resolveInfo to prevent NPE in {@link TvInputInfo#toString}
- TvInputInfo info1 =
- TestUtils.createTvInputInfo(
- resolveInfo, id, "test1", TvInputInfo.TYPE_TUNER, false);
- TvInputInfo info2 =
- TestUtils.createTvInputInfo(
- resolveInfo, id, "test2", TvInputInfo.TYPE_DISPLAY_PORT, true);
- TvInputInfo info3 =
- TestUtils.createTvInputInfo(
- resolveInfo, id, "test", TvInputInfo.TYPE_HDMI, true);
- comparatorTester.addEqualityGroup(info1, info2, info3);
- }
- comparatorTester.testCompare();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/WatchedHistoryManagerTest.java b/tests/robotests/src/com/android/tv/data/WatchedHistoryManagerTest.java
deleted file mode 100644
index 761827a9..00000000
--- a/tests/robotests/src/com/android/tv/data/WatchedHistoryManagerTest.java
+++ /dev/null
@@ -1,144 +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.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.tv.data.WatchedHistoryManager.WatchedRecord;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import com.google.common.util.concurrent.MoreExecutors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.concurrent.TimeUnit;
-
-/** Test for {@link WatchedHistoryManagerTest}. */
-@SmallTest
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class WatchedHistoryManagerTest {
- // Wait time for expected success.
- private static final int MAX_HISTORY_SIZE = 100;
-
- private WatchedHistoryManager mWatchedHistoryManager;
- private TestWatchedHistoryManagerListener mListener;
-
- @Before
- public void setUp() {
- mWatchedHistoryManager =
- new WatchedHistoryManager(
- RuntimeEnvironment.application,
- MAX_HISTORY_SIZE,
- MoreExecutors.directExecutor());
- mListener = new TestWatchedHistoryManagerListener();
- mWatchedHistoryManager.setListener(mListener);
- }
-
- private void startAndWaitForComplete() {
- mWatchedHistoryManager.start();
- assertThat(mListener.mLoadFinished).isTrue();
- }
-
- @Test
- public void testIsLoaded() {
- startAndWaitForComplete();
- assertThat(mWatchedHistoryManager.isLoaded()).isTrue();
- }
-
- @Test
- public void testLogChannelViewStop() {
- startAndWaitForComplete();
- long fakeId = 100000000;
- long time = System.currentTimeMillis();
- long duration = TimeUnit.MINUTES.toMillis(10);
- ChannelImpl channel = new ChannelImpl.Builder().setId(fakeId).build();
- mWatchedHistoryManager.logChannelViewStop(channel, time, duration);
-
- WatchedRecord record = mWatchedHistoryManager.getRecord(0);
- WatchedRecord recordFromSharedPreferences =
- mWatchedHistoryManager.getRecordFromSharedPreferences(0);
- assertThat(fakeId).isEqualTo(record.channelId);
- assertThat(time - duration).isEqualTo(record.watchedStartTime);
- assertThat(duration).isEqualTo(record.duration);
- assertThat(recordFromSharedPreferences).isEqualTo(record);
- }
-
- @Test
- public void testCircularHistoryQueue() {
- startAndWaitForComplete();
- final long startChannelId = 100000000;
- long time = System.currentTimeMillis();
- long duration = TimeUnit.MINUTES.toMillis(10);
-
- int size = MAX_HISTORY_SIZE * 2;
- for (int i = 0; i < size; ++i) {
- ChannelImpl channel = new ChannelImpl.Builder().setId(startChannelId + i).build();
- mWatchedHistoryManager.logChannelViewStop(channel, time + duration * i, duration);
- }
- for (int i = 0; i < MAX_HISTORY_SIZE; ++i) {
- WatchedRecord record = mWatchedHistoryManager.getRecord(i);
- WatchedRecord recordFromSharedPreferences =
- mWatchedHistoryManager.getRecordFromSharedPreferences(i);
- assertThat(recordFromSharedPreferences).isEqualTo(record);
- assertThat(startChannelId + size - 1 - i).isEqualTo(record.channelId);
- }
- // Since the WatchedHistory is a circular queue, the value for 0 and maxHistorySize
- // are same.
- assertThat(mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE))
- .isEqualTo(mWatchedHistoryManager.getRecordFromSharedPreferences(0));
- }
-
- @Test
- public void testWatchedRecordEquals() {
- assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3))).isTrue();
- assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4))).isFalse();
- assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3))).isFalse();
- assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3))).isFalse();
- }
-
- @Test
- public void testEncodeDecodeWatchedRecord() {
- long fakeId = 100000000;
- long time = System.currentTimeMillis();
- long duration = TimeUnit.MINUTES.toMillis(10);
- WatchedRecord record = new WatchedRecord(fakeId, time, duration);
- WatchedRecord sameRecord =
- mWatchedHistoryManager.decode(mWatchedHistoryManager.encode(record));
- assertThat(sameRecord).isEqualTo(record);
- }
-
- private static final class TestWatchedHistoryManagerListener
- implements WatchedHistoryManager.Listener {
- boolean mLoadFinished;
-
- @Override
- public void onLoadFinished() {
- mLoadFinished = true;
- }
-
- @Override
- public void onNewRecordAdded(WatchedRecord watchedRecord) {}
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/api/ProgramTest.java b/tests/robotests/src/com/android/tv/data/api/ProgramTest.java
deleted file mode 100644
index 3b9f062a..00000000
--- a/tests/robotests/src/com/android/tv/data/api/ProgramTest.java
+++ /dev/null
@@ -1,119 +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.data.api;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link Program}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class ProgramTest {
-
- private static ProgramImpl createProgramWithStartEndTimes(
- long startTimeUtcMillis, long endTimeUtcMillis) {
- return new ProgramImpl.Builder()
- .setStartTimeUtcMillis(startTimeUtcMillis)
- .setEndTimeUtcMillis(endTimeUtcMillis)
- .build();
- }
-
- private static ProgramImpl createProgramWithChannelId(long channelId) {
- return new ProgramImpl.Builder().setChannelId(channelId).build();
- }
-
- private final Program start10end20 = createProgramWithStartEndTimes(10, 20);
- private final Program channel1 = createProgramWithChannelId(1);
-
- @Test
- public void sameChannel_nullAlwaysFalse() {
- assertThat(Program.sameChannel(null, null)).isFalse();
- assertThat(Program.sameChannel(channel1, null)).isFalse();
- assertThat(Program.sameChannel(null, channel1)).isFalse();
- }
-
- @Test
- public void sameChannel_true() {
- assertThat(Program.sameChannel(channel1, channel1)).isTrue();
- assertThat(Program.sameChannel(channel1, createProgramWithChannelId(1))).isTrue();
- }
-
- @Test
- public void sameChannel_false() {
- assertThat(Program.sameChannel(channel1, createProgramWithChannelId(2))).isFalse();
- }
-
- @Test
- public void isOverLapping_nullAlwaysFalse() {
- assertThat(Program.isOverlapping(null, null)).isFalse();
- assertThat(Program.isOverlapping(start10end20, null)).isFalse();
- assertThat(Program.isOverlapping(null, start10end20)).isFalse();
- }
-
- @Test
- public void isOverLapping_same() {
- assertThat(Program.isOverlapping(start10end20, start10end20)).isTrue();
- }
-
- @Test
- public void isOverLapping_endBefore() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(1, 9)))
- .isFalse();
- }
-
- @Test
- public void isOverLapping_endAtStart() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(1, 10)))
- .isFalse();
- }
-
- @Test
- public void isOverLapping_endDuring() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(1, 11)))
- .isTrue();
- }
-
- @Test
- public void isOverLapping_startAfter() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(21, 30)))
- .isFalse();
- }
-
- @Test
- public void isOverLapping_beginAtEnd() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(20, 30)))
- .isFalse();
- }
-
- @Test
- public void isOverLapping_beginBeforeEnd() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(19, 30)))
- .isTrue();
- }
-
- @Test
- public void isOverLapping_inside() {
- assertThat(Program.isOverlapping(start10end20, createProgramWithStartEndTimes(11, 19)))
- .isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/epg/EpgFetcherImplTest.java b/tests/robotests/src/com/android/tv/data/epg/EpgFetcherImplTest.java
deleted file mode 100644
index 91472d0d..00000000
--- a/tests/robotests/src/com/android/tv/data/epg/EpgFetcherImplTest.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.data.epg;
-
-/** Tests for {@link EpgFetcher}. */
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.sqlite.SQLiteDatabase;
-import android.media.tv.TvContract;
-
-import androidx.tvprovider.media.tv.Channel;
-
-import com.android.tv.common.CommonPreferences;
-import com.android.tv.common.buildtype.HasBuildType.BuildType;
-import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
-import com.android.tv.common.flags.impl.SettableFlagsModule;
-import com.android.tv.common.util.PostalCodeUtils;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.features.TvFeatures;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.stub.StubPerformanceMonitor;
-import com.android.tv.testing.DbTestingUtils;
-import com.android.tv.testing.EpgTestData;
-import com.android.tv.testing.FakeEpgReader;
-import com.android.tv.testing.FakeTvInputManagerHelper;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.fakes.FakeClock;
-import com.android.tv.testing.fakes.FakeTvProvider;
-import com.android.tv.testing.robo.ContentProviders;
-
-import com.google.android.tv.livechannels.epg.provider.EpgContentProvider;
-import com.google.android.tv.partner.support.EpgContract;
-import com.google.common.collect.ImmutableList;
-import com.android.tv.common.flags.proto.TypedFeatures.StringListParam;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.android.util.concurrent.RoboExecutorService;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-
-/** Tests for {@link EpgFetcherImpl}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = EpgFetcherImplTest.TestApp.class)
-public class EpgFetcherImplTest {
-
- /** TestApp for {@link EpgFetcherImplTest} */
- public static class TestApp extends TestSingletonApp implements HasAndroidInjector {
- @Inject DispatchingAndroidInjector<Object> dispatchingAndroidInjector;
-
- @Override
- public void onCreate() {
- super.onCreate();
- DaggerEpgFetcherImplTest_TestAppComponent.builder()
- .settableFlagsModule(flagsModule)
- .build()
- .inject(this);
- }
-
- @Override
- public AndroidInjector<Object> androidInjector() {
- return dispatchingAndroidInjector;
- }
- }
-
- /** Component for {@link EpgFetcherImplTest} */
- @Component(
- modules = {
- AndroidInjectionModule.class,
- TestModule.class,
- EpgContentProvider.Module.class
- })
- interface TestAppComponent extends AndroidInjector<TestApp> {}
-
- /** Module for {@link EpgFetcherImplTest} */
- @Module(includes = {SettableFlagsModule.class})
- public static class TestModule {}
-
- private static final String[] PROGRAM_COLUMNS = {
- TvContract.Programs.COLUMN_CHANNEL_ID,
- TvContract.Programs.COLUMN_TITLE,
- TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
- TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS
- };
-
- private static final String[] CHANNEL_COLUMNS = {
- TvContract.Channels.COLUMN_DISPLAY_NAME,
- TvContract.Channels.COLUMN_DISPLAY_NUMBER,
- TvContract.Channels.COLUMN_NETWORK_AFFILIATION
- };
-
- private FakeClock mFakeClock;
- private EpgFetcherImpl mEpgFetcher;
- private ChannelDataManager mChannelDataManager;
- private FakeEpgReader mEpgReader;
- private PerformanceMonitor mPerformanceMonitor = new StubPerformanceMonitor();
- private ContentResolver mContentResolver;
- private FakeTvProvider mTvProvider;
- private EpgContentProvider mEpgProvider;
- private EpgContentProvider.EpgDatabaseHelper mDatabaseHelper;
- private TestApp mTestApp;
-
- @Before
- public void setup() {
-
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.enableForTest();
- mTestApp = (TestApp) RuntimeEnvironment.application;
- Shadows.shadowOf(RuntimeEnvironment.application)
- .grantPermissions("com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA");
- mDatabaseHelper = new EpgContentProvider.EpgDatabaseHelper(RuntimeEnvironment.application);
- CommonPreferences.initialize(RuntimeEnvironment.application);
- PostalCodeUtils.setLastPostalCode(RuntimeEnvironment.application, "90210");
- EpgFetchHelper.setLastLineupId(RuntimeEnvironment.application, "test90210");
- mTvProvider = ContentProviders.register(FakeTvProvider.class, TvContract.AUTHORITY);
- mEpgProvider = ContentProviders.register(EpgContentProvider.class, EpgContract.AUTHORITY);
- mEpgProvider.setCallingPackage_("com.google.android.tv");
- mFakeClock = FakeClock.createWithCurrentTime();
- FakeTvInputManagerHelper fakeTvInputManagerHelper =
- new FakeTvInputManagerHelper(RuntimeEnvironment.application);
- mContentResolver = RuntimeEnvironment.application.getContentResolver();
- mChannelDataManager =
- new ChannelDataManager(
- RuntimeEnvironment.application,
- fakeTvInputManagerHelper,
- new RoboExecutorService(),
- mContentResolver);
- fakeTvInputManagerHelper.start();
- mChannelDataManager.start();
- mEpgReader = new FakeEpgReader(mFakeClock);
- mEpgFetcher =
- new EpgFetcherImpl(
- RuntimeEnvironment.application,
- new EpgInputWhiteList(
- mTestApp.flagsModule.cloudEpgFlags,
- mTestApp.flagsModule.legacyFlags),
- mChannelDataManager,
- mEpgReader,
- mPerformanceMonitor,
- mFakeClock,
- new DefaultBackendKnobsFlags(),
- BuildType.NO_JNI_TEST);
- EpgTestData.DATA_90210.loadData(mFakeClock, mEpgReader); // This also sets fake clock
- EpgFetchHelper.setLastEpgUpdatedTimestamp(
- RuntimeEnvironment.application,
- mFakeClock.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
- }
-
- @After
- public void after() {
- mChannelDataManager.stop();
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.resetForTests();
- }
-
- @Test
- public void fetchImmediately_nochannels() throws ExecutionException, InterruptedException {
- EpgFetcherImpl.FetchAsyncTask fetcherTask = mEpgFetcher.createFetchTask(null, null);
- fetcherTask.execute();
-
- assertThat(fetcherTask.get()).isEqualTo(EpgFetcherImpl.REASON_NO_BUILT_IN_CHANNELS);
- List<List<String>> rows =
- DbTestingUtils.toList(
- mContentResolver.query(
- TvContract.Programs.CONTENT_URI,
- PROGRAM_COLUMNS,
- null,
- null,
- null));
- assertThat(rows).isEmpty();
- }
-
- @Test
- public void fetchImmediately_testChannel() throws ExecutionException, InterruptedException {
- // The channels must be in the app package.
- // For this test the package is com.android.tv.data.epg
- insertTestChannels(
- "com.android.tv.data.epg/.tuner.TunerTvInputService", EpgTestData.CHANNEL_10);
- EpgFetcherImpl.FetchAsyncTask fetcherTask = mEpgFetcher.createFetchTask(null, null);
- fetcherTask.execute();
-
- assertThat(fetcherTask.get()).isNull();
- List<List<String>> rows =
- DbTestingUtils.toList(
- mContentResolver.query(
- TvContract.Programs.CONTENT_URI,
- PROGRAM_COLUMNS,
- null,
- null,
- null));
- assertThat(rows)
- .containsExactly(
- ImmutableList.of("1", "Program 1", "1496358000000", "1496359800000"));
- }
-
- @Test
- public void fetchImmediately_epgChannel() throws ExecutionException, InterruptedException {
- mTestApp.flagsModule.cloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Input");
- insertTestChannels("com.example/.Input", EpgTestData.CHANNEL_10, EpgTestData.CHANNEL_11);
- createTestEpgInput();
- EpgFetcherImpl.FetchAsyncTask fetcherTask = mEpgFetcher.createFetchTask(null, null);
- fetcherTask.execute();
-
- assertThat(fetcherTask.get()).isNull();
- List<List<String>> rows =
- DbTestingUtils.toList(
- mContentResolver.query(
- TvContract.Programs.CONTENT_URI,
- PROGRAM_COLUMNS,
- null,
- null,
- null));
- assertThat(rows)
- .containsExactly(
- ImmutableList.of("1", "Program 1", "1496358000000", "1496359800000"),
- ImmutableList.of("2", "Program 2", "1496359800000", "1496361600000"));
- }
-
- @Test
- public void testUpdateNetworkAffiliation() throws ExecutionException, InterruptedException {
- if (!TvFeatures.STORE_NETWORK_AFFILIATION.isEnabled(RuntimeEnvironment.application)) {
- return;
- }
- // set network affiliation to null so that it can be updated later
- Channel channel =
- new Channel.Builder(EpgTestData.CHANNEL_10).setNetworkAffiliation(null).build();
- // The channels must be in the app package.
- // For this test the package is com.android.tv.data.epg
- insertTestChannels("com.android.tv.data.epg/.tuner.TunerTvInputService", channel);
-
- List<List<String>> rows =
- DbTestingUtils.toList(
- mContentResolver.query(
- TvContract.Channels.CONTENT_URI,
- CHANNEL_COLUMNS,
- null,
- null,
- null));
- assertThat(rows).containsExactly(ImmutableList.of("Channel TEN", "10", "null"));
- EpgFetcherImpl.FetchAsyncTask fetcherTask = mEpgFetcher.createFetchTask(null, null);
- fetcherTask.execute();
-
- assertThat(fetcherTask.get()).isNull();
- rows =
- DbTestingUtils.toList(
- mContentResolver.query(
- TvContract.Channels.CONTENT_URI,
- CHANNEL_COLUMNS,
- null,
- null,
- null));
- // network affiliation should be updated
- assertThat(rows)
- .containsExactly(
- ImmutableList.of("Channel TEN", "10", "Channel 10 Network Affiliation"));
- }
-
- protected void insertTestChannels(String inputId, Channel... channels) {
-
- for (Channel channel : channels) {
- ContentValues values =
- new Channel.Builder(channel).setInputId(inputId).build().toContentValues();
- String packageName = inputId.substring(0, inputId.indexOf('/'));
- mTvProvider.setCallingPackage(packageName);
- mContentResolver.insert(TvContract.Channels.CONTENT_URI, values);
- mTvProvider.setCallingPackage("com.android.tv");
- }
- }
-
- private void createTestEpgInput() {
- // Use the database helper so we can set the package name.
- SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
- ContentValues values = new ContentValues();
- values.put(EpgContract.EpgInputs.COLUMN_ID, "1");
- values.put(EpgContract.EpgInputs.COLUMN_PACKAGE_NAME, "com.example");
- values.put(EpgContract.EpgInputs.COLUMN_INPUT_ID, "com.example/.Input");
- values.put(EpgContract.EpgInputs.COLUMN_LINEUP_ID, "lineup1");
- long rowId = db.insert("epg_input", null, values);
- assertThat(rowId).isEqualTo(1);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/data/epg/EpgInputWhiteListTest.java b/tests/robotests/src/com/android/tv/data/epg/EpgInputWhiteListTest.java
deleted file mode 100644
index d989b51f..00000000
--- a/tests/robotests/src/com/android/tv/data/epg/EpgInputWhiteListTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.data.epg;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.features.TvFeatures;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.common.flags.proto.TypedFeatures.StringListParam;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link EpgInputWhiteList}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class EpgInputWhiteListTest {
-
- private EpgInputWhiteList mWhiteList;
- private DefaultCloudEpgFlags mCloudEpgFlags;
- private DefaultLegacyFlags mLegacyFlags;
-
- @Before
- public void setup() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.enableForTest();
- mCloudEpgFlags = new DefaultCloudEpgFlags();
- mLegacyFlags = DefaultLegacyFlags.DEFAULT;
- mWhiteList = new EpgInputWhiteList(mCloudEpgFlags, mLegacyFlags);
- }
-
- @After
- public void after() {
- TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.resetForTests();
- }
-
- @Test
- public void isInputWhiteListed_noRemoteConfig() {
- assertThat(mWhiteList.isInputWhiteListed("com.example/.Foo")).isFalse();
- }
-
- @Test
- public void isInputWhiteListed_noMatch() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Bar");
- assertThat(mWhiteList.isInputWhiteListed("com.example/.Foo")).isFalse();
- }
-
- @Test
- public void isInputWhiteListed_match() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Foo");
- assertThat(mWhiteList.isInputWhiteListed("com.example/.Foo")).isTrue();
- }
-
- @Test
- public void isInputWhiteListed_matchWithTwo() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Foo,com.example/.Bar");
- assertThat(mWhiteList.isInputWhiteListed("com.example/.Foo")).isTrue();
- }
-
- @Test
- public void toInputSet_withNewLine() {
- assertThat(EpgInputWhiteList.toInputSet("com.example/.Foo,\ncom.example/.Bar\n"))
- .containsExactly("com.example/.Foo", "com.example/.Bar");
- }
-
- @Test
- public void toInputSet_withWhiteSpace() {
- assertThat(EpgInputWhiteList.toInputSet("com.example/.Foo , com.example/.Bar "))
- .containsExactly("com.example/.Foo", "com.example/.Bar");
- }
-
- @Test
- public void isPackageWhiteListed_noRemoteConfig() {
- assertThat(mWhiteList.isPackageWhiteListed("com.example")).isFalse();
- }
-
- @Test
- public void isPackageWhiteListed_noMatch() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Bar");
- assertThat(mWhiteList.isPackageWhiteListed("com.other")).isFalse();
- }
-
- @Test
- public void isPackageWhiteListed_match() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Foo");
- assertThat(mWhiteList.isPackageWhiteListed("com.example")).isTrue();
- }
-
- @Test
- public void isPackageWhiteListed_matchWithTwo() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example/.Foo,com.example/.Bar");
- assertThat(mWhiteList.isPackageWhiteListed("com.example")).isTrue();
- }
-
- @Test
- public void isPackageWhiteListed_matchBadInput() {
- mCloudEpgFlags.setThirdPartyEpgInputCsv("com.example.Foo");
- assertThat(mWhiteList.isPackageWhiteListed("com.example")).isFalse();
- }
-
- @Test
- public void isPackageWhiteListed_tunerInput() {
- EpgInputWhiteList whiteList =
- new EpgInputWhiteList(new DefaultCloudEpgFlags(), DefaultLegacyFlags.DEFAULT);
- assertThat(
- whiteList.isInputWhiteListed(
- "com.google.android.tv/.tuner.tvinput.TunerTvInputService"))
- .isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/BaseDvrDataManagerTest.java b/tests/robotests/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
deleted file mode 100644
index 8c3baadb..00000000
--- a/tests/robotests/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr;
-
-import android.os.Build;
-import android.support.annotation.NonNull;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.testing.fakes.FakeClock;
-
-import com.google.common.truth.Truth;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link BaseDvrDataManager} using {@link DvrDataManagerInMemoryImpl}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class BaseDvrDataManagerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
- private FakeClock mFakeClock;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithCurrentTime();
- mDvrDataManager =
- new DvrDataManagerInMemoryImpl(RuntimeEnvironment.application, mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testGetNonStartedScheduledRecordings() {
- ScheduledRecording recording =
- mDvrDataManager.addScheduledRecordingInternal(
- createNewScheduledRecordingStartingNow());
- List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings();
- Truth.assertThat(result).containsExactly(recording);
- }
-
- @Test
- public void testGetNonStartedScheduledRecordings_past() {
- mDvrDataManager.addScheduledRecordingInternal(createNewScheduledRecordingStartingNow());
- mFakeClock.increment(TimeUnit.MINUTES, 6);
- List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings();
- Truth.assertThat(result).isEmpty();
- }
-
- @NonNull
- private ScheduledRecording createNewScheduledRecordingStartingNow() {
- return ScheduledRecording.buildFrom(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- ScheduledRecording.ID_NOT_SET,
- INPUT_ID,
- CHANNEL_ID,
- mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)))
- .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)
- .build();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/DvrDataManagerImplTest.java b/tests/robotests/src/com/android/tv/dvr/DvrDataManagerImplTest.java
deleted file mode 100644
index 528e0233..00000000
--- a/tests/robotests/src/com/android/tv/dvr/DvrDataManagerImplTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Build;
-
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Tests for {@link DvrDataManagerImpl} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class DvrDataManagerImplTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- @Test
- public void testGetNextScheduledStartTimeAfter() {
- long id = 1;
- List<ScheduledRecording> scheduledRecordings = new ArrayList<>();
- assertNextStartTime(scheduledRecordings, 0L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 20L, 30L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, 20L);
- assertNextStartTime(scheduledRecordings, 20L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 30L, 40L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, 20L);
- assertNextStartTime(scheduledRecordings, 20L, 30L);
- assertNextStartTime(scheduledRecordings, 30L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.clear();
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- scheduledRecordings.add(
- RecordingTestUtils.createTestRecordingWithIdAndPeriod(
- id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- }
-
- private void assertNextStartTime(
- List<ScheduledRecording> scheduledRecordings, long startTime, long expected) {
- assertWithMessage("getNextScheduledStartTimeAfter()")
- .that(DvrDataManagerImpl.getNextStartTimeAfter(scheduledRecordings, startTime))
- .isEqualTo(expected);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/DvrScheduleManagerTest.java b/tests/robotests/src/com/android/tv/dvr/DvrScheduleManagerTest.java
deleted file mode 100644
index bd4113e4..00000000
--- a/tests/robotests/src/com/android/tv/dvr/DvrScheduleManagerTest.java
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.fail;
-
-import android.os.Build;
-import android.util.Range;
-
-import com.android.tv.dvr.DvrScheduleManager.ConflictInfo;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests for {@link DvrScheduleManager} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class DvrScheduleManagerTest {
- private static final String INPUT_ID = "input_id";
-
- @Test
- public void testGetConflictingSchedules_emptySchedule() {
- List<ScheduledRecording> schedules = new ArrayList<>();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedules_noConflict() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1)).isEmpty();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedules_noTuner() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 0)).isEmpty();
-
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 0)).isEqualTo(schedules);
- schedules.add(
- 0,
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 0)).isEqualTo(schedules);
- }
-
- @Test
- public void testGetConflictingSchedules_conflict() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1)).isEmpty();
-
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- ScheduledRecording r4 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r4);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
-
- ScheduledRecording r5 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r5);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
-
- ScheduledRecording r6 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 10L, 90L);
- schedules.add(r6);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4)).isEmpty();
-
- ScheduledRecording r7 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 110L, 190L);
- schedules.add(r7);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4)).isEmpty();
-
- ScheduledRecording r8 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 50L, 150L);
- schedules.add(r8);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r7, r6, r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 5)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedules_conflict2() {
- // The case when there is a long schedule.
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 1000L);
- schedules.add(r1);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1)).isEmpty();
-
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedules_reverseOrder() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(0, r1);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1)).isEmpty();
-
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(0, r2);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(0, r3);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2)).isEmpty();
-
- ScheduledRecording r4 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(0, r4);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
-
- ScheduledRecording r5 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(0, r5);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
-
- ScheduledRecording r6 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 10L, 90L);
- schedules.add(0, r6);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4)).isEmpty();
-
- ScheduledRecording r7 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 110L, 190L);
- schedules.add(0, r7);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4)).isEmpty();
-
- ScheduledRecording r8 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 50L, 150L);
- schedules.add(0, r8);
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r7, r6, r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 2))
- .containsExactly(r5, r4, r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3))
- .containsExactly(r3, r2, r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 4))
- .containsExactly(r1)
- .inOrder();
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 5)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedules_period1() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(10L, 20L))))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(110L, 120L))))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_period2() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(10L, 20L))))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(110L, 120L))))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_period3() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r3);
- ScheduledRecording r4 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r4);
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(10L, 20L))))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(110L, 120L))))
- .containsExactly(r2)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- schedules, 1, Collections.singletonList(new Range<>(50L, 150L))))
- .containsExactly(r2, r1)
- .inOrder();
- List<Range<Long>> ranges = new ArrayList<>();
- ranges.add(new Range<>(10L, 20L));
- ranges.add(new Range<>(110L, 120L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1, ranges))
- .containsExactly(r2, r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_addSchedules1() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L)
- .setPriority(++priority)
- .build()),
- schedules,
- 1))
- .containsExactly(r2, r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(
- INPUT_ID, ++channelId, 110L, 120L)
- .setPriority(++priority)
- .build()),
- schedules,
- 1))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_addSchedules2() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L)
- .setPriority(++priority)
- .build()),
- schedules,
- 1))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(
- INPUT_ID, ++channelId, 110L, 120L)
- .setPriority(++priority)
- .build()),
- schedules,
- 1))
- .containsExactly(r2, r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_addLowestPriority() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 400L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- // Returning r1 even though r1 has the higher priority than the new one. That's because r1
- // starts at 0 and stops at 100, and the new one will be recorded successfully.
- assertThat(
- DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(
- INPUT_ID, ++channelId, 200L, 300L)
- .setPriority(0)
- .build()),
- schedules,
- 1))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedules_sameChannel() {
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelId, ++priority, 0L, 200L));
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelId, ++priority, 0L, 200L));
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 3)).isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedule_startEarlyAndFail() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 200L, 300L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 400L);
- schedules.add(r2);
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- // r2 starts recording and fails when r3 starts. r1 is recorded successfully.
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r2)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedule_startLate() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 200L, 400L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 300L);
- schedules.add(r2);
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r3);
- // r2 and r1 are clipped.
- assertThat(DvrScheduleManager.getConflictingSchedules(schedules, 1))
- .containsExactly(r2, r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForTune_canTune() {
- // Can tune to the recorded channel if tuner count is 1.
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelId, ++priority, 0L, 200L));
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForTune(
- INPUT_ID, channelId, 0L, priority + 1, schedules, 1))
- .isEmpty();
- }
-
- @Test
- public void testGetConflictingSchedulesForTune_cannotTune() {
- // Can't tune to a channel if other channel is recording and tuner count is 1.
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelId, ++priority, 0L, 200L));
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForTune(
- INPUT_ID, channelId + 1, 0L, priority + 1, schedules, 1))
- .containsExactly(schedules.get(0))
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_otherChannels() {
- // The other channels are to be recorded.
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3))
- .isEmpty();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannel1() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2))
- .isEmpty();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1))
- .containsExactly(r2)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannel2() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2))
- .isEmpty();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1))
- .containsExactly(r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannelConflict1() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r3);
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3))
- .containsExactly(r2)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2))
- .containsExactly(r2)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1))
- .containsExactly(r2, r1)
- .inOrder();
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannelConflict2() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 =
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r3);
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2))
- .containsExactly(r1)
- .inOrder();
- assertThat(
- DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1))
- .containsExactly(r3, r1)
- .inOrder();
- }
-
- @Test
- public void testPartiallyConflictingSchedules() {
- long priority = 100;
- long channelId = 0;
- List<ScheduledRecording> schedules =
- new ArrayList<>(
- Arrays.asList(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 0L, 400L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 0L, 200L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 200L, 500L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 400L, 600L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 700L, 800L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 600L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 800L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 800L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 750L, 850L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 300L, 450L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, --priority, 50L, 900L)));
- List<ConflictInfo> conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 1);
-
- assertNotInList(schedules.get(0), conflicts);
- assertFullConflict(schedules.get(1), conflicts);
- assertPartialConflict(schedules.get(2), conflicts);
- assertPartialConflict(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertPartialConflict(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertFullConflict(schedules.get(7), conflicts);
- assertFullConflict(schedules.get(8), conflicts);
- assertFullConflict(schedules.get(9), conflicts);
- assertFullConflict(schedules.get(10), conflicts);
-
- conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 2);
-
- assertNotInList(schedules.get(0), conflicts);
- assertNotInList(schedules.get(1), conflicts);
- assertNotInList(schedules.get(2), conflicts);
- assertNotInList(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertNotInList(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertFullConflict(schedules.get(7), conflicts);
- assertFullConflict(schedules.get(8), conflicts);
- assertFullConflict(schedules.get(9), conflicts);
- assertPartialConflict(schedules.get(10), conflicts);
-
- conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 3);
-
- assertNotInList(schedules.get(0), conflicts);
- assertNotInList(schedules.get(1), conflicts);
- assertNotInList(schedules.get(2), conflicts);
- assertNotInList(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertNotInList(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertNotInList(schedules.get(7), conflicts);
- assertPartialConflict(schedules.get(8), conflicts);
- assertNotInList(schedules.get(9), conflicts);
- assertPartialConflict(schedules.get(10), conflicts);
- }
-
- private void assertNotInList(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- fail(schedule + " conflicts with others.");
- }
- }
- }
-
- private void assertPartialConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- if (conflictInfo.partialConflict) {
- return;
- } else {
- fail(schedule + " fully conflicts with others.");
- }
- }
- }
- fail(schedule + " doesn't conflict");
- }
-
- private void assertFullConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- if (!conflictInfo.partialConflict) {
- return;
- } else {
- fail(schedule + " partially conflicts with others.");
- }
- }
- }
- fail(schedule + " doesn't conflict");
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/ScheduledRecordingTest.java b/tests/robotests/src/com/android/tv/dvr/ScheduledRecordingTest.java
deleted file mode 100644
index 4c845c49..00000000
--- a/tests/robotests/src/com/android/tv/dvr/ScheduledRecordingTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr;
-
-import static com.android.tv.testing.dvr.RecordingTestUtils.createTestRecordingWithIdAndPeriod;
-import static com.android.tv.testing.dvr.RecordingTestUtils.normalizePriority;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Build;
-import android.util.Range;
-
-import com.android.tv.data.ChannelImpl;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests for {@link ScheduledRecordingTest} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class ScheduledRecordingTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- @Test
- public void testIsOverLapping() {
- ScheduledRecording r =
- createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L);
- assertOverLapping(false, 1L, 9L, r);
-
- assertOverLapping(true, 1L, 20L, r);
- assertOverLapping(false, 1L, 10L, r);
- assertOverLapping(true, 10L, 19L, r);
- assertOverLapping(true, 10L, 20L, r);
- assertOverLapping(true, 11L, 20L, r);
- assertOverLapping(true, 11L, 21L, r);
- assertOverLapping(false, 20L, 21L, r);
-
- assertOverLapping(false, 21L, 29L, r);
- }
-
- @Test
- public void testBuildProgram() {
- Channel c = new ChannelImpl.Builder().build();
- Program p = new ProgramImpl.Builder().build();
- ScheduledRecording actual =
- ScheduledRecording.builder(INPUT_ID, p).setChannelId(c.getId()).build();
- assertWithMessage("type").that(actual.getType()).isEqualTo(ScheduledRecording.TYPE_PROGRAM);
- }
-
- @Test
- public void testBuildTime() {
- ScheduledRecording actual =
- createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L);
- assertWithMessage("type").that(actual.getType()).isEqualTo(ScheduledRecording.TYPE_TIMED);
- }
-
- @Test
- public void testBuildFrom() {
- ScheduledRecording expected =
- createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L);
- ScheduledRecording actual = ScheduledRecording.buildFrom(expected).build();
- RecordingTestUtils.assertRecordingEquals(expected, actual);
- }
-
- @Test
- public void testBuild_priority() {
- ScheduledRecording a =
- normalizePriority(
- createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L));
- ScheduledRecording b =
- normalizePriority(
- createTestRecordingWithIdAndPeriod(2, INPUT_ID, CHANNEL_ID, 10L, 20L));
- ScheduledRecording c =
- normalizePriority(
- createTestRecordingWithIdAndPeriod(3, INPUT_ID, CHANNEL_ID, 10L, 20L));
-
- // default priority
- assertThat(sortByPriority(c, b, a)).containsExactly(a, b, c).inOrder();
-
- // make A preferred over B
- a = ScheduledRecording.buildFrom(a).setPriority(b.getPriority() + 2).build();
- assertThat(sortByPriority(a, b, c)).containsExactly(b, c, a).inOrder();
- }
-
- public Collection<ScheduledRecording> sortByPriority(
- ScheduledRecording a, ScheduledRecording b, ScheduledRecording c) {
- List<ScheduledRecording> list = Arrays.asList(a, b, c);
- Collections.sort(list, ScheduledRecording.PRIORITY_COMPARATOR);
- return list;
- }
-
- private void assertOverLapping(boolean expected, long lower, long upper, ScheduledRecording r) {
- assertWithMessage("isOverlapping(Range(" + lower + "," + upper + "), recording " + r)
- .that(r.isOverLapping(new Range<>(lower, upper)))
- .isEqualTo(expected);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/data/SeriesRecordingTest.java b/tests/robotests/src/com/android/tv/dvr/data/SeriesRecordingTest.java
deleted file mode 100644
index a0b79cef..00000000
--- a/tests/robotests/src/com/android/tv/dvr/data/SeriesRecordingTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.data;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Parcel;
-
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link SeriesRecording}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SeriesRecordingTest {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long OTHER_CHANNEL_ID = 321;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String OTHER_SERIES_ID = "OTHER_SERIES_ID";
-
- private final SeriesRecording mBaseSeriesRecording =
- new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID)
- .setSeriesId(SERIES_ID)
- .build();
- private final SeriesRecording mSeriesRecordingSeason2 =
- SeriesRecording.buildFrom(mBaseSeriesRecording).setStartFromSeason(2).build();
- private final SeriesRecording mSeriesRecordingSeason2Episode5 =
- SeriesRecording.buildFrom(mSeriesRecordingSeason2).setStartFromEpisode(5).build();
- private final ProgramImpl mBaseProgram =
- new ProgramImpl.Builder()
- .setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID)
- .setSeriesId(SERIES_ID)
- .build();
-
- @Test
- public void testParcelable() {
- SeriesRecording r1 =
- new SeriesRecording.Builder()
- .setId(1)
- .setChannelId(2)
- .setPriority(3)
- .setTitle("4")
- .setDescription("5")
- .setLongDescription("5-long")
- .setSeriesId("6")
- .setStartFromEpisode(7)
- .setStartFromSeason(8)
- .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
- .setCanonicalGenreIds(new int[] {9, 10})
- .setPosterUri("11")
- .setPhotoUri("12")
- .build();
- Parcel p1 = Parcel.obtain();
- Parcel p2 = Parcel.obtain();
- try {
- r1.writeToParcel(p1, 0);
- byte[] bytes = p1.marshall();
- p2.unmarshall(bytes, 0, bytes.length);
- p2.setDataPosition(0);
- SeriesRecording r2 = SeriesRecording.fromParcel(p2);
- assertThat(r2).isEqualTo(r1);
- } finally {
- p1.recycle();
- p2.recycle();
- }
- }
-
- @Test
- public void testDoesProgramMatch_simpleMatch() {
- assertDoesProgramMatch(mBaseProgram, mBaseSeriesRecording, true);
- }
-
- @Test
- public void testDoesProgramMatch_differentSeriesId() {
- Program program =
- new ProgramImpl.Builder(mBaseProgram).setSeriesId(OTHER_SERIES_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- @Test
- public void testDoesProgramMatch_differentChannel() {
- Program program =
- new ProgramImpl.Builder(mBaseProgram).setChannelId(OTHER_CHANNEL_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- @Test
- public void testDoesProgramMatch_startFromSeason2() {
- ProgramImpl program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new ProgramImpl.Builder(program).setSeasonNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, false);
- program = new ProgramImpl.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new ProgramImpl.Builder(program).setSeasonNumber("3").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- }
-
- @Test
- public void testDoesProgramMatch_startFromSeason2episode5() {
- ProgramImpl program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new ProgramImpl.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new ProgramImpl.Builder(program).setEpisodeNumber("4").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, false);
- program = new ProgramImpl.Builder(program).setEpisodeNumber("5").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new ProgramImpl.Builder(program).setEpisodeNumber("6").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program =
- new ProgramImpl.Builder(program).setSeasonNumber("3").setEpisodeNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- }
-
- private void assertDoesProgramMatch(
- Program p, SeriesRecording seriesRecording, boolean expected) {
- assertWithMessage(seriesRecording + " doesProgramMatch " + p)
- .that(seriesRecording.matchProgram(p))
- .isEqualTo(expected);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/provider/DvrDbSyncTest.java b/tests/robotests/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
deleted file mode 100644
index 5f8db0ad..00000000
--- a/tests/robotests/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.provider;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.WritableDvrDataManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.util.concurrent.RoboExecutorService;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link com.android.tv.dvr.DvrScheduleManager} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class DvrDbSyncTest {
- private static final String INPUT_ID = "input_id";
- private static final long BASE_PROGRAM_ID = 1;
- private static final long BASE_START_TIME_MS = 0;
- private static final long BASE_END_TIME_MS = 1;
- private static final String BASE_SEASON_NUMBER = "2";
- private static final String BASE_EPISODE_NUMBER = "3";
- private ProgramImpl baseProgram;
- private ProgramImpl baseSeriesProgram;
- private ScheduledRecording baseSchedule;
- private ScheduledRecording baseSeriesSchedule;
-
- private DvrDbSync mDbSync;
- @Mock private DvrManager mDvrManager;
- @Mock private WritableDvrDataManager mDataManager;
- @Mock private ChannelDataManager mChannelDataManager;
- @Mock private SeriesRecordingScheduler mSeriesRecordingScheduler;
-
- @Before
- public void setUp() {
- // TODO(b/69843199): make these static finals
- baseProgram =
- new ProgramImpl.Builder()
- .setId(BASE_PROGRAM_ID)
- .setStartTimeUtcMillis(BASE_START_TIME_MS)
- .setEndTimeUtcMillis(BASE_END_TIME_MS)
- .build();
- baseSeriesProgram =
- new ProgramImpl.Builder()
- .setId(BASE_PROGRAM_ID)
- .setStartTimeUtcMillis(BASE_START_TIME_MS)
- .setEndTimeUtcMillis(BASE_END_TIME_MS)
- .setSeasonNumber(BASE_SEASON_NUMBER)
- .setEpisodeNumber(BASE_EPISODE_NUMBER)
- .build();
- baseSchedule = ScheduledRecording.builder(INPUT_ID, baseProgram).build();
- baseSeriesSchedule = ScheduledRecording.builder(INPUT_ID, baseSeriesProgram).build();
-
- MockitoAnnotations.initMocks(this);
- when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- when(mDvrManager.addSeriesRecording(any(), any(), anyInt()))
- .thenReturn(SeriesRecording.builder(INPUT_ID, baseProgram).build());
- mDbSync =
- new DvrDbSync(
- RuntimeEnvironment.application.getApplicationContext(),
- mDataManager,
- mChannelDataManager,
- mDvrManager,
- mSeriesRecordingScheduler,
- new RoboExecutorService());
- }
-
- @Test
- public void testHandleUpdateProgram_null() {
- addSchedule(BASE_PROGRAM_ID, baseSchedule);
- mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID);
- verify(mDataManager).removeScheduledRecording(baseSchedule);
- }
-
- @Test
- public void testHandleUpdateProgram_changeTimeNotStarted() {
- addSchedule(BASE_PROGRAM_ID, baseSchedule);
- long startTimeMs = BASE_START_TIME_MS + 1;
- long endTimeMs = BASE_END_TIME_MS + 1;
- Program program =
- new ProgramImpl.Builder(baseProgram)
- .setStartTimeUtcMillis(startTimeMs)
- .setEndTimeUtcMillis(endTimeMs)
- .build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- @Test
- public void testHandleUpdateProgram_changeTimeInProgressNotCalled() {
- addSchedule(
- BASE_PROGRAM_ID,
- ScheduledRecording.buildFrom(baseSchedule)
- .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS)
- .build());
- long startTimeMs = BASE_START_TIME_MS + 1;
- Program program =
- new ProgramImpl.Builder(baseProgram).setStartTimeUtcMillis(startTimeMs).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(any());
- }
-
- @Test
- public void testHandleUpdateProgram_changeSeason() {
- addSchedule(BASE_PROGRAM_ID, baseSeriesSchedule);
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program =
- new ProgramImpl.Builder(baseSeriesProgram)
- .setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber)
- .build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- @Test
- public void testHandleUpdateProgram_finished() {
- addSchedule(
- BASE_PROGRAM_ID,
- ScheduledRecording.buildFrom(baseSeriesSchedule)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED)
- .build());
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program =
- new ProgramImpl.Builder(baseSeriesProgram)
- .setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber)
- .build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(any());
- }
-
- private void addSchedule(long programId, ScheduledRecording schedule) {
- when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule);
- }
-
- private void assertUpdateScheduleCalled(Program program) {
- verify(mDataManager)
- .updateScheduledRecording(
- eq(ScheduledRecording.builder(INPUT_ID, program).build()));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java b/tests/robotests/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
deleted file mode 100644
index 3597342d..00000000
--- a/tests/robotests/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.provider;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build.VERSION_CODES;
-
-import com.android.tv.dvr.data.SeasonEpisodeNumber;
-import com.android.tv.testing.TestSingletonApp;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Tests for {@link EpisodicProgramLoadTask} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = VERSION_CODES.N, application = TestSingletonApp.class)
-public class EpisodicProgramLoadTaskTest {
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final long SERIES_RECORDING_ID2 = 2;
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- @Test
- public void testEpisodeAlreadyScheduled_true() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber =
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertThat(seasonEpisodeNumbers)
- .contains(
- new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1));
- }
-
- @Test
- public void testEpisodeAlreadyScheduled_false() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber =
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(
- new SeasonEpisodeNumber(
- SERIES_RECORDING_ID2, SEASON_NUMBER1, EPISODE_NUMBER1));
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(
- new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER2, EPISODE_NUMBER1));
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(
- new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER2));
- }
-
- @Test
- public void testEpisodeAlreadyScheduled_null() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber =
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, EPISODE_NUMBER1));
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, null));
- assertThat(seasonEpisodeNumbers)
- .doesNotContain(new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, null));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java b/tests/robotests/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
deleted file mode 100644
index 40069f62..00000000
--- a/tests/robotests/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.recorder;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.media.tv.TvInputInfo;
-import android.os.Build;
-import android.os.Looper;
-import android.os.SystemClock;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.common.util.Clock;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.api.Channel;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.WritableDvrDataManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.recorder.InputTaskScheduler.RecordingTaskFactory;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.testing.fakes.FakeClock;
-import com.android.tv.testing.utils.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link InputTaskScheduler}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class InputTaskSchedulerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 1;
- private static final long LISTENER_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
- private static final int TUNER_COUNT_ONE = 1;
- private static final int TUNER_COUNT_TWO = 2;
- private static final long LOW_PRIORITY = 1;
- private static final long HIGH_PRIORITY = 2;
-
- private FakeClock mFakeClock;
- private InputTaskScheduler mScheduler;
- @Mock private DvrManager mDvrManager;
- @Mock private WritableDvrDataManager mDataManager;
- @Mock private InputSessionManager mSessionManager;
- @Mock private AlarmManager mMockAlarmManager;
- @Mock private ChannelDataManager mChannelDataManager;
- private List<RecordingTask> mRecordingTasks;
-
- @Before
- public void setUp() throws Exception {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- mRecordingTasks = new ArrayList();
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_ONE);
- mScheduler =
- new InputTaskScheduler(
- RuntimeEnvironment.application,
- input,
- Looper.myLooper(),
- mChannelDataManager,
- mDvrManager,
- mDataManager,
- mSessionManager,
- mFakeClock,
- new RecordingTaskFactory() {
- @Override
- public RecordingTask createRecordingTask(
- ScheduledRecording scheduledRecording,
- Channel channel,
- DvrManager dvrManager,
- InputSessionManager sessionManager,
- WritableDvrDataManager dataManager,
- Clock clock) {
- RecordingTask task = mock(RecordingTask.class);
- when(task.getPriority())
- .thenReturn(scheduledRecording.getPriority());
- when(task.getEndTimeMs())
- .thenReturn(scheduledRecording.getEndTimeMs());
- mRecordingTasks.add(task);
- return task;
- }
- });
- }
-
- @Test
- public void testAddSchedule_past() {
- ScheduledRecording r =
- RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, 0L, 1L);
- when(mDataManager.getScheduledRecording(anyLong())).thenReturn(r);
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- verify(mDataManager, timeout((int) LISTENER_TIMEOUT_MS).times(1))
- .changeState(
- any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED),
- eq(
- ScheduledRecording
- .FAILED_REASON_PROGRAM_ENDED_BEFORE_RECORDING_STARTED));
- }
-
- @Test
- public void testAddSchedule_start() {
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID,
- CHANNEL_ID,
- mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- }
-
- @Test
- public void testAddSchedule_consecutiveNoStop() {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- // The first schedule should not be stopped because the second one should wait for the end
- // of the first schedule.
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- }
-
- @Test
- public void testAddSchedule_consecutiveNoFail() {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- when(mDataManager.getScheduledRecording(anyLong()))
- .thenReturn(ScheduledRecording.builder(INPUT_ID, CHANNEL_ID, 0L, 0L).build());
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- // The second schedule should not fail because it can starts after the first one finishes.
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mDataManager, never())
- .changeState(
- any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED));
- }
-
- @Test
- public void testAddSchedule_consecutiveUseLessSession() throws Exception {
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_TWO);
- mScheduler.updateTvInputInfo(input);
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(
- ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- // The second schedule should wait until the first one finishes rather than creating a new
- // session even though there are available tuners.
- assertTrue(mRecordingTasks.size() == 1);
- }
-
- @Test
- public void testUpdateSchedule_noCancel() {
- ScheduledRecording r =
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID,
- CHANNEL_ID,
- mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(r);
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).cancel();
- }
-
- @Test
- public void testUpdateSchedule_cancel() {
- ScheduledRecording r =
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID,
- CHANNEL_ID,
- mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(2));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(
- ScheduledRecording.buildFrom(r)
- .setStartTimeMs(mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))
- .build());
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).cancel();
- }
-
- private TvInputInfo createTvInputInfo(int tunerCount) throws Exception {
- return TestUtils.createTvInputInfo(null, null, null, 0, false, true, tunerCount);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/recorder/RecordingTaskTest.java b/tests/robotests/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
deleted file mode 100644
index 55ee270c..00000000
--- a/tests/robotests/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.recorder;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.InputSessionManager.RecordingSession;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.ChannelImpl;
-import com.android.tv.data.api.Channel;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.recorder.RecordingTask.State;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.testing.fakes.FakeClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link RecordingTask}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class RecordingTaskTest {
- private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
- private static final long START_OFFSET_MS = RecordingScheduler.MS_TO_WAKE_BEFORE_START;
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- @Mock Handler mMockHandler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mMockSessionManager;
- @Mock RecordingSession mMockRecordingSession;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(RuntimeEnvironment.application, mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testHandle_init() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(
- eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong()))
- .thenReturn(mMockRecordingSession);
- when(mMockHandler.sendMessageAtTime(any(), anyLong())).thenReturn(true);
- assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)));
- assertEquals(State.CONNECTION_PENDING, task.getState());
- verify(mMockSessionManager)
- .createRecordingSession(
- eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong());
- verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri()));
- verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager);
- }
-
- private static Channel createTestChannel() {
- return new ChannelImpl.Builder()
- .setInputId(INPUT_ID)
- .setId(CHANNEL_ID)
- .setDisplayName("Test Ch " + CHANNEL_ID)
- .build();
- }
-
- @Test
- public void testOnConnected() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- mDataManager.addScheduledRecording(r);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(
- eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong()))
- .thenReturn(mMockRecordingSession);
- when(mMockHandler.sendEmptyMessageDelayed(anyInt(), anyLong())).thenReturn(true);
- task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE));
- task.onTuned(channel.getUri());
- assertEquals(State.CONNECTED, task.getState());
- }
-
- private ScheduledRecording createRecording(Channel c) {
- long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS;
- long endTime = startTime + DURATION;
- return RecordingTestUtils.createTestRecordingWithPeriod(
- c.getInputId(), c.getId(), startTime, endTime);
- }
-
- private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
- RecordingTask recordingTask =
- new RecordingTask(
- RuntimeEnvironment.application,
- r,
- channel,
- mDvrManager,
- mMockSessionManager,
- mDataManager,
- mFakeClock);
- recordingTask.setHandler(mMockHandler);
- return recordingTask;
- }
-
- private Message createMessage(int what) {
- Message msg = new Message();
- msg.setTarget(mMockHandler);
- msg.what = what;
- return msg;
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java b/tests/robotests/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
deleted file mode 100644
index 945c031f..00000000
--- a/tests/robotests/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.recorder;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertTrue;
-
-import android.os.Build;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.common.util.CommonUtils;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.testing.fakes.FakeClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link ScheduledProgramReaper}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class ScheduledProgramReaperTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
- private static final long DURATION = TimeUnit.HOURS.toMillis(1);
-
- private ScheduledProgramReaper mReaper;
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
- @Mock private DvrManager mDvrManager;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithTimeOne();
- mDvrDataManager =
- new DvrDataManagerInMemoryImpl(RuntimeEnvironment.application, mFakeClock);
- mReaper = new ScheduledProgramReaper(mDvrDataManager, mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testRun_noRecordings() {
- assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
- mReaper.run();
- assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
- }
-
- @Test
- public void testRun_oneRecordingsTomorrow() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- mReaper.run();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- }
-
- @Test
- public void testRun_oneRecordingsStarted() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mReaper.run();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- }
-
- @Test
- public void testRun_oneRecordingsFinished() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mFakeClock.increment(TimeUnit.MINUTES, 2);
- mReaper.run();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- }
-
- @Test
- public void testRun_oneRecordingsExpired() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- assertThat(mDvrDataManager.getAllScheduledRecordings()).containsExactly(recording);
- mFakeClock.increment(TimeUnit.DAYS, 1 + ScheduledProgramReaper.DAYS);
- mFakeClock.increment(TimeUnit.MILLISECONDS, DURATION);
- // After the cutoff and enough so we can see on the clock
- mFakeClock.increment(TimeUnit.SECONDS, 1);
-
- mReaper.run();
- assertTrue(
- "Recordings after reaper at "
- + CommonUtils.toIsoDateTimeString(mFakeClock.currentTimeMillis()),
- mDvrDataManager.getAllScheduledRecordings().isEmpty());
- }
-
- private ScheduledRecording addNewScheduledRecordingForTomorrow() {
- long startTime = mFakeClock.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);
- ScheduledRecording recording =
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID, CHANNEL_ID, startTime, startTime + DURATION);
- return mDvrDataManager.addScheduledRecordingInternal(
- ScheduledRecording.buildFrom(recording)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED)
- .build());
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/recorder/SchedulerTest.java b/tests/robotests/src/com/android/tv/dvr/recorder/SchedulerTest.java
deleted file mode 100644
index d2bd2ff1..00000000
--- a/tests/robotests/src/com/android/tv/dvr/recorder/SchedulerTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.recorder;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.os.Build;
-import android.os.Looper;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.testing.fakes.FakeClock;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link RecordingScheduler}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class SchedulerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- private RecordingScheduler mScheduler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mSessionManager;
- @Mock AlarmManager mMockAlarmManager;
- @Mock ChannelDataManager mChannelDataManager;
- @Mock TvInputManagerHelper mInputManager;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(RuntimeEnvironment.application, mFakeClock);
- Mockito.when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- mScheduler =
- new RecordingScheduler(
- Looper.myLooper(),
- mDvrManager,
- mSessionManager,
- mDataManager,
- mChannelDataManager,
- mInputManager,
- RuntimeEnvironment.application,
- mFakeClock,
- mMockAlarmManager);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testUpdate_none() {
- mScheduler.updateAndStartServiceIfNeeded();
- verifyZeroInteractions(mMockAlarmManager);
- }
-
- @Test
- public void testUpdate_nextIn12Hours() {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + TimeUnit.HOURS.toMillis(12);
- ScheduledRecording r =
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID, CHANNEL_ID, startTime, startTime + TimeUnit.HOURS.toMillis(1));
- mDataManager.addScheduledRecording(r);
- verify(mMockAlarmManager)
- .setExactAndAllowWhileIdle(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- Mockito.reset(mMockAlarmManager);
- mScheduler.updateAndStartServiceIfNeeded();
- verify(mMockAlarmManager)
- .setExactAndAllowWhileIdle(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- }
-
- @Test
- public void testStartsWithin() {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + 3;
- ScheduledRecording r =
- RecordingTestUtils.createTestRecordingWithPeriod(
- INPUT_ID, CHANNEL_ID, startTime, startTime + 100);
- assertFalse(mScheduler.startsWithin(r, 2));
- assertTrue(mScheduler.startsWithin(r, 3));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java b/tests/robotests/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
deleted file mode 100644
index dc4f4db4..00000000
--- a/tests/robotests/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.recorder;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build;
-import android.util.LongSparseArray;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.fakes.FakeClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests for {@link SeriesRecordingScheduler} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.N, application = TestSingletonApp.class)
-public class SeriesRecordingSchedulerTest {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- private final SeriesRecording mBaseSeriesRecording =
- new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID)
- .setSeriesId(SERIES_ID)
- .build();
- private final ProgramImpl mBaseProgram =
- new ProgramImpl.Builder()
- .setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID)
- .setSeriesId(SERIES_ID)
- .build();
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- private DvrDataManagerInMemoryImpl mDataManager;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- FakeClock fakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(RuntimeEnvironment.application, fakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testPickOneProgramPerEpisode_onePerEpisode() {
- SeriesRecording seriesRecording =
- SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 =
- new ProgramImpl.Builder(mBaseProgram)
- .setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1)
- .build();
- programs.add(program1);
- Program program2 =
- new ProgramImpl.Builder(mBaseProgram)
- .setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2)
- .build();
- programs.add(program2);
- LongSparseArray<List<Program>> result =
- SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- assertThat(result.get(SERIES_RECORDING_ID1)).containsExactly(program1, program2);
- }
-
- @Test
- public void testPickOneProgramPerEpisode_manyPerEpisode() {
- SeriesRecording seriesRecording =
- SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- ProgramImpl program1 =
- new ProgramImpl.Builder(mBaseProgram)
- .setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1)
- .setStartTimeUtcMillis(0)
- .build();
- programs.add(program1);
- Program program2 = new ProgramImpl.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- Program program3 =
- new ProgramImpl.Builder(mBaseProgram)
- .setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2)
- .build();
- programs.add(program3);
- Program program4 = new ProgramImpl.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program4);
- LongSparseArray<List<Program>> result =
- SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- assertThat(result.get(SERIES_RECORDING_ID1)).containsExactly(program1, program3);
- }
-
- @Test
- public void testPickOneProgramPerEpisode_nullEpisode() {
- SeriesRecording seriesRecording =
- SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new ProgramImpl.Builder(mBaseProgram).setStartTimeUtcMillis(0).build();
- programs.add(program1);
- Program program2 = new ProgramImpl.Builder(mBaseProgram).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- LongSparseArray<List<Program>> result =
- SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- assertThat(result.get(SERIES_RECORDING_ID1)).containsExactly(program1, program2);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java b/tests/robotests/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
deleted file mode 100644
index aa90d413..00000000
--- a/tests/robotests/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.ObjectAdapter;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Objects;
-
-/** Tests for {@link SortedArrayAdapter}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SortedArrayAdapterTest {
- public static final TestData P1 = TestData.create(1, "c");
- public static final TestData P2 = TestData.create(2, "b");
- public static final TestData P3 = TestData.create(3, "a");
- public static final TestData EXTRA = TestData.create(4, "k");
- private TestSortedArrayAdapter mAdapter;
-
- @Before
- public void setUp() {
- mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, null);
- }
-
- @Test
- public void testContents_empty() {
- assertEmpty();
- }
-
- @Test
- public void testAdd_one() {
- mAdapter.add(P1);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P1);
- }
-
- @Test
- public void testAdd_two() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- }
-
- @Test
- public void testSetInitialItems_two() {
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- }
-
- @Test
- public void testMaxInitialCount() {
- mAdapter = new TestSortedArrayAdapter(1, null);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertThat(mAdapter.size()).isEqualTo(1);
- assertThat(mAdapter.get(0)).isEqualTo(P2);
- }
-
- @Test
- public void testExtraItem() {
- mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, EXTRA);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertThat(mAdapter.size()).isEqualTo(3);
- assertThat(mAdapter.get(0)).isEqualTo(P2);
- assertThat(mAdapter.get(2)).isEqualTo(EXTRA);
- mAdapter.remove(P2);
- mAdapter.remove(P1);
- assertThat(mAdapter.size()).isEqualTo(1);
- assertThat(mAdapter.get(0)).isEqualTo(EXTRA);
- }
-
- @Test
- public void testExtraItemWithMaxCount() {
- mAdapter = new TestSortedArrayAdapter(1, EXTRA);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertThat(mAdapter.size()).isEqualTo(2);
- assertThat(mAdapter.get(0)).isEqualTo(P2);
- assertThat(mAdapter.get(1)).isEqualTo(EXTRA);
- mAdapter.remove(P2);
- assertThat(mAdapter.size()).isEqualTo(1);
- assertThat(mAdapter.get(0)).isEqualTo(EXTRA);
- }
-
- @Test
- public void testRemove() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.remove(P3);
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.remove(P2);
- assertContentsInOrder(mAdapter, P1);
- mAdapter.remove(P1);
- assertEmpty();
- mAdapter.add(P1);
- mAdapter.add(P2);
- mAdapter.add(P3);
- assertContentsInOrder(mAdapter, P3, P2, P1);
- mAdapter.removeItems(0, 2);
- assertContentsInOrder(mAdapter, P1);
- mAdapter.add(P2);
- mAdapter.add(P3);
- mAdapter.addExtraItem(EXTRA);
- assertContentsInOrder(mAdapter, P3, P2, P1, EXTRA);
- mAdapter.removeItems(1, 1);
- assertContentsInOrder(mAdapter, P3, P1, EXTRA);
- mAdapter.removeItems(1, 2);
- assertContentsInOrder(mAdapter, P3);
- mAdapter.addExtraItem(EXTRA);
- mAdapter.addExtraItem(P2);
- mAdapter.add(P1);
- assertContentsInOrder(mAdapter, P3, P1, EXTRA, P2);
- mAdapter.removeItems(1, 2);
- assertContentsInOrder(mAdapter, P3, P2);
- mAdapter.add(P1);
- assertContentsInOrder(mAdapter, P3, P1, P2);
- }
-
- @Test
- public void testReplace() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.replace(1, P3);
- assertContentsInOrder(mAdapter, P3, P2);
- mAdapter.replace(0, P1);
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.addExtraItem(EXTRA);
- assertContentsInOrder(mAdapter, P2, P1, EXTRA);
- mAdapter.replace(2, P3);
- assertContentsInOrder(mAdapter, P2, P1, P3);
- }
-
- @Test
- public void testChange_sorting() {
- TestData p2_changed = TestData.create(2, "z changed");
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.change(p2_changed);
- assertContentsInOrder(mAdapter, P1, p2_changed);
- }
-
- @Test
- public void testChange_new() {
- mAdapter.change(P1);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P1);
- }
-
- private void assertEmpty() {
- assertWithMessage("empty").that(mAdapter.isEmpty()).isTrue();
- }
-
- private void assertNotEmpty() {
- assertWithMessage("empty").that(mAdapter.isEmpty()).isFalse();
- }
-
- private static void assertContentsInOrder(ObjectAdapter adapter, Object... contents) {
- int ex = contents.length;
- assertWithMessage("size").that(adapter.size()).isEqualTo(ex);
- for (int i = 0; i < ex; i++) {
- assertWithMessage("element " + 1).that(adapter.get(i)).isEqualTo(contents[i]);
- }
- }
-
- private static class TestData {
- @Override
- public String toString() {
- return "TestData[" + mId + "]{" + mText + '}';
- }
-
- static TestData create(long first, String text) {
- return new TestData(first, text);
- }
-
- private final long mId;
- private final String mText;
-
- private TestData(long id, String second) {
- this.mId = id;
- this.mText = second;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof TestData)) return false;
- TestData that = (TestData) o;
- return mId == that.mId && Objects.equals(mText, that.mText);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mId, mText);
- }
- }
-
- private static class TestSortedArrayAdapter extends SortedArrayAdapter<TestData> {
-
- private static final Comparator<TestData> TEXT_COMPARATOR =
- new Comparator<TestData>() {
- @Override
- public int compare(TestData lhs, TestData rhs) {
- return lhs.mText.compareTo(rhs.mText);
- }
- };
-
- TestSortedArrayAdapter(int maxInitialCount, Object extra) {
- super(new ClassPresenterSelector(), TEXT_COMPARATOR, maxInitialCount);
- if (extra != null) {
- addExtraItem((TestData) extra);
- }
- }
-
- @Override
- protected long getId(TestData item) {
- return item.mId;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/ui/browse/DvrBrowseFragmentTest.java b/tests/robotests/src/com/android/tv/dvr/ui/browse/DvrBrowseFragmentTest.java
deleted file mode 100644
index 25a4256f..00000000
--- a/tests/robotests/src/com/android/tv/dvr/ui/browse/DvrBrowseFragmentTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui.browse;
-
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.ComparatorTester;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Test for {@link DvrBrowseFragment}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class DvrBrowseFragmentTest {
-
- @Test
- public void testRecentRowComparator_scheduledRecordings_latestFirst() {
- ComparatorTester comparatorTester =
- new ComparatorTester(DvrBrowseFragment.RECENT_ROW_COMPARATOR)
- .permitInconsistencyWithEquals();
- // priority (highest to lowest): start time, class, ID
- comparatorTester.addEqualityGroup(buildRecordedProgramForTest(2, 120, 150));
- comparatorTester.addEqualityGroup(buildRecordedProgramForTest(1, 120, 150));
- comparatorTester.addEqualityGroup(buildScheduledRecordingForTest(1, 120, 150));
- comparatorTester.addEqualityGroup(buildScheduledRecordingForTest(2, 120, 150));
- comparatorTester.addEqualityGroup(buildRecordedProgramForTest(4, 100, 200));
- comparatorTester.addEqualityGroup(buildRecordedProgramForTest(3, 100, 200));
- comparatorTester.addEqualityGroup(buildScheduledRecordingForTest(3, 100, 200));
- comparatorTester.addEqualityGroup(buildScheduledRecordingForTest(4, 100, 200));
- comparatorTester.addEqualityGroup(new Object(), Long.valueOf("777"), "string");
- comparatorTester.testCompare();
- }
-
- private ScheduledRecording buildScheduledRecordingForTest(long id, long start, long end) {
- return ScheduledRecording.builder("test", 1, start, end).setId(id).build();
- }
-
- private RecordedProgram buildRecordedProgramForTest(long id, long start, long end) {
- return RecordedProgram.builder()
- .setId(id)
- .setInputId("test")
- .setStartTimeUtcMillis(start)
- .setEndTimeUtcMillis(end)
- .build();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapterTest.java b/tests/robotests/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapterTest.java
deleted file mode 100644
index 5d247e37..00000000
--- a/tests/robotests/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapterTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui.list;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-
-import com.android.tv.common.flags.impl.DefaultUiFlags;
-import com.android.tv.common.util.Clock;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.testing.fakes.FakeClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Test for {@link DvrHistoryRowAdapter}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class DvrHistoryRowAdapterTest {
-
- private static final ScheduledRecording SCHEDULE_1 =
- buildScheduledRecordingForTest(
- 2,
- 1518249600000L, // 2/10/2018 0:00 PST
- 1518250600000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- private static final ScheduledRecording SCHEDULE_1_COPY =
- buildScheduledRecordingForTest(
- 3,
- 1518249600000L, // 2/10/2018 0:00 PST
- 1518250600000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- private static final ScheduledRecording SCHEDULE_2 =
- buildScheduledRecordingForTest(
- 4,
- 1518595200000L, // 2/14/2018 0:00 PST
- 1518596200000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- private static final ScheduledRecording SCHEDULE_2_COPY =
- buildScheduledRecordingForTest(
- 5,
- 1518595200000L, // 2/14/2018 0:00 PST
- 1518596200000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
-
- private static RecordedProgram sRecordedProgram;
- private static final long FAKE_CURRENT_TIME = 1518764400000L; // 2/15/2018 23:00 PST
-
- private DvrHistoryRowAdapter mDvrHistoryRowAdapter;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
-
- @Before
- public void setUp() {
- sRecordedProgram =
- buildRecordedProgramForTest(
- 6,
- 1518249600000L, // 2/10/2018 0:00 PST
- 1518250600000L);
-
- TestSingletonApp app = (TestSingletonApp) RuntimeEnvironment.application;
- Clock clock = FakeClock.createWithTime(FAKE_CURRENT_TIME);
-
- mDvrDataManager = new DvrDataManagerInMemoryImpl(app, clock);
- app.mDvrDataManager = mDvrDataManager;
- // keep the original IDs instead of creating a new one.
- mDvrDataManager.addScheduledRecording(
- true, SCHEDULE_1, SCHEDULE_1_COPY, SCHEDULE_2, SCHEDULE_2_COPY);
-
- ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
- mDvrHistoryRowAdapter =
- new DvrHistoryRowAdapter(
- RuntimeEnvironment.application,
- presenterSelector,
- clock,
- mDvrDataManager,
- new DefaultUiFlags());
- }
-
- @Test
- public void testStart() {
- mDvrHistoryRowAdapter.start();
- assertInitialState();
- }
-
- @Test
- public void testOnScheduledRecordingAdded_existingHeader() {
- mDvrHistoryRowAdapter.start();
- ScheduledRecording toAdd =
- buildScheduledRecordingForTest(
- 6,
- 1518249600000L, // 2/10/2018
- 1518250600000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- mDvrHistoryRowAdapter.onScheduledRecordingAdded(toAdd);
-
- // a schedule row is added
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(7);
- assertThat(getHeaderItemCounts()).containsExactly(2, 3).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
- }
-
- @Test
- public void testOnScheduledRecordingAdded_newHeader_addOldest() {
- mDvrHistoryRowAdapter.start();
- ScheduledRecording toAdd =
- buildScheduledRecordingForTest(
- 6,
- 1518159600000L, // 2/8/2018 PST
- 1518160600000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- mDvrHistoryRowAdapter.onScheduledRecordingAdded(toAdd);
-
- // a header row and a schedule row are added
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(8);
- assertThat(getHeaderItemCounts()).containsExactly(2, 2, 1).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
- }
-
- @Test
- public void testOnScheduledRecordingAdded_newHeader_addBetween() {
- mDvrHistoryRowAdapter.start();
- ScheduledRecording toAdd =
- buildScheduledRecordingForTest(
- 6,
- 1518336000000L, // 2/11/2018 PST
- 1518337000000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- mDvrHistoryRowAdapter.onScheduledRecordingAdded(toAdd);
-
- // a header row and a schedule row are added
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(8);
- assertThat(getHeaderItemCounts()).containsExactly(2, 1, 2).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
- }
-
- @Test
- public void testOnScheduledRecordingAdded_newHeader_addNewest() {
- mDvrHistoryRowAdapter.start();
- ScheduledRecording toAdd =
- buildScheduledRecordingForTest(
- 6,
- 1518681600000L, // 2/15/2018 PST
- 1518682600000L,
- ScheduledRecording.STATE_RECORDING_FAILED);
- mDvrHistoryRowAdapter.onScheduledRecordingAdded(toAdd);
-
- // a header row and a schedule row are added
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(8);
- assertThat(getHeaderItemCounts()).containsExactly(1, 2, 2).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
- }
-
- @Test
- public void testOnScheduledRecordingAdded_addRecordedProgram() {
- mDvrHistoryRowAdapter.start();
- mDvrHistoryRowAdapter.onScheduledRecordingAdded(sRecordedProgram);
-
- // a header row and a schedule row are added
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(7);
- assertThat(getHeaderItemCounts()).containsExactly(2, 3).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
- }
-
- @Test
- public void testOnScheduledRecordingRemoved_keepHeader() {
- mDvrHistoryRowAdapter.start();
- mDvrHistoryRowAdapter.onScheduledRecordingRemoved(SCHEDULE_1);
-
- // a schedule row is removed
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(5);
- assertThat(getHeaderItemCounts()).containsExactly(2, 1).inOrder();
- assertThat(getScheduleSize()).isEqualTo(3);
- }
-
- @Test
- public void testOnScheduledRecordingRemoved_removeHeader() {
- mDvrHistoryRowAdapter.start();
- mDvrHistoryRowAdapter.onScheduledRecordingRemoved(SCHEDULE_1);
- mDvrHistoryRowAdapter.onScheduledRecordingRemoved(SCHEDULE_1_COPY);
-
- // a header row and a schedule row are removed
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(3);
- assertThat(getHeaderItemCounts()).containsExactly(2).inOrder();
- assertThat(getScheduleSize()).isEqualTo(2);
- }
-
- @Test
- public void testOnScheduledRecordingRemoved_removeRecordedProgram() {
- mDvrDataManager.addRecordedProgramInternal(sRecordedProgram, true);
- mDvrHistoryRowAdapter.start();
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(7);
- assertThat(getHeaderItemCounts()).containsExactly(2, 3).inOrder();
- assertThat(getScheduleSize()).isEqualTo(5);
-
- mDvrHistoryRowAdapter.onScheduledRecordingRemoved(sRecordedProgram);
-
- // a schedule row is removed
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(6);
- assertThat(getHeaderItemCounts()).containsExactly(2, 2);
- assertThat(getScheduleSize()).isEqualTo(4);
- }
-
- private static ScheduledRecording buildScheduledRecordingForTest(
- long id, long startTime, long endTime, int state) {
- ScheduledRecording.Builder builder =
- ScheduledRecording.builder("fakeInput", 1, startTime, endTime)
- .setId(id)
- .setState(state);
- return builder.build();
- }
-
- private static RecordedProgram buildRecordedProgramForTest(
- long id, long startTime, long endTime) {
- RecordedProgram.Builder builder =
- RecordedProgram.builder()
- .setId(id)
- .setInputId("fakeInput")
- .setStartTimeUtcMillis(startTime)
- .setEndTimeUtcMillis(endTime);
- return builder.build();
- }
-
- private int getScheduleSize() {
- int size = 0;
- for (int i = 0; i < mDvrHistoryRowAdapter.size(); i++) {
- Object item = mDvrHistoryRowAdapter.get(i);
- if (item instanceof ScheduleRow && ((ScheduleRow) item).getSchedule() != null) {
- size++;
- }
- }
- return size;
- }
-
- private List<Integer> getHeaderItemCounts() {
- List<Integer> result = new ArrayList<>();
- for (int i = 0; i < mDvrHistoryRowAdapter.size(); i++) {
- Object item = mDvrHistoryRowAdapter.get(i);
- if (item instanceof SchedulesHeaderRow) {
- int count = ((SchedulesHeaderRow) item).getItemCount();
- assertThat(count).isAtLeast(1);
- result.add(count);
- }
- }
- return result;
- }
-
- private void assertInitialState() {
- assertThat(mDvrHistoryRowAdapter.size()).isEqualTo(6);
- assertThat(getHeaderItemCounts()).containsExactly(2, 2).inOrder();
- assertThat(getScheduleSize()).isEqualTo(4);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/dvr/ui/playback/DvrPlayerTest.java b/tests/robotests/src/com/android/tv/dvr/ui/playback/DvrPlayerTest.java
deleted file mode 100644
index ad0ddf35..00000000
--- a/tests/robotests/src/com/android/tv/dvr/ui/playback/DvrPlayerTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui.playback;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvTrackInfo;
-
-import com.android.tv.ShadowTvView;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.ui.AppLayerTvView;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/** Test for {@link DvrPlayer}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(
- sdk = ConfigConstants.SDK,
- application = TestSingletonApp.class,
- shadows = {ShadowTvView.class})
-public class DvrPlayerTest {
- private ShadowTvView mShadowTvView;
- private DvrPlayer mDvrPlayer;
-
- @Before
- public void setUp() {
- AppLayerTvView tvView = new AppLayerTvView(RuntimeEnvironment.application);
- mShadowTvView = Shadow.extract(tvView);
- mDvrPlayer = new DvrPlayer(tvView, RuntimeEnvironment.application);
- }
-
- @Test
- public void testGetAudioTracks_null() {
- mShadowTvView.mTracks.put(TvTrackInfo.TYPE_AUDIO, null);
- assertThat(mDvrPlayer.getAudioTracks()).isNotNull();
- assertThat(mDvrPlayer.getAudioTracks()).isEmpty();
- }
-
- @Test
- public void testGetAudioTracks_empty() {
- mShadowTvView.mTracks.put(TvTrackInfo.TYPE_AUDIO, new ArrayList<>());
- assertThat(mDvrPlayer.getAudioTracks()).isNotNull();
- assertThat(mDvrPlayer.getAudioTracks()).isEmpty();
- }
-
- @Test
- public void testGetAudioTracks_nonEmpty() {
- TvTrackInfo info = new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "fake id").build();
- mShadowTvView.mTracks.put(TvTrackInfo.TYPE_AUDIO, Collections.singletonList(info));
- assertThat(mDvrPlayer.getAudioTracks()).containsExactly(info);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/guide/ProgramItemViewTest.java b/tests/robotests/src/com/android/tv/guide/ProgramItemViewTest.java
deleted file mode 100644
index e7850c1b..00000000
--- a/tests/robotests/src/com/android/tv/guide/ProgramItemViewTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.guide;
-
-import static com.google.android.libraries.testing.truth.TextViewSubject.assertThat;
-
-import android.support.annotation.NonNull;
-import android.view.LayoutInflater;
-
-import com.android.tv.R;
-import com.android.tv.common.util.Clock;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.guide.ProgramItemViewTest.TestApp;
-import com.android.tv.guide.ProgramItemViewTest.TestModule.Contributes;
-import com.android.tv.guide.ProgramManager.TableEntry;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.robo.RobotTestAppHelper;
-import com.android.tv.testing.testdata.TestData;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.time.Duration;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-
-/** Tests for {@link ProgramItemView}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestApp.class)
-public class ProgramItemViewTest {
-
- /** TestApp for {@link ProgramItemViewTest} */
- public static class TestApp extends TestSingletonApp implements HasAndroidInjector {
- @Inject DispatchingAndroidInjector<Object> dispatchingAndroidInjector;
-
- @Override
- public void onCreate() {
- super.onCreate();
- DaggerProgramItemViewTest_TestAppComponent.builder()
- .testModule(new TestModule(this))
- .build()
- .inject(this);
- }
-
- @Override
- public AndroidInjector<Object> androidInjector() {
- return dispatchingAndroidInjector;
- }
- }
-
- /** Component for {@link ProgramItemViewTest} */
- @Component(
- modules = {
- AndroidInjectionModule.class,
- TestModule.class,
- })
- interface TestAppComponent extends AndroidInjector<TestApp> {}
-
- /** Module for {@link ProgramItemViewTest} */
- @Module(includes = {Contributes.class})
- public static class TestModule {
-
- @Module()
- public abstract static class Contributes {
- @ContributesAndroidInjector
- abstract ProgramItemView contributesProgramItemView();
- }
-
- private final TestApp myTestApp;
-
- TestModule(TestApp test) {
- myTestApp = test;
- }
-
- @Provides
- ChannelDataManager providesChannelDataManager() {
- return myTestApp.getChannelDataManager();
- }
-
- @Provides
- Clock provideClock() {
- return myTestApp.getClock();
- }
- }
-
- // Thursday, June 1, 2017 1:00:00 PM GMT-07:00
- private final long testStartTimeMs = 1496347200000L;
-
- // Thursday, June 1, 2017 8:00:00 PM GMT-07:00
- private final long eightPM = 1496372400000L;
- private final ProgramImpl baseProgram =
- new ProgramImpl.Builder()
- .setChannelId(1)
- .setStartTimeUtcMillis(eightPM)
- .setEndTimeUtcMillis(eightPM + Duration.ofHours(1).toMillis())
- .build();
-
- private ProgramItemView mPprogramItemView;
-
- @Mock DvrManager dvrManager;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- TestSingletonApp app = (TestSingletonApp) RuntimeEnvironment.application;
- app.dvrManager = dvrManager;
- app.fakeClock.setBootTimeMillis(testStartTimeMs + TimeUnit.HOURS.toMillis(-12));
- app.fakeClock.setCurrentTimeMillis(testStartTimeMs);
- RobotTestAppHelper.loadTestData(app, TestData.DEFAULT_10_CHANNELS);
- mPprogramItemView =
- (ProgramItemView)
- LayoutInflater.from(RuntimeEnvironment.application)
- .inflate(R.layout.program_guide_table_item, null);
- GuideUtils.setWidthPerHour(100);
- }
-
- @Test
- public void initialState() {
- assertThat(mPprogramItemView).hasEmptyText();
- }
-
- @Test
- public void setValue_noProgram() {
- TableEntry tableEntry = create30MinuteTableEntryFor(null, null, false);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("a gap");
- assertThat(mPprogramItemView).hasContentDescription("1 a gap 8:00 – 9:00 PM");
- }
-
- @Test
- public void setValue_programNoTitle() {
- ProgramImpl program = new ProgramImpl.Builder(baseProgram).build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, null, false);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("No information");
- assertThat(mPprogramItemView).hasContentDescription("1 No information 8:00 – 9:00 PM");
- }
-
- @Test
- public void setValue_programTitle() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram).setTitle("A good program").build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, null, false);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program");
- assertThat(mPprogramItemView).hasContentDescription("1 A good program 8:00 – 9:00 PM");
- }
-
- @Test
- public void setValue_programDescriptionBlocked() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram)
- .setTitle("A good program")
- .setDescription("Naughty")
- .build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, null, true);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program");
- assertThat(mPprogramItemView)
- .hasContentDescription("1 A good program 8:00 – 9:00 PM This program is blocked");
- }
-
- @Test
- public void setValue_programEpisode() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram)
- .setTitle("A good program")
- .setEpisodeTitle("The one with an episode")
- .build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, null, false);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program\n\u200DThe one with an episode");
- assertThat(mPprogramItemView)
- .hasContentDescription("1 A good program 8:00 – 9:00 PM The one with an episode");
- }
-
- @Test
- public void setValue_programEpisodeAndDescrition() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram)
- .setTitle("A good program")
- .setEpisodeTitle("The one with an episode")
- .setDescription("Jack and Jill go up a hill")
- .build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, null, false);
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program\n\u200DThe one with an episode");
- assertThat(mPprogramItemView)
- .hasContentDescription(
- "1 A good program 8:00 – 9:00 PM The one with an episode"
- + " Jack and Jill go up a hill");
- }
-
- @Test
- public void setValue_scheduledConflict() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram).setTitle("A good program").build();
- ScheduledRecording scheduledRecording =
- ScheduledRecording.builder("input1", program).build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, scheduledRecording, false);
- Mockito.when(dvrManager.isConflicting(scheduledRecording)).thenReturn(true);
-
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program");
- assertThat(mPprogramItemView)
- .hasContentDescription("1 A good program 8:00 – 9:00 PM Recording conflict");
- }
-
- @Test
- public void setValue_scheduled() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram).setTitle("A good program").build();
- ScheduledRecording scheduledRecording =
- ScheduledRecording.builder("input1", program)
- .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)
- .build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, scheduledRecording, false);
- Mockito.when(dvrManager.isConflicting(scheduledRecording)).thenReturn(false);
-
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program");
- assertThat(mPprogramItemView)
- .hasContentDescription("1 A good program 8:00 – 9:00 PM Recording scheduled");
- }
-
- @Test
- public void setValue_recordingInProgress() {
- ProgramImpl program =
- new ProgramImpl.Builder(baseProgram).setTitle("A good program").build();
- ScheduledRecording scheduledRecording =
- ScheduledRecording.builder("input1", program)
- .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS)
- .build();
- TableEntry tableEntry = create30MinuteTableEntryFor(program, scheduledRecording, false);
- Mockito.when(dvrManager.isConflicting(scheduledRecording)).thenReturn(false);
-
- mPprogramItemView.setValues(null, tableEntry, 0, 0, 0, "a gap");
- assertThat(mPprogramItemView).hasText("A good program");
- assertThat(mPprogramItemView)
- .hasContentDescription("1 A good program 8:00 – 9:00 PM Recording");
- }
-
- @NonNull
- private TableEntry create30MinuteTableEntryFor(
- ProgramImpl program, ScheduledRecording scheduledRecording, boolean isBlocked) {
- return ProgramManager.createTableEntryForTest(
- 1,
- program,
- scheduledRecording,
- eightPM,
- eightPM + Duration.ofHours(1).toMillis(),
- isBlocked);
- }
-}
diff --git a/tests/robotests/src/com/android/tv/guide/ProgramTableAdapterTest.java b/tests/robotests/src/com/android/tv/guide/ProgramTableAdapterTest.java
deleted file mode 100644
index 52072748..00000000
--- a/tests/robotests/src/com/android/tv/guide/ProgramTableAdapterTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.guide;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyLong;
-
-import com.android.tv.common.flags.impl.DefaultUiFlags;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ChannelImpl;
-import com.android.tv.data.GenreItems;
-import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link ProgramTableAdapter}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class ProgramTableAdapterTest {
-
- @Mock private ProgramGuide mProgramGuide;
- @Mock private ChannelDataManager mChannelDataManager;
- @Mock private ProgramDataManager mProgramDataManager;
- private ProgramManager mProgramManager;
-
- // Thursday, June 1, 2017 1:00:00 PM GMT-07:00
- private final long mTestStartTimeMs = 1496347200000L;
- // Thursday, June 1, 2017 8:00:00 PM GMT-07:00
- private final long mEightPM = 1496372400000L;
- private DefaultUiFlags mUiFlags;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- TestSingletonApp app = (TestSingletonApp) RuntimeEnvironment.application;
- app.fakeClock.setBootTimeMillis(mTestStartTimeMs + TimeUnit.HOURS.toMillis(-12));
- app.fakeClock.setCurrentTimeMillis(mTestStartTimeMs);
- mUiFlags = new DefaultUiFlags();
- mProgramManager =
- new ProgramManager(
- app.getTvInputManagerHelper(),
- mChannelDataManager,
- mProgramDataManager,
- null,
- null);
- }
-
- @Test
- public void testOnTableEntryChanged() {
- Mockito.when(mProgramGuide.getProgramManager()).thenReturn(mProgramManager);
- Mockito.when(mProgramDataManager.getCurrentProgram(anyLong()))
- .thenAnswer(
- invocation -> {
- long id = (long) invocation.getArguments()[0];
- return buildProgramForTesting(
- id, id, (int) id % GenreItems.getGenreCount());
- });
- ProgramTableAdapter programTableAdapter =
- new ProgramTableAdapter(RuntimeEnvironment.application, mProgramGuide, mUiFlags);
- mProgramManager.setChannels(buildChannelForTesting(1, 2, 3));
- assertThat(mProgramManager.getChannelCount()).isEqualTo(3);
-
- // set genre ID to 1. Then channel 1 is in the filtered list but channel 2 is not.
- mProgramManager.resetChannelListWithGenre(1);
- assertThat(mProgramManager.getChannelCount()).isEqualTo(1);
- assertThat(mProgramManager.getChannelIndex(2)).isEqualTo(-1);
-
- // should be no exception when onTableEntryChanged() is called
- programTableAdapter.onTableEntryChanged(
- ProgramManager.createTableEntryForTest(
- 2,
- mProgramDataManager.getCurrentProgram(2),
- null,
- mTestStartTimeMs,
- mEightPM,
- false));
- }
-
- private List<Channel> buildChannelForTesting(long... ids) {
- List<Channel> channels = new ArrayList<>();
- for (long id : ids) {
- channels.add(new ChannelImpl.Builder().setId(id).build());
- }
- return channels;
- }
-
- private Program buildProgramForTesting(long id, long channelId, int genreId) {
- return new ProgramImpl.Builder()
- .setId(id)
- .setChannelId(channelId)
- .setCanonicalGenres(GenreItems.getCanonicalGenre(genreId))
- .build();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/search/FakeSearchInterface.java b/tests/robotests/src/com/android/tv/search/FakeSearchInterface.java
deleted file mode 100644
index 568bddde..00000000
--- a/tests/robotests/src/com/android/tv/search/FakeSearchInterface.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.search;
-
-import android.content.Intent;
-import android.media.tv.TvContract;
-import android.media.tv.TvContract.Programs;
-
-import com.android.tv.data.api.Program;
-import com.android.tv.search.LocalSearchProvider.SearchResult;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Fake {@link SearchInterface} for testing. */
-public class FakeSearchInterface implements SearchInterface {
- public final List<Program> mPrograms = new ArrayList<>();
-
- @Override
- public List<SearchResult> search(String query, int limit, int action) {
-
- List<SearchResult> results = new ArrayList<>();
- for (Program program : mPrograms) {
- if (program.getTitle().contains(query) || program.getDescription().contains(query)) {
- results.add(fromProgram(program));
- }
- }
- return results;
- }
-
- public static SearchResult fromProgram(Program program) {
- SearchResult.Builder result = SearchResult.builder();
- result.setTitle(program.getTitle());
- result.setDescription(
- program.getStartTimeUtcMillis() + " - " + program.getEndTimeUtcMillis());
- result.setImageUri(program.getPosterArtUri());
- result.setIntentAction(Intent.ACTION_VIEW);
- result.setIntentData(TvContract.buildChannelUri(program.getChannelId()).toString());
- result.setIntentExtraData(TvContract.buildProgramUri(program.getId()).toString());
- result.setContentType(Programs.CONTENT_ITEM_TYPE);
- result.setIsLive(true);
- result.setVideoWidth(program.getVideoWidth());
- result.setVideoHeight(program.getVideoHeight());
- result.setDuration(program.getDurationMillis());
- result.setChannelId(program.getChannelId());
- return result.build();
- }
-}
diff --git a/tests/robotests/src/com/android/tv/search/LocalSearchProviderTest.java b/tests/robotests/src/com/android/tv/search/LocalSearchProviderTest.java
deleted file mode 100644
index 76151264..00000000
--- a/tests/robotests/src/com/android/tv/search/LocalSearchProviderTest.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.search;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.fail;
-
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-import android.app.SearchManager;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.database.Cursor;
-import android.net.Uri;
-
-import com.android.tv.common.flags.impl.SettableFlagsModule;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.stub.StubPerformanceMonitor;
-import com.android.tv.search.LocalSearchProvider.SearchResult;
-import com.android.tv.search.LocalSearchProviderTest.TestAppComponent.TestAppModule;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.robo.ContentProviders;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/** Unit test for {@link LocalSearchProvider}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = LocalSearchProviderTest.TestApp.class)
-public class LocalSearchProviderTest {
-
- /** Test app for {@link LocalSearchProviderTest} */
- public static class TestApp extends TestSingletonApp implements HasAndroidInjector {
- @Inject DispatchingAndroidInjector<Object> mDispatchingAndroidProvider;
-
- @Override
- public void onCreate() {
- super.onCreate();
- DaggerLocalSearchProviderTest_TestAppComponent.builder()
- .settableFlagsModule(flagsModule)
- .build()
- .inject(this);
- }
-
- @Override
- public AndroidInjector<Object> androidInjector() {
- return mDispatchingAndroidProvider;
- }
- }
-
- @Component(
- modules = {
- AndroidInjectionModule.class,
- SettableFlagsModule.class,
- LocalSearchProvider.Module.class,
- TestAppModule.class
- })
- @Singleton
- interface TestAppComponent extends AndroidInjector<TestApp> {
- @Module
- abstract static class TestAppModule {
- @Provides
- @Singleton
- static PerformanceMonitor providePerformanceMonitor() {
- return new StubPerformanceMonitor();
- }
- }
- }
-
- private final Program mProgram1 =
- new ProgramImpl.Builder()
- .setTitle("Dummy program")
- .setDescription("Dummy program season 2")
- .setPosterArtUri("FakeUri")
- .setStartTimeUtcMillis(1516674000000L)
- .setEndTimeUtcMillis(1516677000000L)
- .setChannelId(7)
- .setVideoWidth(1080)
- .setVideoHeight(960)
- .build();
-
- private final String mAuthority = "com.android.tv.search";
- private final String mKeyword = "mKeyword";
- private final Uri mBaseSearchUri =
- Uri.parse(
- "content://"
- + mAuthority
- + "/"
- + SearchManager.SUGGEST_URI_PATH_QUERY
- + "/"
- + mKeyword);
-
- private final Uri mWrongSearchUri =
- Uri.parse("content://" + mAuthority + "/wrong_path/" + mKeyword);
-
- private LocalSearchProvider mProvider;
- private ContentResolver mContentResolver;
-
- @Mock private SearchInterface mMockSearchInterface;
- private final FakeSearchInterface mFakeSearchInterface = new FakeSearchInterface();
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mProvider = ContentProviders.register(LocalSearchProvider.class, mAuthority);
- mContentResolver = RuntimeEnvironment.application.getContentResolver();
- }
-
- @Test
- public void testQuery_normalUri() {
- verifyQueryWithArguments(null, null);
- verifyQueryWithArguments(1, null);
- verifyQueryWithArguments(null, 1);
- verifyQueryWithArguments(1, 1);
- }
-
- @Test
- public void testQuery_invalidUri() {
- try (Cursor c = mContentResolver.query(mWrongSearchUri, null, null, null, null)) {
- fail("Query with invalid URI should fail.");
- } catch (IllegalArgumentException e) {
- // Success.
- }
- }
-
- @Test
- public void testQuery_invalidLimit() {
- verifyQueryWithArguments(-1, null);
- }
-
- @Test
- public void testQuery_invalidAction() {
- verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_START - 1);
- verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_END + 1);
- }
-
- private void verifyQueryWithArguments(Integer limit, Integer action) {
- mProvider.setSearchInterface(mMockSearchInterface);
- Uri uri = mBaseSearchUri;
- if (limit != null || action != null) {
- Uri.Builder builder = uri.buildUpon();
- if (limit != null) {
- builder.appendQueryParameter(
- SearchManager.SUGGEST_PARAMETER_LIMIT, limit.toString());
- }
- if (action != null) {
- builder.appendQueryParameter(
- LocalSearchProvider.SUGGEST_PARAMETER_ACTION, action.toString());
- }
- uri = builder.build();
- }
- try (Cursor c = mContentResolver.query(uri, null, null, null, null)) {
- // Do nothing.
- }
- int expectedLimit =
- limit == null || limit <= 0 ? LocalSearchProvider.DEFAULT_SEARCH_LIMIT : limit;
- int expectedAction =
- (action == null
- || action < SearchInterface.ACTION_TYPE_START
- || action > SearchInterface.ACTION_TYPE_END)
- ? LocalSearchProvider.DEFAULT_SEARCH_ACTION
- : action;
- verify(mMockSearchInterface).search(mKeyword, expectedLimit, expectedAction);
- reset(mMockSearchInterface);
- }
-
- @Test
- public void testGetType() {
- assertThat(mProvider.getType(mBaseSearchUri)).isEqualTo(SearchManager.SUGGEST_MIME_TYPE);
- }
-
- @Test
- public void query_empty() {
- mProvider.setSearchInterface(mFakeSearchInterface);
- Cursor cursor = mContentResolver.query(mBaseSearchUri, null, null, null, null);
- assertThat(cursor.moveToNext()).isFalse();
- }
-
- @Test
- public void query_program1() {
- mProvider.setSearchInterface(mFakeSearchInterface);
- mFakeSearchInterface.mPrograms.add(mProgram1);
- Uri uri =
- Uri.parse(
- "content://"
- + mAuthority
- + "/"
- + SearchManager.SUGGEST_URI_PATH_QUERY
- + "/"
- + "Dummy");
- Cursor cursor = mContentResolver.query(uri, null, null, null, null);
- assertThat(fromCursor(cursor)).containsExactly(FakeSearchInterface.fromProgram(mProgram1));
- }
-
- private List<SearchResult> fromCursor(Cursor cursor) {
- List<SearchResult> results = new ArrayList<>();
- while (cursor.moveToNext()) {
- SearchResult.Builder result = SearchResult.builder();
- int i = 0;
- result.setTitle(cursor.getString(i++));
- result.setDescription(cursor.getString(i++));
- result.setImageUri(cursor.getString(i++));
- result.setIntentAction(cursor.getString(i++));
- String intentData = cursor.getString(i++);
- result.setIntentData(intentData);
- result.setIntentExtraData(cursor.getString(i++));
- result.setContentType(cursor.getString(i++));
- result.setIsLive(cursor.getString(i++).equals("1"));
- result.setVideoWidth(Integer.valueOf(cursor.getString(i++)));
- result.setVideoHeight(Integer.valueOf(cursor.getString(i++)));
- result.setDuration(Long.valueOf(cursor.getString(i++)));
- result.setProgressPercentage(Integer.valueOf(cursor.getString(i)));
- result.setChannelId(ContentUris.parseId(Uri.parse(intentData)));
- results.add(result.build());
- }
- return results;
- }
-}
diff --git a/tests/robotests/src/com/android/tv/testing/TvRobolectricTestRunner.java b/tests/robotests/src/com/android/tv/testing/TvRobolectricTestRunner.java
deleted file mode 100644
index 445fab26..00000000
--- a/tests/robotests/src/com/android/tv/testing/TvRobolectricTestRunner.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.testing;
-
-import org.junit.runners.model.InitializationError;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.manifest.AndroidManifest;
-import org.robolectric.res.Fs;
-import org.robolectric.res.ResourcePath;
-
-import java.util.List;
-
-/**
- * Custom test runner TV. This is needed because the default behavior for robolectric is just to
- * grab the resource directory in the target package. We want to override this to add several
- * spanning different projects.
- *
- * <p><b>Note</b> copied from
- * http://cs/android/packages/apps/Settings/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
- */
-public class TvRobolectricTestRunner extends RobolectricTestRunner {
-
- /** We don't actually want to change this behavior, so we just call super. */
- public TvRobolectricTestRunner(Class<?> testClass) throws InitializationError {
- super(testClass);
- }
-
- /**
- * We are going to create our own custom manifest so that we can add multiple resource paths to
- * it. This lets us access resources in both Settings and SettingsLib in our tests.
- */
- @Override
- protected AndroidManifest getAppManifest(Config config) {
- final String packageName = "com.android.tv";
-
- // By adding any resources from libraries we need the AndroidManifest, we can access
- // them from within the parallel universe's resource loader.
- return new AndroidManifest(
- Fs.fileFromPath(config.manifest()),
- Fs.fileFromPath(config.resourceDir()),
- Fs.fileFromPath(config.assetDir()),
- packageName) {
- @Override
- public List<ResourcePath> getIncludedResourcePaths() {
- List<ResourcePath> paths = super.getIncludedResourcePaths();
- TvRobolectricTestRunner.getIncludedResourcePaths(paths);
- return paths;
- }
- };
- }
-
- public static void getIncludedResourcePaths(List<ResourcePath> paths) {
- paths.add(
- new ResourcePath(
- null,
- Fs.fileFromPath("./packages/apps/TV/res"),
- null));
- paths.add(
- new ResourcePath(
- null,
- Fs.fileFromPath("./packages/apps/TV/common/res"),
- null));
- paths.add(
- new ResourcePath(
- null,
- Fs.fileFromPath("./packages/apps/TV/material_res"),
- null));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/ui/ChannelBannerViewTest.java b/tests/robotests/src/com/android/tv/ui/ChannelBannerViewTest.java
deleted file mode 100644
index 80a50f6f..00000000
--- a/tests/robotests/src/com/android/tv/ui/ChannelBannerViewTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 static com.google.common.truth.Truth.assertThat;
-
-import static org.robolectric.Shadows.shadowOf;
-
-import android.app.Activity;
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.tv.R;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.common.singletons.HasSingletons;
-import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.ui.ChannelBannerView.MySingletons;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.annotation.Config;
-
-import javax.inject.Provider;
-
-/** Tests for {@link ChannelBannerView}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class ChannelBannerViewTest {
-
- private TestActivity testActivity;
- private ChannelBannerView mChannelBannerView;
- private ImageView mChannelSignalStrengthView;
-
- @Before
- public void setUp() {
- testActivity = Robolectric.buildActivity(TestActivity.class).create().get();
- mChannelBannerView =
- (ChannelBannerView)
- LayoutInflater.from(testActivity).inflate(R.layout.channel_banner, null);
- mChannelSignalStrengthView = mChannelBannerView.findViewById(R.id.channel_signal_strength);
- }
-
- @Test
- public void updateChannelSignalStrengthView_valueIsNotValid() {
- mChannelBannerView.updateChannelSignalStrengthView(-1);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.GONE);
- mChannelBannerView.updateChannelSignalStrengthView(101);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void updateChannelSignalStrengthView_20() {
- mChannelBannerView.updateChannelSignalStrengthView(20);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(shadowOf(mChannelSignalStrengthView.getDrawable()).getCreatedFromResId())
- .isEqualTo(R.drawable.quantum_ic_signal_cellular_0_bar_white_24);
- }
-
- @Test
- public void updateChannelSignalStrengthView_40() {
- mChannelBannerView.updateChannelSignalStrengthView(40);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(shadowOf(mChannelSignalStrengthView.getDrawable()).getCreatedFromResId())
- .isEqualTo(R.drawable.quantum_ic_signal_cellular_1_bar_white_24);
- }
-
- @Test
- public void updateChannelSignalStrengthView_60() {
- mChannelBannerView.updateChannelSignalStrengthView(60);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(shadowOf(mChannelSignalStrengthView.getDrawable()).getCreatedFromResId())
- .isEqualTo(R.drawable.quantum_ic_signal_cellular_2_bar_white_24);
- }
-
- @Test
- public void updateChannelSignalStrengthView_80() {
- mChannelBannerView.updateChannelSignalStrengthView(80);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(shadowOf(mChannelSignalStrengthView.getDrawable()).getCreatedFromResId())
- .isEqualTo(R.drawable.quantum_ic_signal_cellular_3_bar_white_24);
- }
-
- @Test
- public void updateChannelSignalStrengthView_100() {
- mChannelBannerView.updateChannelSignalStrengthView(100);
- assertThat(mChannelSignalStrengthView.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(shadowOf(mChannelSignalStrengthView.getDrawable()).getCreatedFromResId())
- .isEqualTo(R.drawable.quantum_ic_signal_cellular_4_bar_white_24);
- }
-
- /** An activity for {@link ChannelBannerViewTest}. */
- public static class TestActivity extends Activity implements HasSingletons<MySingletons> {
-
- MySingletonsImpl mSingletons = new MySingletonsImpl();
- Context mContext = this;
-
- @Override
- public ChannelBannerView.MySingletons singletons() {
- return mSingletons;
- }
-
- /** MySingletons implementation needed for this class. */
- public class MySingletonsImpl implements ChannelBannerView.MySingletons {
-
- @Override
- public Provider<Channel> getCurrentChannelProvider() {
- return null;
- }
-
- @Override
- public Provider<Program> getCurrentProgramProvider() {
- return null;
- }
-
- @Override
- public Provider<TvOverlayManager> getOverlayManagerProvider() {
- return null;
- }
-
- @Override
- public TvInputManagerHelper getTvInputManagerHelperSingleton() {
- return new TvInputManagerHelper(mContext, DefaultLegacyFlags.DEFAULT);
- }
-
- @Override
- public Provider<Long> getCurrentPlayingPositionProvider() {
- return null;
- }
-
- @Override
- public DvrManager getDvrManagerSingleton() {
- return null;
- }
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/ui/hideable/AutoHideSchedulerTest.java b/tests/robotests/src/com/android/tv/ui/hideable/AutoHideSchedulerTest.java
deleted file mode 100644
index a0a21070..00000000
--- a/tests/robotests/src/com/android/tv/ui/hideable/AutoHideSchedulerTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hideable;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowLooper;
-
-import java.util.concurrent.TimeUnit;
-
-/** Test for {@link AutoHideScheduler}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class AutoHideSchedulerTest {
-
- private TestRunnable mTestRunnable = new TestRunnable();
- private AutoHideScheduler mAutoHideScheduler;
- private ShadowLooper mShadowLooper;
-
- @Before
- public void setUp() throws Exception {
- mShadowLooper = ShadowLooper.getShadowMainLooper();
- mAutoHideScheduler = new AutoHideScheduler(RuntimeEnvironment.application, mTestRunnable);
- }
-
- @Test
- public void initialState() {
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- }
-
- @Test
- public void cancel() {
- mAutoHideScheduler.cancel();
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- }
-
- @Test
- public void schedule() {
- mAutoHideScheduler.schedule(10);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- }
-
- @Test
- public void setA11yEnabledThenSchedule() {
- mAutoHideScheduler.onAccessibilityStateChanged(true);
- mAutoHideScheduler.schedule(10);
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- }
-
- @Test
- public void scheduleThenCancel() {
- mAutoHideScheduler.schedule(10);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- mAutoHideScheduler.cancel();
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- }
-
- @Test
- public void scheduleThenLoop() {
- mAutoHideScheduler.schedule(10);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- mShadowLooper.idle(9, TimeUnit.MILLISECONDS);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- mShadowLooper.idle(1, TimeUnit.MILLISECONDS);
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- assertThat(mTestRunnable.runCount).isEqualTo(1);
- }
-
- @Test
- public void scheduleSetA11yEnabledThenLoop() {
- mAutoHideScheduler.schedule(10);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- mShadowLooper.idle(9, TimeUnit.MILLISECONDS);
- assertThat(mAutoHideScheduler.isScheduled()).isTrue();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- mAutoHideScheduler.onAccessibilityStateChanged(true);
- mShadowLooper.idle(1, TimeUnit.MILLISECONDS);
- assertThat(mAutoHideScheduler.isScheduled()).isFalse();
- assertThat(mTestRunnable.runCount).isEqualTo(0);
- }
-
- private static class TestRunnable implements Runnable {
- int runCount = 0;
-
- @Override
- public void run() {
- runCount++;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/util/MultiLongSparseArrayTest.java b/tests/robotests/src/com/android/tv/util/MultiLongSparseArrayTest.java
deleted file mode 100644
index 931ff0be..00000000
--- a/tests/robotests/src/com/android/tv/util/MultiLongSparseArrayTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link MultiLongSparseArray}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class MultiLongSparseArrayTest {
- @Test
- public void testEmpty() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- assertThat(sparseArray.get(0)).isEmpty();
- }
-
- @Test
- public void testOneElement() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.put(0, "foo");
- assertThat(sparseArray.get(0)).containsExactly("foo");
- }
-
- @Test
- public void testTwoElements() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.put(0, "foo");
- sparseArray.put(0, "bar");
- assertThat(sparseArray.get(0)).containsExactly("foo", "bar");
- }
-
- @Test
- public void testClearEmptyCache() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(0);
- sparseArray.put(0, "foo");
- sparseArray.remove(0, "foo");
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(1);
- sparseArray.clearEmptyCache();
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(0);
- }
-
- @Test
- public void testMaxEmptyCacheSize() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(0);
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.put(i, "foo");
- }
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.remove(i, "foo");
- }
- assertThat(sparseArray.getEmptyCacheSize())
- .isEqualTo(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT);
- sparseArray.clearEmptyCache();
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(0);
- }
-
- @Test
- public void testReuseEmptySets() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertThat(sparseArray.getEmptyCacheSize()).isEqualTo(0);
- // create a bunch of sets
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.put(i, "foo");
- }
- // remove them so they are all put in the cache.
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.remove(i, "foo");
- }
- assertThat(sparseArray.getEmptyCacheSize())
- .isEqualTo(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT);
-
- // now create elements, that use the cached empty sets.
- for (int i = 0; i < MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT; i++) {
- sparseArray.put(10 + i, "bar");
- assertThat(sparseArray.getEmptyCacheSize())
- .isEqualTo(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT - i - 1);
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/util/TvInputManagerHelperRoboTest.java b/tests/robotests/src/com/android/tv/util/TvInputManagerHelperRoboTest.java
deleted file mode 100644
index 9586c1f5..00000000
--- a/tests/robotests/src/com/android/tv/util/TvInputManagerHelperRoboTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
-
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/**
- * Tests for {@link TvInputManagerHelper}.
- *
- * <p>This test is named ...RoboTest because there is already a test named <code>
- * TvInputManagerHelperTest</code>
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class TvInputManagerHelperRoboTest {
-
- @Test
- public void getInputState_null() {
- TvInputInfo tvinputInfo = null;
- TvInputManagerHelper tvInputManagerHelper =
- new TvInputManagerHelper(
- RuntimeEnvironment.application, DefaultLegacyFlags.DEFAULT);
- assertThat(TvInputManager.INPUT_STATE_DISCONNECTED)
- .isSameInstanceAs(tvInputManagerHelper.getInputState(tvinputInfo));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/util/TvProviderUtilsTest.java b/tests/robotests/src/com/android/tv/util/TvProviderUtilsTest.java
deleted file mode 100644
index bd0e9966..00000000
--- a/tests/robotests/src/com/android/tv/util/TvProviderUtilsTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.pm.ProviderInfo;
-import android.media.tv.TvContract;
-import android.os.Bundle;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.fakes.FakeTvProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowContentResolver;
-
-import java.util.Set;
-
-/** Tests for {@link TvProviderUtils}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(
- sdk = ConfigConstants.SDK,
- shadows = {ShadowContentResolver.class})
-public class TvProviderUtilsTest {
-
- @Before
- public void setUp() {
- ProviderInfo info = new ProviderInfo();
- info.authority = TvContract.AUTHORITY;
- FakeTvProvider provider =
- Robolectric.buildContentProvider(FakeTvProviderForTesting.class).create(info).get();
- provider.onCreate();
- ShadowContentResolver.registerProviderInternal(TvContract.AUTHORITY, provider);
- }
-
- @Test
- public void testAddExtraColumnsToProjection() {
- String[] inputStrings = {"column_1", "column_2", "column_3"};
- assertThat(
- TvProviderUtils.addExtraColumnsToProjection(
- inputStrings, TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE))
- .asList()
- .containsExactly(
- "column_1",
- "column_2",
- "column_3",
- TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE)
- .inOrder();
- }
-
- @Test
- public void testAddExtraColumnsToProjection_extraColumnExists() {
- String[] inputStrings = {
- "column_1",
- "column_2",
- TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID,
- TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE,
- "column_3"
- };
- assertThat(
- TvProviderUtils.addExtraColumnsToProjection(
- inputStrings, TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE))
- .asList()
- .containsExactly(
- "column_1",
- "column_2",
- TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID,
- TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE,
- "column_3")
- .inOrder();
- }
-
- @Test
- public void testGetExistingColumns_noException() {
- FakeTvProviderForTesting.mThrowException = false;
- FakeTvProviderForTesting.mBundleResult = new Bundle();
- FakeTvProviderForTesting.mBundleResult.putStringArray(
- TvContract.EXTRA_EXISTING_COLUMN_NAMES, new String[] {"column 1", "column 2"});
- Set<String> columns =
- TvProviderUtils.getExistingColumns(
- RuntimeEnvironment.application, TvContract.Programs.CONTENT_URI);
- assertThat(columns).containsExactly("column 1", "column 2");
- }
-
- @Test
- public void testGetExistingColumns_throwsException() {
- FakeTvProviderForTesting.mThrowException = true;
- FakeTvProviderForTesting.mBundleResult = new Bundle();
- // should be no exception here
- Set<String> columns =
- TvProviderUtils.getExistingColumns(
- RuntimeEnvironment.application, TvContract.Programs.CONTENT_URI);
- assertThat(columns).isEmpty();
- }
-
- private static class FakeTvProviderForTesting extends FakeTvProvider {
- private static Bundle mBundleResult;
- private static boolean mThrowException;
-
- @Override
- public Bundle call(String method, String arg, Bundle extras) {
- if (mThrowException) {
- throw new IllegalStateException();
- }
- return mBundleResult;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/tv/util/TvTrackInfoUtilsTest.java b/tests/robotests/src/com/android/tv/util/TvTrackInfoUtilsTest.java
deleted file mode 100644
index c59cb16e..00000000
--- a/tests/robotests/src/com/android/tv/util/TvTrackInfoUtilsTest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.util;
-
-import static com.android.tv.util.TvTrackInfoUtils.getBestTrackInfo;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.assertEquals;
-
-import android.media.tv.TvTrackInfo;
-import android.os.Build.VERSION_CODES;
-import android.os.LocaleList;
-
-import com.android.tv.testing.ComparatorTester;
-import com.android.tv.testing.TvRobolectricTestRunner;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-
-/** Tests for {@link com.android.tv.util.TvTrackInfoUtils}. */
-@RunWith(TvRobolectricTestRunner.class)
-@Config(minSdk = ConfigConstants.MIN_SDK, maxSdk = ConfigConstants.MAX_SDK)
-public class TvTrackInfoUtilsTest {
-
- /** Tests for {@link TvTrackInfoUtils#getBestTrackInfo}. */
- private static final String UN_MATCHED_ID = "no matching ID";
-
- private final TvTrackInfo info1En1 = createTvTrackInfo("track_1", "en", 1);
-
- private final TvTrackInfo info2En5 = createTvTrackInfo("track_2", "en", 5);
-
- private final TvTrackInfo info3Fr8 = createTvTrackInfo("track_3", "fr", 8);
-
- private final TvTrackInfo info4Null2 = createTvTrackInfo("track_4", null, 2);
-
- private final TvTrackInfo info5Null6 = createTvTrackInfo("track_5", null, 6);
-
- private TvTrackInfo createTvTrackInfo(String trackId, String language, int audioChannelCount) {
- return new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, trackId)
- .setLanguage(language)
- .setAudioChannelCount(audioChannelCount)
- .build();
- }
-
- private final List<TvTrackInfo> allTracks =
- Arrays.asList(info1En1, info2En5, info3Fr8, info4Null2, info5Null6);
- private final List<TvTrackInfo> nullLanguageTracks = Arrays.asList(info4Null2, info5Null6);
-
- @Test
- public void testGetBestTrackInfo_empty() {
- TvTrackInfo result = getBestTrackInfo(Collections.emptyList(), UN_MATCHED_ID, "en", 1);
- assertWithMessage("best track ").that(result).isEqualTo(null);
- }
-
- @Test
- public void testGetBestTrackInfo_exactMatch() {
- TvTrackInfo result = getBestTrackInfo(allTracks, "track_1", "en", 1);
- assertWithMessage("best track ").that(result).isEqualTo(info1En1);
- }
-
- @Test
- public void testGetBestTrackInfo_langAndChannelCountMatch() {
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, "en", 5);
- assertWithMessage("best track ").that(result).isEqualTo(info2En5);
- }
-
- @Test
- public void testGetBestTrackInfo_languageOnlyMatch() {
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, "fr", 1);
- assertWithMessage("best track ").that(result).isEqualTo(info3Fr8);
- }
-
- @Test
- @Config(minSdk = ConfigConstants.MIN_SDK, maxSdk = VERSION_CODES.M)
- public void testGetBestTrackInfo_channelCountOnlyMatchWithNullLanguage_23() {
- Locale localPreference = Locale.forLanguageTag("es");
- Locale.setDefault(localPreference);
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, null, 8);
- assertWithMessage("best track ").that(result).isEqualTo(info3Fr8);
- }
-
- @Test
- @Config(minSdk = VERSION_CODES.N, maxSdk = ConfigConstants.MAX_SDK)
- public void testGetBestTrackInfo_channelCountOnlyMatchWithNullLanguage() {
- // Setting LoacaleList to a language which is not in the test set.
- LocaleList localPreferenceList = LocaleList.forLanguageTags("es");
- LocaleList.setDefault(localPreferenceList);
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, null, 8);
- assertWithMessage("best track ").that(result).isEqualTo(info3Fr8);
- }
-
- @Test
- public void testGetBestTrackInfo_noMatches() {
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, "kr", 1);
- assertWithMessage("best track ").that(result).isEqualTo(info1En1);
- }
-
- @Test
- @Config(minSdk = ConfigConstants.MIN_SDK, maxSdk = VERSION_CODES.M)
- public void testGetBestTrackInfo_noMatchesWithNullLanguage_23() {
- Locale localPreference = Locale.forLanguageTag("es");
- Locale.setDefault(localPreference);
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, null, 0);
- assertWithMessage("best track ").that(result).isEqualTo(info3Fr8);
- }
-
- @Test
- @Config(minSdk = VERSION_CODES.N, maxSdk = ConfigConstants.MAX_SDK)
- public void testGetBestTrackInfo_noMatchesWithNullLanguage() {
- // Setting LoacaleList to a language which is not in the test set.
- LocaleList localPreferenceList = LocaleList.forLanguageTags("es");
- LocaleList.setDefault(localPreferenceList);
- TvTrackInfo result = getBestTrackInfo(allTracks, UN_MATCHED_ID, null, 0);
- assertWithMessage("best track ").that(result).isEqualTo(info3Fr8);
- }
-
- @Test
- public void testGetBestTrackInfo_channelCountAndIdMatch() {
- TvTrackInfo result = getBestTrackInfo(nullLanguageTracks, "track_5", null, 6);
- assertWithMessage("best track ").that(result).isEqualTo(info5Null6);
- }
-
- @Test
- public void testComparator() {
- List<String> languages = Arrays.asList("en", "spa", "hi");
- Comparator<TvTrackInfo> comparator =
- TvTrackInfoUtils.createComparator("track_1", languages, 1);
- new ComparatorTester(comparator)
- .permitInconsistencyWithEquals()
- // lang not match
- .addEqualityGroup(
- createTvTrackInfo("track_1", "kr", 2),
- createTvTrackInfo("track_1", "ja", 2),
- createTvTrackInfo("track_1", "ch", 2))
- // lang not match, better count
- .addEqualityGroup(
- createTvTrackInfo("track_1", "kr", 3),
- createTvTrackInfo("track_1", "ch", 3))
- // lang not match, count match
- .addEqualityGroup(
- createTvTrackInfo("track_1", "ch", 1),
- createTvTrackInfo("track_1", "ja", 1))
- // lang match in order of increasing priority
- .addEqualityGroup(createTvTrackInfo("track_1", "hi", 3))
- .addEqualityGroup(createTvTrackInfo("track_2", "hi", 7))
- .addEqualityGroup(createTvTrackInfo("track_1", "hi", 1))
- .addEqualityGroup(createTvTrackInfo("track_1", "spa", 5))
- .addEqualityGroup(createTvTrackInfo("track_2", "spa", 1))
- .addEqualityGroup(createTvTrackInfo("track_1", "spa", 1))
- .addEqualityGroup(createTvTrackInfo("track_2", "en", 3))
- .addEqualityGroup(
- createTvTrackInfo("track_1", "en", 5),
- createTvTrackInfo("track_2", "en", 5))
- // best lang match and count match
- .addEqualityGroup(
- createTvTrackInfo("track_2", "en", 1),
- createTvTrackInfo("track_3", "en", 1))
- // all match
- .addEqualityGroup(
- createTvTrackInfo("track_1", "en", 1),
- createTvTrackInfo("track_1", "en", 1))
- .testCompare();
- }
-
- /** Tests for {@link TvTrackInfoUtils#needToShowSampleRate}. */
- private final TvTrackInfo info6En1 = createTvTrackInfo("track_6", "en", 1);
-
- private final TvTrackInfo info7En0 = createTvTrackInfo("track_7", "en", 0);
-
- private final TvTrackInfo info8En0 = createTvTrackInfo("track_8", "en", 0);
-
- private List<TvTrackInfo> trackList;
-
- @Test
- public void needToShowSampleRate_false() {
- trackList = Arrays.asList(info1En1, info2En5);
- assertEquals(
- false,
- TvTrackInfoUtils.needToShowSampleRate(RuntimeEnvironment.application, trackList));
- }
-
- @Test
- public void needToShowSampleRate_sameLanguageAndChannelCount() {
- trackList = Arrays.asList(info1En1, info6En1);
- assertEquals(
- true,
- TvTrackInfoUtils.needToShowSampleRate(RuntimeEnvironment.application, trackList));
- }
-
- @Test
- public void needToShowSampleRate_sameLanguageNoChannelCount() {
- trackList = Arrays.asList(info7En0, info8En0);
- assertEquals(
- true,
- TvTrackInfoUtils.needToShowSampleRate(RuntimeEnvironment.application, trackList));
- }
-
- /** Tests for {@link TvTrackInfoUtils#getMultiAudioString}. */
- private static final String TRACK_ID = "test_track_id";
-
- private static final int AUDIO_SAMPLE_RATE = 48000;
-
- @Test
- public void testAudioTrackLanguage() {
- assertEquals(
- "Korean",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("kor"), false));
- assertEquals(
- "English",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng"), false));
- assertEquals(
- "Unknown language",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo(null), false));
- assertEquals(
- "Unknown language",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo(""), false));
- assertEquals(
- "abc",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("abc"), false));
- }
-
- @Test
- public void testAudioTrackCount() {
- assertEquals(
- "English",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", -1), false));
- assertEquals(
- "English",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 0), false));
- assertEquals(
- "English (mono)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 1), false));
- assertEquals(
- "English (stereo)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 2), false));
- assertEquals(
- "English (3 channels)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 3), false));
- assertEquals(
- "English (4 channels)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 4), false));
- assertEquals(
- "English (5 channels)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 5), false));
- assertEquals(
- "English (5.1 surround)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 6), false));
- assertEquals(
- "English (7 channels)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 7), false));
- assertEquals(
- "English (7.1 surround)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("eng", 8), false));
- }
-
- @Test
- public void testShowSampleRate() {
- assertEquals(
- "Korean (48kHz)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("kor", 0), true));
- assertEquals(
- "Korean (7.1 surround, 48kHz)",
- TvTrackInfoUtils.getMultiAudioString(
- RuntimeEnvironment.application, createAudioTrackInfo("kor", 8), true));
- }
-
- private static TvTrackInfo createAudioTrackInfo(String language) {
- return createAudioTrackInfo(language, 0);
- }
-
- private static TvTrackInfo createAudioTrackInfo(String language, int channelCount) {
- return new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, TRACK_ID)
- .setLanguage(language)
- .setAudioChannelCount(channelCount)
- .setAudioSampleRate(AUDIO_SAMPLE_RATE)
- .build();
- }
-
- /** Tests for {@link TvTrackInfoUtils#toString */
- @Test
- public void toString_audioWithDetails() {
- assertEquals(
- "TvTrackInfo{type=Audio, id=track_1, language=en, "
- + "description=test, audioChannelCount=1, audioSampleRate=5}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "track_1")
- .setLanguage("en")
- .setAudioChannelCount(1)
- .setDescription("test")
- .setAudioSampleRate(5)
- .build()));
- }
-
- @Test
- public void toString_audioWithDefaults() {
- assertEquals(
- "TvTrackInfo{type=Audio, id=track_2, language=null, "
- + "description=null, audioChannelCount=0, audioSampleRate=0}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "track_2").build()));
- }
-
- @Test
- public void toString_videoWithDetails() {
- assertEquals(
- "TvTrackInfo{type=Video, id=track_3, language=en, description=test, videoWidth=1,"
- + " videoHeight=1, videoFrameRate=1.0, videoPixelAspectRatio=2.0}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "track_3")
- .setLanguage("en")
- .setDescription("test")
- .setVideoWidth(1)
- .setVideoHeight(1)
- .setVideoFrameRate(1)
- .setVideoPixelAspectRatio(2)
- .build()));
- }
-
- @Test
- public void toString_videoWithDefaults() {
- assertEquals(
- "TvTrackInfo{type=Video, id=track_4, language=null, description=null, videoWidth=0,"
- + " videoHeight=0, videoFrameRate=0.0, videoPixelAspectRatio=1.0}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "track_4").build()));
- }
-
- @Test
- public void toString_subtitleWithDetails() {
- assertEquals(
- "TvTrackInfo{type=Subtitle, id=track_5, language=en, description=test}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, "track_5")
- .setLanguage("en")
- .setDescription("test")
- .build()));
- }
-
- @Test
- public void toString_subtitleWithDefaults() {
- assertEquals(
- "TvTrackInfo{type=Subtitle, id=track_6, language=null, description=null}",
- TvTrackInfoUtils.toString(
- new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, "track_6").build()));
- }
-}
diff --git a/tests/robotests/src/com/android/tv/util/UtilsTest.java b/tests/robotests/src/com/android/tv/util/UtilsTest.java
deleted file mode 100644
index eb27e8a0..00000000
--- a/tests/robotests/src/com/android/tv/util/UtilsTest.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.text.format.DateUtils;
-
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * Tests for {@link com.android.tv.util.Utils#getDurationString}.
- *
- * <p>This test uses deprecated flags {@link DateUtils#FORMAT_12HOUR} and {@link
- * DateUtils#FORMAT_24HOUR} to run this test independent to system's 12/24h format.
- */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class UtilsTest {
- // TODO: Mock Context so we can specify current time and locale for test.
- private Locale mLocale;
- private static final long DATE_THIS_YEAR_2_1_MS = getFebOfThisYearInMillis(1, 0, 0);
-
- // All possible list for a parameter to test parameter independent result.
- private static final boolean[] PARAM_USE_SHORT_FORMAT = {false, true};
-
- @Before
- public void setUp() {
- // Set locale to US
- mLocale = Locale.getDefault();
- Locale.setDefault(Locale.US);
- }
-
- @After
- public void tearDown() {
- // Revive system locale.
- Locale.setDefault(mLocale);
- }
-
- /** Return time in millis assuming that whose year is this year and month is Jan. */
- private static long getJanOfThisYearInMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(getThisYear(), Calendar.JANUARY, date, hour, minutes)
- .getTimeInMillis();
- }
-
- private static long getJanOfThisYearInMillis(int date, int hour) {
- return getJanOfThisYearInMillis(date, hour, 0);
- }
-
- /** Return time in millis assuming that whose year is this year and month is Feb. */
- private static long getFebOfThisYearInMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(getThisYear(), Calendar.FEBRUARY, date, hour, minutes)
- .getTimeInMillis();
- }
-
- private static long getFebOfThisYearInMillis(int date, int hour) {
- return getFebOfThisYearInMillis(date, hour, 0);
- }
-
- private static int getThisYear() {
- return new GregorianCalendar().get(GregorianCalendar.YEAR);
- }
-
- @Test
- public void testSameDateAndTime() {
- assertEquals(
- "3:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3),
- getFebOfThisYearInMillis(1, 3),
- false,
- DateUtils.FORMAT_12HOUR));
- assertEquals(
- "03:00",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3),
- getFebOfThisYearInMillis(1, 3),
- false,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationWithinToday() {
- assertEquals(
- "12:00 – 3:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3),
- false,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationFromYesterdayToToday() {
- assertEquals(
- "Jan 31, 3:00 AM – Feb 1, 4:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getJanOfThisYearInMillis(31, 23, 30),
- getFebOfThisYearInMillis(1, 0, 30),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationFromTodayToTomorrow() {
- assertEquals(
- "Feb 1, 3:00 AM – Feb 2, 4:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23, 30),
- getFebOfThisYearInMillis(2, 0, 30),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationWithinTomorrow() {
- assertEquals(
- "Feb 2, 2:00 – 4:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 2),
- getFebOfThisYearInMillis(2, 4),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testStartOfDay() {
- assertEquals(
- "12:00 – 1:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0),
- getFebOfThisYearInMillis(2, 1),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testEndOfDay() {
- for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
- assertEquals(
- "11:00 PM – 12:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23),
- getFebOfThisYearInMillis(2, 0),
- useShortFormat,
- DateUtils.FORMAT_12HOUR));
- assertEquals(
- "23:00 – 00:00",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 23),
- getFebOfThisYearInMillis(3, 0),
- true,
- DateUtils.FORMAT_24HOUR));
- assertEquals(
- "2/2, 12:00 AM – 2/3, 12:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0),
- getFebOfThisYearInMillis(3, 0),
- true,
- DateUtils.FORMAT_12HOUR));
- assertEquals(
- "2/2, 00:00 – 2/3, 00:00",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0),
- getFebOfThisYearInMillis(3, 0),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testMidnight() {
- for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
- assertEquals(
- "12:00 AM",
- Utils.getDurationString(
- RuntimeEnvironment.application,
- 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(
- RuntimeEnvironment.application,
- DATE_THIS_YEAR_2_1_MS,
- DATE_THIS_YEAR_2_1_MS,
- DATE_THIS_YEAR_2_1_MS,
- useShortFormat,
- DateUtils.FORMAT_24HOUR));
- }
- }
-
- @Test
- public void testIsInGivenDay() {
- assertTrue(
- Utils.isInGivenDay(
- new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
- new GregorianCalendar(2015, Calendar.JANUARY, 1, 0, 30).getTimeInMillis()));
- }
-
- @Test
- public void testIsNotInGivenDay() {
- assertFalse(
- Utils.isInGivenDay(
- new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
- new GregorianCalendar(2015, Calendar.JANUARY, 2).getTimeInMillis()));
- }
-
- @Test
- public void testIfTimeZoneApplied() {
- TimeZone timeZone = TimeZone.getDefault();
-
- TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
-
- // 2015.01.01 00:00 in KST = 2014.12.31 15:00 in UTC
- long date2015StartMs = new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis();
-
- // 2015.01.01 10:00 in KST = 2015.01.01 01:00 in UTC
- long date2015Start10AMMs =
- new GregorianCalendar(2015, Calendar.JANUARY, 1, 10, 0).getTimeInMillis();
-
- // Those two times aren't in the same day in UTC, but they are in KST.
- assertTrue(Utils.isInGivenDay(date2015StartMs, date2015Start10AMMs));
-
- TimeZone.setDefault(timeZone);
- }
-
- @Test
- public void testIsInternalTvInputInvalidInternalInputId() {
- String inputId = "tv.comp";
- assertFalse(Utils.isInternalTvInput(RuntimeEnvironment.application, inputId));
- }
-}
diff --git a/tests/unit/Android.mk b/tests/unit/Android.mk
index 80dbfeef..5ea7ccd8 100644
--- a/tests/unit/Android.mk
+++ b/tests/unit/Android.mk
@@ -9,7 +9,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
androidx.test.runner \
- mockito-robolectric-prebuilt \
+ mockito-target \
tv-test-common \
LOCAL_JAVA_LIBRARIES := \
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index 5ee17de2..c7d2f528 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests" >
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23" />
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
index 052123c0..4b85eaae 100644
--- a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
+++ b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
@@ -53,9 +53,9 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
public void testOnSeekRequested() {
long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3;
mMediator.onSeekRequested(seekToTimeMs);
- assertWithMessage("Seek request time")
- .that(mMediator.mSeekRequestTimeMs)
- .isNotSameInstanceAs(INVALID_TIME);
+ assertWithMessage("Seek request time")
+ .that(mMediator.mSeekRequestTimeMs)
+ .isNotSameAs(INVALID_TIME);
assertWithMessage("Current position")
.that(mMediator.mCurrentPositionMs)
.isEqualTo(seekToTimeMs);
@@ -68,15 +68,15 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
long newCurrentTimeMs = seekToTimeMs + REQUEST_TIMEOUT_MS;
mMediator.onSeekRequested(seekToTimeMs);
mMediator.onCurrentPositionChanged(newCurrentTimeMs);
- assertWithMessage("Seek request time")
- .that(mMediator.mSeekRequestTimeMs)
- .isNotSameInstanceAs(INVALID_TIME);
- assertWithMessage("Current position")
- .that(mMediator.mCurrentPositionMs)
- .isNotSameInstanceAs(seekToTimeMs);
- assertWithMessage("Current position")
- .that(mMediator.mCurrentPositionMs)
- .isNotSameInstanceAs(newCurrentTimeMs);
+ assertWithMessage("Seek request time")
+ .that(mMediator.mSeekRequestTimeMs)
+ .isNotSameAs(INVALID_TIME);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isNotSameAs(seekToTimeMs);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isNotSameAs(newCurrentTimeMs);
}
@UiThreadTest
diff --git a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
index ecae18a2..71ccaf35 100644
--- a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
@@ -56,7 +56,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
+import org.mockito.Matchers;
import org.mockito.Mockito;
/**
@@ -92,29 +92,35 @@ public class ChannelDataManagerTest {
mContentResolver = new FakeContentResolver();
mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
mListener = new TestChannelDataManagerListener();
- getInstrumentation()
- .runOnMainSync(
- new Runnable() {
- @Override
- public void run() {
- TvInputManagerHelper mockHelper = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(mockHelper.hasTvInputInfo(ArgumentMatchers.anyString()))
- .thenReturn(true);
- Context mockContext = Mockito.mock(Context.class);
- Mockito.when(mockContext.getContentResolver()).thenReturn(mContentResolver);
- Mockito.when(mockContext.checkSelfPermission(ArgumentMatchers.anyString()))
- .thenAnswer(
- invocation -> {
- Object[] args = invocation.getArguments();
- return getTargetContext().checkSelfPermission(((String) args[0]));
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ TvInputManagerHelper mockHelper =
+ Mockito.mock(TvInputManagerHelper.class);
+ Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString()))
+ .thenReturn(true);
+ Context mockContext = Mockito.mock(Context.class);
+ Mockito.when(mockContext.getContentResolver())
+ .thenReturn(mContentResolver);
+ Mockito.when(mockContext.checkSelfPermission(Matchers.anyString()))
+ .thenAnswer(
+ invocation -> {
+ Object[] args = invocation.getArguments();
+ return getTargetContext()
+ .checkSelfPermission(((String) args[0]));
+ });
+
+ mChannelDataManager =
+ new ChannelDataManager(
+ mockContext,
+ mockHelper,
+ AsyncTask.SERIAL_EXECUTOR,
+ mContentResolver);
+ mChannelDataManager.addListener(mListener);
+ }
});
-
- mChannelDataManager =
- new ChannelDataManager(
- mockContext, mockHelper, AsyncTask.SERIAL_EXECUTOR, mContentResolver);
- mChannelDataManager.addListener(mListener);
- }
- });
}
@After
diff --git a/tests/unit/src/com/android/tv/data/ChannelImplTest.java b/tests/unit/src/com/android/tv/data/ChannelImplTest.java
index df2f1a1f..86cfab66 100644
--- a/tests/unit/src/com/android/tv/data/ChannelImplTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelImplTest.java
@@ -25,24 +25,20 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-
import com.android.tv.data.api.Channel;
import com.android.tv.testing.ComparatorTester;
import com.android.tv.util.TvInputManagerHelper;
-
+import java.util.Comparator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
+import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.Comparator;
-
/** Tests for {@link ChannelImpl}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -50,7 +46,7 @@ public class ChannelImplTest {
// Used for testing TV inputs with invalid input package. This could happen when a TV input is
// uninstalled while drawing an app link card.
private static final String INVALID_TV_INPUT_PACKAGE_NAME = "com.android.tv.invalid_tv_input";
- // Used for testing TV inputs defined inside of TV app.
+ // Used for testing TV inputs defined inside of Live TV.
private static final String LIVE_CHANNELS_PACKAGE_NAME = "com.android.tv";
// Used for testing a TV input which doesn't have its leanback launcher activity.
private static final String NONE_LEANBACK_TV_INPUT_PACKAGE_NAME =
@@ -119,7 +115,7 @@ public class ChannelImplTest {
}
})
.when(mockPackageManager)
- .getActivityInfo(ArgumentMatchers.<ComponentName>any(), ArgumentMatchers.anyInt());
+ .getActivityInfo(Mockito.<ComponentName>any(), Mockito.anyInt());
mMockContext = Mockito.mock(Context.class);
Mockito.when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
@@ -257,7 +253,7 @@ public class ChannelImplTest {
@Test
public void testComparator() {
TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(manager.isPartnerInput(ArgumentMatchers.anyString()))
+ Mockito.when(manager.isPartnerInput(Matchers.anyString()))
.thenAnswer(
new Answer<Boolean>() {
@Override
@@ -267,18 +263,17 @@ public class ChannelImplTest {
}
});
Comparator<Channel> comparator = new TestChannelComparator(manager);
- ComparatorTester comparatorTester =
- new ComparatorTester(comparator).permitInconsistencyWithEquals();
- comparatorTester.addEqualityGroup(
+ ComparatorTester<Channel> comparatorTester = ComparatorTester.withoutEqualsTest(comparator);
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId(PARTNER_INPUT_ID).build());
- comparatorTester.addEqualityGroup(new ChannelImpl.Builder().setInputId("1").build());
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(new ChannelImpl.Builder().setInputId("1").build());
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId("1").setDisplayNumber("2").build());
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId("2").setDisplayNumber("1.0").build());
// display name does not affect comparator
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder()
.setInputId("2")
.setDisplayNumber("1.62")
@@ -294,12 +289,12 @@ public class ChannelImplTest {
.setDisplayNumber("1.62")
.setDisplayName("test3")
.build());
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId("2").setDisplayNumber("2.0").build());
// Numeric display number sorting
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId("2").setDisplayNumber("12.2").build());
- comparatorTester.testCompare();
+ comparatorTester.test();
}
/**
@@ -311,7 +306,7 @@ public class ChannelImplTest {
@Test
public void testComparatorLabel() {
TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(manager.isPartnerInput(ArgumentMatchers.anyString()))
+ Mockito.when(manager.isPartnerInput(Matchers.anyString()))
.thenAnswer(
new Answer<Boolean>() {
@Override
@@ -321,21 +316,20 @@ public class ChannelImplTest {
}
});
Comparator<Channel> comparator = new ChannelComparatorWithDescriptionAsLabel(manager);
- ComparatorTester comparatorTester =
- new ComparatorTester(comparator).permitInconsistencyWithEquals();
+ ComparatorTester<Channel> comparatorTester = ComparatorTester.withoutEqualsTest(comparator);
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setInputId(PARTNER_INPUT_ID).setDescription("A").build());
// The description is used as a label for this test.
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setDescription("A").setInputId("1").build());
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setDescription("A").setInputId("2").build());
- comparatorTester.addEqualityGroup(
+ comparatorTester.addComparableGroup(
new ChannelImpl.Builder().setDescription("B").setInputId("1").build());
- comparatorTester.testCompare();
+ comparatorTester.test();
}
@Test
diff --git a/tests/unit/src/com/android/tv/features/FeaturesTest.java b/tests/unit/src/com/android/tv/features/FeaturesTest.java
new file mode 100644
index 00000000..e35758c3
--- /dev/null
+++ b/tests/unit/src/com/android/tv/features/FeaturesTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.features;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test for features. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FeaturesTest {
+ @Test
+ public void testPropertyFeatureKeyLength() {
+ // This forces the class to be loaded and verifies all PropertyFeature key lengths.
+ // If any keys are too long the test will fail to load.
+ assertThat(TvFeatures.TEST_FEATURE.isEnabled(null)).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/tv/menu/MenuTest.java b/tests/unit/src/com/android/tv/menu/MenuTest.java
index 7058316e..e384c398 100644
--- a/tests/unit/src/com/android/tv/menu/MenuTest.java
+++ b/tests/unit/src/com/android/tv/menu/MenuTest.java
@@ -25,7 +25,6 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -43,10 +42,8 @@ public class MenuTest {
public void setUp() {
mMenuView = Mockito.mock(IMenuView.class);
MenuRowFactory factory = Mockito.mock(MenuRowFactory.class);
- Mockito.when(
- factory.createMenuRow(
- ArgumentMatchers.any(Menu.class), ArgumentMatchers.any(Class.class)))
- .thenReturn(null);
+ Mockito.when(factory.createMenuRow(Mockito.any(Menu.class), Mockito.any(Class.class)))
+ .thenReturn(null);
mVisibilityChangeListener = Mockito.mock(OnMenuVisibilityChangeListener.class);
mMenu = new Menu(getTargetContext(), mMenuView, factory, mVisibilityChangeListener);
mMenu.disableAnimationForTest();
diff --git a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
index 64a055a2..5ecbdf02 100644
--- a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
+++ b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
@@ -24,7 +24,6 @@ import android.os.SystemClock;
import android.text.TextUtils;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
import com.android.tv.testing.activities.BaseMainActivityTestCase;
import com.android.tv.testing.constants.Constants;
import com.android.tv.testing.testinput.ChannelState;
@@ -50,9 +49,7 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
@Before
public void setUp() {
super.setUp();
- mTvOptionsRowAdapter =
- new TvOptionsRowAdapter(
- mActivity, Collections.emptyList(), DefaultLegacyFlags.DEFAULT);
+ mTvOptionsRowAdapter = new TvOptionsRowAdapter(mActivity, Collections.emptyList());
tuneToChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
waitUntilAudioTracksHaveSize(1);
waitUntilAudioTrackSelected(ChannelState.DEFAULT.getSelectedAudioTrackId());
@@ -76,10 +73,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilAudioTrackSelected(Constants.EN_STEREO_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertWithMessage("update Action had change").that(result).isTrue();
- assertWithMessage("Multi Audio enabled")
- .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
- .isTrue();
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isTrue();
}
@Test
@@ -94,10 +91,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilAudioTrackSelected(Constants.GENERIC_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertWithMessage("update Action had change").that(result).isTrue();
- assertWithMessage("Multi Audio enabled")
- .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
- .isFalse();
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isFalse();
}
@Test
@@ -113,10 +110,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilVideoTrackSelected(data.mSelectedVideoTrackId);
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertWithMessage("update Action had change").that(result).isTrue();
- assertWithMessage("Multi Audio enabled")
- .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
- .isFalse();
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isFalse();
}
private void waitUntilAudioTracksHaveSize(int expected) {
diff --git a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
index eb012f49..b929a0ae 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
@@ -26,7 +26,7 @@ import java.util.List;
import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
-import org.mockito.ArgumentMatchers;
+import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -57,16 +57,17 @@ public class RecommendationUtils {
})
.when(dataManager)
.getChannelRecords();
- Mockito.doAnswer(
- new Answer<ChannelRecord>() {
- @Override
- public ChannelRecord answer(InvocationOnMock invocation) throws Throwable {
- long channelId = (long) invocation.getArguments()[0];
- return channelRecordSortedMap.get(channelId);
- }
- })
- .when(dataManager)
- .getChannelRecord(ArgumentMatchers.anyLong());
+ Mockito.doAnswer(
+ new Answer<ChannelRecord>() {
+ @Override
+ public ChannelRecord answer(InvocationOnMock invocation)
+ throws Throwable {
+ long channelId = (long) invocation.getArguments()[0];
+ return channelRecordSortedMap.get(channelId);
+ }
+ })
+ .when(dataManager)
+ .getChannelRecord(Matchers.anyLong());
return dataManager;
}
@@ -130,7 +131,7 @@ public class RecommendationUtils {
// Time hopping with random minutes.
latestWatchEndTimeMs += TimeUnit.MINUTES.toMillis(mRandom.nextInt(30) + 1);
}
- long watchedDurationMs = mRandom.nextInt((int) maxWatchDurationMs) + 1L;
+ long watchedDurationMs = mRandom.nextInt((int) maxWatchDurationMs) + 1;
if (!addWatchLog(channelId, latestWatchEndTimeMs, watchedDurationMs)) {
return false;
}
diff --git a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
index 6cb0e08c..d9149050 100644
--- a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
@@ -17,22 +17,17 @@
package com.android.tv.recommendation;
import static com.google.common.truth.Truth.assertThat;
-
import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.recommendation.RoutineWatchEvaluator.ProgramTime;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/** Tests for {@link RoutineWatchEvaluator}. */
@SmallTest
@@ -126,15 +121,15 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
@Test
public void testCalculateTitleMatchScore_longerMatchIsBetter() {
String base = "foo bar baz";
- assertThat(
- new ScoredItem[] {
- score(base, ""),
- score(base, "bar"),
- score(base, "foo bar"),
- score(base, "foo bar baz")
- })
- .asList()
- .isInOrder();
+ assertThat(
+ new ScoredItem[] {
+ score(base, ""),
+ score(base, "bar"),
+ score(base, "foo bar"),
+ score(base, "foo bar baz")
+ })
+ .asList()
+ .isOrdered();
}
@Test
@@ -325,7 +320,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
private Program createDummyProgram(Calendar startTime, long programDurationMs) {
long startTimeMs = startTime.getTimeInMillis();
- return new ProgramImpl.Builder()
+ return new Program.Builder()
.setStartTimeUtcMillis(startTimeMs)
.setEndTimeUtcMillis(startTimeMs + programDurationMs)
.build();
diff --git a/tests/unit/src/com/android/tv/util/MockTvSingletons.java b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
index d9ff5e71..fd4b43cf 100644
--- a/tests/unit/src/com/android/tv/util/MockTvSingletons.java
+++ b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
@@ -17,15 +17,16 @@
package com.android.tv.util;
import android.content.Context;
-
import com.android.tv.InputSessionManager;
import com.android.tv.MainActivityWrapper;
import com.android.tv.TvApplication;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
+import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
import com.android.tv.common.flags.impl.DefaultUiFlags;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.singletons.HasSingletons;
@@ -33,6 +34,7 @@ import com.android.tv.common.util.Clock;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -40,14 +42,11 @@ import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.recorder.RecordingScheduler;
import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.testing.fakes.FakeClock;
+import com.android.tv.testing.FakeClock;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-
import com.google.common.base.Optional;
-
-import dagger.Lazy;
-
import java.util.concurrent.Executor;
+import javax.inject.Provider;
/** Mock {@link TvSingletons} class. */
public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingletons> {
@@ -57,6 +56,8 @@ public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingleton
private final DefaultBackendKnobsFlags mBackendFlags = new DefaultBackendKnobsFlags();
private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
private final DefaultUiFlags mUiFlags = new DefaultUiFlags();
+ private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
+ new DefaultConcurrentDvrPlaybackFlags();
private PerformanceMonitor mPerformanceMonitor;
public MockTvSingletons(Context context) {
@@ -77,11 +78,21 @@ public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingleton
}
@Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return mApp.isChannelDataManagerLoadFinished();
+ }
+
+ @Override
public ProgramDataManager getProgramDataManager() {
return mApp.getProgramDataManager();
}
@Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return mApp.isProgramDataManagerCurrentProgramsLoadFinished();
+ }
+
+ @Override
public PreviewDataManager getPreviewDataManager() {
return mApp.getPreviewDataManager();
}
@@ -137,11 +148,16 @@ public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingleton
}
@Override
- public Lazy<EpgReader> providesEpgReader() {
+ public Provider<EpgReader> providesEpgReader() {
return mApp.providesEpgReader();
}
@Override
+ public EpgFetcher getEpgFetcher() {
+ return mApp.getEpgFetcher();
+ }
+
+ @Override
public SetupUtils getSetupUtils() {
return mApp.getSetupUtils();
}
@@ -152,11 +168,21 @@ public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingleton
}
@Override
+ public ExperimentLoader getExperimentLoader() {
+ return mApp.getExperimentLoader();
+ }
+
+ @Override
public MainActivityWrapper getMainActivityWrapper() {
return mApp.getMainActivityWrapper();
}
@Override
+ public com.android.tv.util.account.AccountHelper getAccountHelper() {
+ return mApp.getAccountHelper();
+ }
+
+ @Override
public boolean isRunningInMainProcess() {
return mApp.isRunningInMainProcess();
}
@@ -196,6 +222,11 @@ public class MockTvSingletons implements TvSingletons, HasSingletons<TvSingleton
}
@Override
+ public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ @Override
public TvSingletons singletons() {
return this;
}
diff --git a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
index ab3c5e79..7e35d76b 100644
--- a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
+++ b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
@@ -20,24 +20,19 @@ import static androidx.test.InstrumentationRegistry.getContext;
import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-
import com.android.tv.testing.ComparatorTester;
import com.android.tv.testing.utils.TestUtils;
-
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
/** Test for {@link TvInputManagerHelper} */
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -92,13 +87,13 @@ public class TvInputManagerHelperTest {
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester comparatorTester =
- new ComparatorTester(new TvInputManagerHelper.InputComparatorInternal(manager))
- .permitInconsistencyWithEquals();
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.InputComparatorInternal(manager));
for (TvInputInfo input : inputs) {
- comparatorTester.addEqualityGroup(input);
+ comparatorTester.addComparableGroup(input);
}
- comparatorTester.testCompare();
+ comparatorTester.test();
}
@Test
@@ -148,17 +143,15 @@ public class TvInputManagerHelperTest {
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester comparatorTester =
- new ComparatorTester(
- new TvInputManagerHelper.HardwareInputComparator(
- getContext(), manager))
- .permitInconsistencyWithEquals();
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
comparatorTester
- .addEqualityGroup(hdmi3)
- .addEqualityGroup(hdmi2)
- .addEqualityGroup(hdmi1)
- .addEqualityGroup(hdmi4)
- .testCompare();
+ .addComparableGroup(hdmi3)
+ .addComparableGroup(hdmi2)
+ .addComparableGroup(hdmi1)
+ .addComparableGroup(hdmi4)
+ .test();
}
@Test
@@ -209,12 +202,10 @@ public class TvInputManagerHelperTest {
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester comparatorTester =
- new ComparatorTester(
- new TvInputManagerHelper.HardwareInputComparator(
- getContext(), manager))
- .permitInconsistencyWithEquals();
- comparatorTester.addEqualityGroup(cec1).addEqualityGroup(cec2).testCompare();
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
+ comparatorTester.addComparableGroup(cec1).addComparableGroup(cec2).test();
}
private TvInputManagerHelper createMockTvInputManager() {
@@ -228,7 +219,7 @@ public class TvInputManagerHelperTest {
}
})
.when(manager)
- .isPartnerInput(ArgumentMatchers.<TvInputInfo>any());
+ .isPartnerInput(Mockito.<TvInputInfo>any());
Mockito.doAnswer(
new Answer<String>() {
@Override
@@ -238,7 +229,7 @@ public class TvInputManagerHelperTest {
}
})
.when(manager)
- .loadLabel(ArgumentMatchers.<TvInputInfo>any());
+ .loadLabel(Mockito.<TvInputInfo>any());
Mockito.doAnswer(
new Answer<String>() {
@Override
@@ -248,7 +239,7 @@ public class TvInputManagerHelperTest {
}
})
.when(manager)
- .loadCustomLabel(ArgumentMatchers.<TvInputInfo>any());
+ .loadCustomLabel(Mockito.<TvInputInfo>any());
Mockito.doAnswer(
new Answer<TvInputInfo>() {
@Override
@@ -260,7 +251,7 @@ public class TvInputManagerHelperTest {
}
})
.when(manager)
- .getTvInputInfo(ArgumentMatchers.<String>any());
+ .getTvInputInfo(Mockito.<String>any());
return manager;
}
diff --git a/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java b/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java
index 6e968249..41722135 100644
--- a/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java
+++ b/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java
@@ -52,28 +52,28 @@ public class ImageCacheTest {
public void testPutIfLarger_smaller() throws Exception {
mImageCache.putIfNeeded(INFO_50);
- assertWithMessage("before").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_50);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_50);
mImageCache.putIfNeeded(INFO_25);
- assertWithMessage("after").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_50);
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_50);
}
@Test
public void testPutIfLarger_larger() throws Exception {
mImageCache.putIfNeeded(INFO_50);
- assertWithMessage("before").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_50);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_50);
mImageCache.putIfNeeded(INFO_100);
- assertWithMessage("after").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_100);
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_100);
}
@Test
public void testPutIfLarger_alreadyMax() throws Exception {
mImageCache.putIfNeeded(INFO_100);
- assertWithMessage("before").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_100);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_100);
mImageCache.putIfNeeded(INFO_200);
- assertWithMessage("after").that(mImageCache.get(KEY)).isSameInstanceAs(INFO_100);
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_100);
}
}
diff --git a/tuner/Android.bp b/tuner/Android.bp
index d1df99fc..215a1e53 100644
--- a/tuner/Android.bp
+++ b/tuner/Android.bp
@@ -20,25 +20,25 @@ android_library {
sdk_version: "system_current",
resource_dirs: ["res"],
libs: [
- "android-support-annotations",
- "android-support-compat",
- "android-support-core-ui",
- "android-support-v7-palette",
- "android-support-v7-recyclerview",
- "androidx.leanback_leanback",
- "androidx.tvprovider_tvprovider",
- "jsr330",
- "live-tv-tuner-proto",
"tv-auto-value-jar",
"tv-auto-factory-jar",
- "tv-common",
+ "android-support-annotations",
"tv-error-prone-annotations-jar",
"tv-guava-android-jar",
"tv-javax-annotations-jar",
+ "jsr330",
"tv-lib-dagger",
"tv-lib-exoplayer",
"tv-lib-exoplayer-v2-core",
+ "live-tv-tuner-proto",
+ "android-support-compat",
+ "android-support-core-ui",
+ "android-support-v7-palette",
+ "android-support-v7-recyclerview",
+ "android-support-v17-leanback",
+ "androidx.tvprovider_tvprovider",
"tv-lib-dagger-android",
+ "tv-common",
],
plugins: [
"tv-auto-value",
diff --git a/tuner/AndroidManifest.xml b/tuner/AndroidManifest.xml
index c084f3fc..fd217717 100644
--- a/tuner/AndroidManifest.xml
+++ b/tuner/AndroidManifest.xml
@@ -18,7 +18,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.tv.tuner"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application tools:replace="android:appComponentFactory"
android:appComponentFactory="android.support.v4.app.CoreComponentFactory" />
</manifest>
diff --git a/tuner/SampleDvbTuner/AndroidManifest.xml b/tuner/SampleDvbTuner/AndroidManifest.xml
index da23f84a..5ad927e3 100755
--- a/tuner/SampleDvbTuner/AndroidManifest.xml
+++ b/tuner/SampleDvbTuner/AndroidManifest.xml
@@ -19,7 +19,7 @@
<uses-sdk
android:minSdkVersion="23"
- android:targetSdkVersion="28" />
+ android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -29,8 +29,6 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
- <!-- Permission to modify Recorded Program -->
- <uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA" />
<!-- Permissions/feature for USB tuner -->
<uses-permission android:name="android.permission.DVB_DEVICE" />
diff --git a/tuner/SampleDvbTuner/build.gradle b/tuner/SampleDvbTuner/build.gradle
index 28ad3e4a..657a4258 100644
--- a/tuner/SampleDvbTuner/build.gradle
+++ b/tuner/SampleDvbTuner/build.gradle
@@ -19,35 +19,48 @@
* Experimental gradle configuration. This file may not be up to date.
*/
+buildscript {
+ repositories {
+ mavenCentral()
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
+ }
+}
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
-
android {
- compileSdkVersion 28
- buildToolsVersion '28.0.3'
+ compileSdkVersion 26
+ buildToolsVersion '28.0.2'
- compileOptions() {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ dexOptions {
+ preDexLibraries = false
+ additionalParameters=['--core-library']
+ javaMaxHeapSize "6g"
+ }
+ android {
+ defaultConfig {
+ resConfigs "en"
+ }
}
-
defaultConfig {
minSdkVersion 23
- resConfigs "en"
- targetSdkVersion 28
+ targetSdkVersion 26
versionCode 1
versionName "1.0"
}
-
buildTypes {
debug {
minifyEnabled false
}
- release {
- minifyEnabled true
- }
}
-
+ compileOptions() {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
sourceSets {
main {
res.srcDirs = ['res']
@@ -57,18 +70,22 @@ android {
}
}
-dependencies {
- implementation 'androidx.leanback:leanback:1.1.0-alpha02'
- implementation 'androidx.palette:palette:1.0.0'
- implementation 'androidx.tvprovider:tvprovider:1.0.0'
-
- annotationProcessor 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.dagger:dagger:2.23'
- implementation 'com.google.dagger:dagger-android:2.23'
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.23'
- annotationProcessor 'com.google.dagger:dagger-compiler:2.23'
+repositories {
+ mavenCentral()
+ jcenter()
+ google()
+}
- implementation project(':common')
- implementation project(':tuner')
+final String SUPPORT_LIBS_VERSION = '26.1.0'
+dependencies {
+ implementation 'com.google.android.exoplayer:exoplayer-core:2.9.0'
+ implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'
+ implementation "com.android.support:palette-v7:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:leanback-v17:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:support-tv-provider:${SUPPORT_LIBS_VERSION}"
+ /*Not building with latest one (1.6.2)*/
+ annotationProcessor 'com.google.auto.value:auto-value:1.5.4'
+ implementation 'com.google.auto.value:auto-value:1.5.4'
+ implementation project(':common')
+ implementation project(':tuner')
}
diff --git a/tuner/SampleDvbTuner/robotests/javatests/com/android/tv/tuner/sample/dvb/util/SampleDvbConstantsTest.java b/tuner/SampleDvbTuner/robotests/javatests/com/android/tv/tuner/sample/dvb/util/SampleDvbConstantsTest.java
deleted file mode 100644
index 52fcffd6..00000000
--- a/tuner/SampleDvbTuner/robotests/javatests/com/android/tv/tuner/sample/dvb/util/SampleDvbConstantsTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.sample.dvb.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ComponentName;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.sample.dvb.tvinput.SampleDvbTunerTvInputService;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link SampleDvbConstants}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SampleDvbConstantsTest {
-
- @Test
- public void tunerInputId() {
- assertThat(ComponentName.unflattenFromString(SampleDvbConstants.TUNER_INPUT_ID))
- .isEqualTo(
- new ComponentName(
- ApplicationProvider.getApplicationContext(),
- SampleDvbTunerTvInputService.class));
- }
-}
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/AndroidManifest.xml b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/AndroidManifest.xml
index 8732b0d8..dc042286 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/AndroidManifest.xml
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/AndroidManifest.xml
@@ -27,8 +27,6 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
- <!-- Permission to modify Recorded Program -->
- <uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA" />
<!-- Permissions/feature for USB tuner -->
<uses-permission android:name="android.permission.DVB_DEVICE" />
@@ -38,7 +36,7 @@
<uses-feature android:name="android.software.leanback" android:required="true" />
<uses-feature android:name="android.software.live_tv" android:required="true" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application
android:name=".app.SampleDvbTuner"
android:icon="@mipmap/ic_launcher"
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTuner.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTuner.java
index 5c9e8420..568e3c98 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTuner.java
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTuner.java
@@ -18,18 +18,16 @@ package com.android.tv.tuner.sample.dvb.app;
import android.content.ComponentName;
import android.media.tv.TvContract;
-
import com.android.tv.common.BaseApplication;
-import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.tuner.modules.TunerSingletonsModule;
import com.android.tv.tuner.sample.dvb.singletons.SampleDvbSingletons;
import com.android.tv.tuner.sample.dvb.tvinput.SampleDvbTunerTvInputService;
-
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactoryImpl;
import dagger.android.AndroidInjector;
-
import com.android.tv.common.flags.CloudEpgFlags;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import javax.inject.Inject;
/** The top level application for Sample DVB Tuner. */
@@ -38,6 +36,8 @@ public class SampleDvbTuner extends BaseApplication
private String mEmbeddedInputId;
@Inject CloudEpgFlags mCloudEpgFlags;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TunerSessionFactoryImpl mTunerSessionFactory;
@Override
public void onCreate() {
@@ -47,7 +47,7 @@ public class SampleDvbTuner extends BaseApplication
@Override
protected AndroidInjector<SampleDvbTuner> applicationInjector() {
return DaggerSampleDvbTunerComponent.builder()
- .applicationModule(new ApplicationModule(this))
+ .sampleDvbTunerModule(new SampleDvbTunerModule(this))
.tunerSingletonsModule(new TunerSingletonsModule(this))
.build();
}
@@ -73,7 +73,16 @@ public class SampleDvbTuner extends BaseApplication
}
@Override
+ public ConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ @Override
public SampleDvbSingletons singletons() {
return this;
}
+
+ public TunerSessionFactory getTunerSessionFactory() {
+ return mTunerSessionFactory;
+ }
}
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerModule.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerModule.java
index aaaa1011..4da3ca9d 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerModule.java
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerModule.java
@@ -15,30 +15,38 @@
*/
package com.android.tv.tuner.sample.dvb.app;
-import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.flags.impl.DefaultFlagsModule;
import com.android.tv.tuner.api.TunerFactory;
-import com.android.tv.tuner.dvb.DvbTunerHalFactory;
+import com.android.tv.tuner.builtin.BuiltInTunerHalFactory;
import com.android.tv.tuner.modules.TunerModule;
import com.android.tv.tuner.sample.dvb.setup.SampleDvbTunerSetupActivity;
import com.android.tv.tuner.sample.dvb.tvinput.SampleDvbTunerTvInputService;
-
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
import dagger.Module;
import dagger.Provides;
/** Dagger module for {@link SampleDvbTuner}. */
@Module(
includes = {
- ApplicationModule.class,
DefaultFlagsModule.class,
SampleDvbTunerTvInputService.Module.class,
SampleDvbTunerSetupActivity.Module.class,
TunerModule.class,
})
class SampleDvbTunerModule {
+ private final SampleDvbTuner mSampleDvbTuner;
+
+ SampleDvbTunerModule(SampleDvbTuner sampleDvbTuner) {
+ mSampleDvbTuner = sampleDvbTuner;
+ }
+
+ @Provides
+ public TunerSessionFactory providesTunerSessionFactory() {
+ return mSampleDvbTuner.getTunerSessionFactory();
+ }
@Provides
TunerFactory providesTunerFactory() {
- return DvbTunerHalFactory.INSTANCE;
+ return BuiltInTunerHalFactory.INSTANCE;
}
}
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/setup/SampleDvbTunerSetupActivity.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/setup/SampleDvbTunerSetupActivity.java
index e2b5063c..f9ef29c4 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/setup/SampleDvbTunerSetupActivity.java
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/setup/SampleDvbTunerSetupActivity.java
@@ -36,7 +36,6 @@ import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.common.util.PostalCodeUtils;
import com.android.tv.tuner.sample.dvb.R;
-import com.android.tv.tuner.sample.dvb.util.SampleDvbConstants;
import com.android.tv.tuner.setup.BaseTunerSetupActivity;
import com.android.tv.tuner.setup.ConnectionTypeFragment;
import com.android.tv.tuner.setup.LineupFragment;
@@ -56,7 +55,7 @@ import dagger.android.ContributesAndroidInjector;
import java.util.ArrayList;
import java.util.List;
-/** An activity that serves Sample DVB tuner setup process. */
+/** An activity that serves Live TV tuner setup process. */
public class SampleDvbTunerSetupActivity extends BaseTunerSetupActivity {
private static final String TAG = "SampleDvbTunerSetupActivity";
private static final boolean DEBUG = false;
@@ -79,10 +78,6 @@ public class SampleDvbTunerSetupActivity extends BaseTunerSetupActivity {
private final Runnable cancelFetchLineupTaskRunnable = this::cancelFetchLineup;
private String embeddedInputId;
- public SampleDvbTunerSetupActivity() {
- super(SampleDvbConstants.TUNER_INPUT_ID);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -198,7 +193,6 @@ public class SampleDvbTunerSetupActivity extends BaseTunerSetupActivity {
case ScanFragment.ACTION_CATEGORY:
switch (actionId) {
case ScanFragment.ACTION_CANCEL:
- clearTunerHal();
getFragmentManager().popBackStack();
return true;
case ScanFragment.ACTION_FINISH:
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/util/SampleDvbConstants.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/util/SampleDvbConstants.java
deleted file mode 100644
index f7b34cef..00000000
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/util/SampleDvbConstants.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.sample.dvb.util;
-
-/** Static constants for Sample DVB Tuner */
-public final class SampleDvbConstants {
-
- /** The Input ID for the embedded tuner in Sample DVB Tuner */
- public static final String TUNER_INPUT_ID =
- "com.android.tv.tuner.sample.dvb/.tvinput.SampleDvbTunerTvInputService";
-
- private SampleDvbConstants() {}
-}
diff --git a/tuner/SampleNetworkTuner/AndroidManifest.xml b/tuner/SampleNetworkTuner/AndroidManifest.xml
index 22b03567..0ec9afca 100755
--- a/tuner/SampleNetworkTuner/AndroidManifest.xml
+++ b/tuner/SampleNetworkTuner/AndroidManifest.xml
@@ -19,19 +19,16 @@
<uses-sdk
android:minSdkVersion="23"
- android:targetSdkVersion="28" />
+ android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTENT_RATING_SYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_TV_LISTINGS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
- <!-- Permission to modify Recorded Program -->
- <uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA" />
<!-- Permissions/feature for USB tuner -->
<uses-permission android:name="android.permission.DVB_DEVICE" />
diff --git a/tuner/SampleNetworkTuner/build.gradle b/tuner/SampleNetworkTuner/build.gradle
index 28ad3e4a..657a4258 100644
--- a/tuner/SampleNetworkTuner/build.gradle
+++ b/tuner/SampleNetworkTuner/build.gradle
@@ -19,35 +19,48 @@
* Experimental gradle configuration. This file may not be up to date.
*/
+buildscript {
+ repositories {
+ mavenCentral()
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
+ }
+}
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
-
android {
- compileSdkVersion 28
- buildToolsVersion '28.0.3'
+ compileSdkVersion 26
+ buildToolsVersion '28.0.2'
- compileOptions() {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ dexOptions {
+ preDexLibraries = false
+ additionalParameters=['--core-library']
+ javaMaxHeapSize "6g"
+ }
+ android {
+ defaultConfig {
+ resConfigs "en"
+ }
}
-
defaultConfig {
minSdkVersion 23
- resConfigs "en"
- targetSdkVersion 28
+ targetSdkVersion 26
versionCode 1
versionName "1.0"
}
-
buildTypes {
debug {
minifyEnabled false
}
- release {
- minifyEnabled true
- }
}
-
+ compileOptions() {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
sourceSets {
main {
res.srcDirs = ['res']
@@ -57,18 +70,22 @@ android {
}
}
-dependencies {
- implementation 'androidx.leanback:leanback:1.1.0-alpha02'
- implementation 'androidx.palette:palette:1.0.0'
- implementation 'androidx.tvprovider:tvprovider:1.0.0'
-
- annotationProcessor 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.auto.value:auto-value:1.5.3'
- implementation 'com.google.dagger:dagger:2.23'
- implementation 'com.google.dagger:dagger-android:2.23'
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.23'
- annotationProcessor 'com.google.dagger:dagger-compiler:2.23'
+repositories {
+ mavenCentral()
+ jcenter()
+ google()
+}
- implementation project(':common')
- implementation project(':tuner')
+final String SUPPORT_LIBS_VERSION = '26.1.0'
+dependencies {
+ implementation 'com.google.android.exoplayer:exoplayer-core:2.9.0'
+ implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'
+ implementation "com.android.support:palette-v7:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:leanback-v17:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:support-tv-provider:${SUPPORT_LIBS_VERSION}"
+ /*Not building with latest one (1.6.2)*/
+ annotationProcessor 'com.google.auto.value:auto-value:1.5.4'
+ implementation 'com.google.auto.value:auto-value:1.5.4'
+ implementation project(':common')
+ implementation project(':tuner')
}
diff --git a/tuner/SampleNetworkTuner/robotests/javatests/com/android/tv/tuner/sample/network/util/SampleNetworkConstantsTest.java b/tuner/SampleNetworkTuner/robotests/javatests/com/android/tv/tuner/sample/network/util/SampleNetworkConstantsTest.java
deleted file mode 100644
index 5c860ef0..00000000
--- a/tuner/SampleNetworkTuner/robotests/javatests/com/android/tv/tuner/sample/network/util/SampleNetworkConstantsTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.sample.network.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ComponentName;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.sample.network.tvinput.SampleNetworkTunerTvInputService;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link SampleNetworkConstants}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SampleNetworkConstantsTest {
-
- @Test
- public void tunerInputId() {
- assertThat(ComponentName.unflattenFromString(SampleNetworkConstants.TUNER_INPUT_ID))
- .isEqualTo(
- new ComponentName(
- ApplicationProvider.getApplicationContext(),
- SampleNetworkTunerTvInputService.class));
- }
-}
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/AndroidManifest.xml b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/AndroidManifest.xml
index 73313917..dddd8a4b 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/AndroidManifest.xml
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/AndroidManifest.xml
@@ -21,15 +21,12 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_CONTENT_RATING_SYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_TV_LISTINGS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
- <!-- Permission to modify Recorded Program -->
- <uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA" />
<!-- Permissions/feature for USB tuner -->
<uses-permission android:name="android.permission.DVB_DEVICE" />
@@ -39,7 +36,7 @@
<uses-feature android:name="android.software.leanback" android:required="true" />
<uses-feature android:name="android.software.live_tv" android:required="true" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application
android:name=".app.SampleNetworkTuner"
android:icon="@mipmap/ic_launcher"
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTuner.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTuner.java
index 0f9d24e6..eb5b2ad4 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTuner.java
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTuner.java
@@ -18,18 +18,16 @@ package com.android.tv.tuner.sample.network.app;
import android.content.ComponentName;
import android.media.tv.TvContract;
-
import com.android.tv.common.BaseApplication;
-import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.tuner.modules.TunerSingletonsModule;
import com.android.tv.tuner.sample.network.singletons.SampleNetworkSingletons;
import com.android.tv.tuner.sample.network.tvinput.SampleNetworkTunerTvInputService;
-
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactoryImpl;
import dagger.android.AndroidInjector;
-
import com.android.tv.common.flags.CloudEpgFlags;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import javax.inject.Inject;
/** The top level application for Sample DVB Tuner. */
@@ -38,6 +36,8 @@ public class SampleNetworkTuner extends BaseApplication
private String mEmbeddedInputId;
@Inject CloudEpgFlags mCloudEpgFlags;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TunerSessionFactoryImpl mTunerSessionFactory;
@Override
public void onCreate() {
@@ -47,7 +47,7 @@ public class SampleNetworkTuner extends BaseApplication
@Override
protected AndroidInjector<SampleNetworkTuner> applicationInjector() {
return DaggerSampleNetworkTunerComponent.builder()
- .applicationModule(new ApplicationModule(this))
+ .sampleNetworkTunerModule(new SampleNetworkTunerModule(this))
.tunerSingletonsModule(new TunerSingletonsModule(this))
.build();
}
@@ -73,7 +73,16 @@ public class SampleNetworkTuner extends BaseApplication
}
@Override
+ public ConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ @Override
public SampleNetworkSingletons singletons() {
return this;
}
+
+ public TunerSessionFactory getTunerSessionFactory() {
+ return mTunerSessionFactory;
+ }
}
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerModule.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerModule.java
index 3fa45027..d974e20a 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerModule.java
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerModule.java
@@ -15,30 +15,38 @@
*/
package com.android.tv.tuner.sample.network.app;
-import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.flags.impl.DefaultFlagsModule;
import com.android.tv.tuner.api.TunerFactory;
-import com.android.tv.tuner.hdhomerun.HdHomeRunTunerHalFactory;
+import com.android.tv.tuner.builtin.BuiltInTunerHalFactory;
import com.android.tv.tuner.modules.TunerModule;
import com.android.tv.tuner.sample.network.setup.SampleNetworkTunerSetupActivity;
import com.android.tv.tuner.sample.network.tvinput.SampleNetworkTunerTvInputService;
-
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
import dagger.Module;
import dagger.Provides;
/** Dagger module for {@link SampleNetworkTuner}. */
@Module(
includes = {
- ApplicationModule.class,
DefaultFlagsModule.class,
SampleNetworkTunerTvInputService.Module.class,
SampleNetworkTunerSetupActivity.Module.class,
TunerModule.class,
})
class SampleNetworkTunerModule {
+ private final SampleNetworkTuner mSampleNetworkTuner;
+
+ SampleNetworkTunerModule(SampleNetworkTuner sampleNetworkTuner) {
+ mSampleNetworkTuner = sampleNetworkTuner;
+ }
+
+ @Provides
+ public TunerSessionFactory providesTunerSessionFactory() {
+ return mSampleNetworkTuner.getTunerSessionFactory();
+ }
@Provides
TunerFactory providesTunerFactory() {
- return HdHomeRunTunerHalFactory.INSTANCE;
+ return BuiltInTunerHalFactory.INSTANCE;
}
}
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/setup/SampleNetworkTunerSetupActivity.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/setup/SampleNetworkTunerSetupActivity.java
index 755e0bb9..fd783c4f 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/setup/SampleNetworkTunerSetupActivity.java
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/setup/SampleNetworkTunerSetupActivity.java
@@ -36,7 +36,6 @@ import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.common.util.PostalCodeUtils;
import com.android.tv.tuner.sample.network.R;
-import com.android.tv.tuner.sample.network.util.SampleNetworkConstants;
import com.android.tv.tuner.setup.BaseTunerSetupActivity;
import com.android.tv.tuner.setup.ConnectionTypeFragment;
import com.android.tv.tuner.setup.LineupFragment;
@@ -56,7 +55,7 @@ import dagger.android.ContributesAndroidInjector;
import java.util.ArrayList;
import java.util.List;
-/** An activity that serves TV app tuner setup process. */
+/** An activity that serves Live TV tuner setup process. */
public class SampleNetworkTunerSetupActivity extends BaseTunerSetupActivity {
private static final String TAG = "SampleNetworkTunerSetupActivity";
private static final boolean DEBUG = false;
@@ -79,10 +78,6 @@ public class SampleNetworkTunerSetupActivity extends BaseTunerSetupActivity {
private final Runnable cancelFetchLineupTaskRunnable = this::cancelFetchLineup;
private String embeddedInputId;
- public SampleNetworkTunerSetupActivity() {
- super(SampleNetworkConstants.TUNER_INPUT_ID);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/util/SampleNetworkConstants.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/util/SampleNetworkConstants.java
deleted file mode 100644
index d0a8d254..00000000
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/util/SampleNetworkConstants.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.sample.network.util;
-
-/** Static constants for Sample Network Tuner */
-public final class SampleNetworkConstants {
-
- /** The Input ID for the embedded tuner in Sample Network Tuner */
- public static final String TUNER_INPUT_ID =
- "com.android.tv.tuner.sample.network/.tvinput.SampleNetworkTunerTvInputService";
-
- private SampleNetworkConstants() {}
-}
diff --git a/tuner/build.gradle b/tuner/build.gradle
index b00b4609..0f40a29b 100644
--- a/tuner/build.gradle
+++ b/tuner/build.gradle
@@ -21,24 +21,39 @@
apply plugin: 'com.android.library'
apply plugin: 'com.google.protobuf'
-
+buildscript {
+ repositories {
+ mavenCentral()
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
+ }
+}
android {
- compileSdkVersion 28
- buildToolsVersion '28.0.3'
+ compileSdkVersion 26
+ buildToolsVersion '28.0.2'
- compileOptions() {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ dexOptions {
+ preDexLibraries = false
+ additionalParameters = ['--core-library']
+ javaMaxHeapSize "6g"
+ }
+
+ android {
+ defaultConfig {
+ resConfigs "en"
+ }
}
defaultConfig {
minSdkVersion 23
- resConfigs "en"
- targetSdkVersion 28
+ targetSdkVersion 26
versionCode 1
versionName "1.0"
}
-
buildTypes {
debug {
minifyEnabled false
@@ -47,6 +62,10 @@ android {
minifyEnabled true
}
}
+ compileOptions() {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
sourceSets {
main {
@@ -54,54 +73,43 @@ android {
java.srcDirs = ['src']
manifest.srcFile 'AndroidManifest.xml'
proto {
- srcDir 'proto/src/main/proto'
+ srcDir 'proto/'
}
}
}
}
-dependencies {
- implementation 'androidx.annotation:annotation:1.1.0'
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.leanback:leanback:1.1.0-alpha02'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
- implementation 'androidx.tvprovider:tvprovider:1.0.0'
-
- implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'
- api 'com.google.android.exoplayer:exoplayer-core:2.10.1'
- annotationProcessor 'com.google.auto.factory:auto-factory:1.0-beta6'
- implementation 'com.google.auto.factory:auto-factory:1.0-beta6'
- implementation 'com.google.dagger:dagger:2.23'
- implementation 'com.google.dagger:dagger-android:2.23'
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.23'
- annotationProcessor 'com.google.dagger:dagger-compiler:2.23'
- implementation 'com.google.guava:guava:28.0-jre'
- implementation 'com.google.protobuf:protobuf-java:3.0.0'
+repositories {
+ mavenCentral()
+ google()
+ jcenter()
+}
- implementation project(':common')
+final String SUPPORT_LIBS_VERSION = '26.1.0'
+dependencies {
+ implementation 'com.google.android.exoplayer:exoplayer-core:2.9.0'
+ implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'
+ implementation "com.android.support:support-tv-provider:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:appcompat-v7:${SUPPORT_LIBS_VERSION}"
+ implementation "com.android.support:leanback-v17:${SUPPORT_LIBS_VERSION}"
+ implementation 'com.google.guava:guava:26.0-android'
+ implementation 'com.google.protobuf.nano:protobuf-javanano:3.2.0rc2'
+ implementation project(':common')
}
protobuf {
// Configure the protoc executable
protoc {
- artifact = 'com.google.protobuf:protoc:3.0.0'
-
- plugins {
- javalite {
- // The codegen for lite comes as a separate artifact
- artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
- }
- }
+ artifact = 'com.google.protobuf:protoc:3.1.0'
generateProtoTasks {
all().each {
task -> task.builtins {
remove java
- }
- task.plugins {
- javalite {}
+ javanano {
+ option "enum_style=java"
}
+ }
}
}
}
-}
+} \ No newline at end of file
diff --git a/tuner/proto/Android.bp b/tuner/proto/Android.bp
index d1728a64..67f35f82 100644
--- a/tuner/proto/Android.bp
+++ b/tuner/proto/Android.bp
@@ -19,7 +19,8 @@ java_library {
srcs: ["*.proto"],
sdk_version: "system_current",
proto: {
- type: "lite",
+ type: "nano",
+ output_params: ["enum_style=java"],
canonical_path_from_root: false,
},
min_sdk_version: "23",
diff --git a/tuner/proto/channel.proto b/tuner/proto/channel.proto
index 815ffbca..ff372ad5 100644
--- a/tuner/proto/channel.proto
+++ b/tuner/proto/channel.proto
@@ -18,13 +18,18 @@ syntax = 'proto2';
package com.android.tv.tuner.data;
-import "track.proto";
-
option java_package = "com.android.tv.tuner.data";
option java_outer_classname = "Channel";
+
+// AOSP_Comment_Out import "third_party/android/nanoproto/nano_descriptor.proto";
+
+import "track.proto";
+
// Holds information about a channel used in the tuners.
message TunerChannelProto {
+// AOSP_Comment_Out option (proto2.nano.message_as_lite) = false;
+
optional TunerType type = 1;
optional string short_name = 2;
optional string long_name = 3;
@@ -46,24 +51,22 @@ message TunerChannelProto {
optional int32 audio_track_index = 19;
repeated AtscCaptionTrack caption_tracks = 20;
optional bool has_caption_track = 21;
- optional AtscServiceType service_type = 22
- [default = SERVICE_TYPE_ATSC_DIGITAL_TELEVISION];
+ optional AtscServiceType service_type = 22 [default = SERVICE_TYPE_ATSC_DIGITAL_TELEVISION];
optional bool recording_prohibited = 23;
optional string video_format = 24;
/**
* The flag indicating whether this TV channel is locked or not.
- * This is primarily used for alternative parental control to prevent
- * unauthorized users from watching the current channel regardless of the
- * content rating
- * @see <a
- * href="https://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_LOCKED">link</a>
+ * This is primarily used for alternative parental control to prevent unauthorized users from
+ * watching the current channel regardless of the content rating
+ * @see <a href="https://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_LOCKED">link</a>
*/
optional bool locked = 25;
- optional DeliverySystemType delivery_system_type = 26;
}
// Enum describing the types of tuner.
enum TunerType {
+// AOSP_Comment_Out option (proto2.nano.enum_as_lite) = false;
+
TYPE_TUNER = 0;
TYPE_FILE = 1;
TYPE_NETWORK = 2;
@@ -71,10 +74,8 @@ enum TunerType {
// Enum describing the types of video stream.
enum VideoStreamType {
- // Default unset value. The spec says 0 is reserved.
- UNSET = 0x00;
- // DEPRECATED: previously used as default or unset value
- INVALID_STREAMTYPE = -1 [deprecated=true];
+// AOSP_Comment_Out option (proto2.nano.enum_as_lite) = false;
+
// ISO/IEC 11172 Video (MPEG-1)
MPEG1 = 0x01;
// ISO/IEC 13818-2 (MPEG-2) Video
@@ -89,6 +90,8 @@ enum VideoStreamType {
// Enum describing the types of audio stream.
enum AudioStreamType {
+// AOSP_Comment_Out option (proto2.nano.enum_as_lite) = false;
+
// ISO/IEC 11172 Audio (MPEG-1)
MPEG1AUDIO = 0x03;
// ISO/IEC 13818-3 Audio (MPEG-2)
@@ -106,6 +109,8 @@ enum AudioStreamType {
// Enum describing ATSC service types
// See ATSC Code Points Registry.
enum AtscServiceType {
+// AOSP_Comment_Out option (proto2.nano.enum_as_lite) = false;
+
SERVICE_TYPE_ATSC_RESERVED = 0x0;
SERVICE_TYPE_ANALOG_TELEVISION_CHANNELS = 0x1;
SERVICE_TYPE_ATSC_DIGITAL_TELEVISION = 0x2;
@@ -117,15 +122,3 @@ enum AtscServiceType {
SERVICE_TYPE_ATSC_NRT_SERVICE = 0x8;
SERVICE_TYPE_EXTENDED_PARAMERTERIZED_SERVICE = 0x9;
}
-
-// Enum describing the types of delivery system.
-enum DeliverySystemType {
- // Do not reorder. Must match Tuner.java
- DELIVERY_SYSTEM_UNDEFINED = 0;
- DELIVERY_SYSTEM_ATSC = 1;
- DELIVERY_SYSTEM_DVBC = 2;
- DELIVERY_SYSTEM_DVBS = 3;
- DELIVERY_SYSTEM_DVBS2 = 4;
- DELIVERY_SYSTEM_DVBT = 5;
- DELIVERY_SYSTEM_DVBT2 = 6;
-}
diff --git a/tuner/proto/track.proto b/tuner/proto/track.proto
index a4a20dbc..11ca784d 100644
--- a/tuner/proto/track.proto
+++ b/tuner/proto/track.proto
@@ -18,11 +18,15 @@ syntax = "proto2";
package com.android.tv.tuner.data;
+// AOSP_Comment_Out import "third_party/android/nanoproto/nano_descriptor.proto";
+
option java_package = "com.android.tv.tuner.data";
option java_outer_classname = "Track";
// Represents a AC3 audio track.
message AtscAudioTrack {
+// AOSP_Comment_Out option (proto2.nano.message_as_lite) = false;
+
optional string language = 1;
optional AudioType audio_type = 2;
optional int32 index = 3;
@@ -32,6 +36,8 @@ message AtscAudioTrack {
// Enum describing the types of a audio track.
// See ISO/IEC 138181-1:2000(e) Table 2-53.
enum AudioType {
+// AOSP_Comment_Out option (proto2.nano.enum_as_lite) = false;
+
AUDIOTYPE_UNDEFINED = 0;
AUDIOTYPE_CLEAN_EFFECTS = 1;
AUDIOTYPE_HEARING_IMPAIRED = 2;
@@ -41,8 +47,11 @@ message AtscAudioTrack {
// Represents a CEA-708 caption track.
message AtscCaptionTrack {
+// AOSP_Comment_Out option (proto2.nano.message_as_lite) = false;
+
optional string language = 1;
optional int32 service_number = 2;
optional bool easy_reader = 3;
optional bool wide_aspect_ratio = 4;
}
+
diff --git a/tuner/res/layout/guided_action_editable.xml b/tuner/res/layout/guided_action_editable.xml
index 4d3c87fd..84f56f8d 100644
--- a/tuner/res/layout/guided_action_editable.xml
+++ b/tuner/res/layout/guided_action_editable.xml
@@ -15,13 +15,13 @@
~ limitations under the License.
-->
-<androidx.leanback.widget.GuidedActionItemContainer
+<android.support.v17.leanback.widget.GuidedActionItemContainer
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/guidedactions_editable"
style="?attr/guidedActionItemContainerStyle"
android:layout_height="88dp">
- <androidx.leanback.widget.NonOverlappingLinearLayout
+ <android.support.v17.leanback.widget.NonOverlappingLinearLayout
android:id="@+id/guidedactions_item_content"
style="?attr/guidedActionItemContentStyle" >
@@ -32,10 +32,10 @@
android:textColor="@color/lb_guidedactions_item_unselected_text_color"
android:textSize="16sp" />
- <androidx.leanback.widget.GuidedActionEditText
+ <android.support.v17.leanback.widget.GuidedActionEditText
android:id="@+id/guidedactions_item_description"
style="?attr/guidedActionItemDescriptionStyle" />
- </androidx.leanback.widget.NonOverlappingLinearLayout>
+ </android.support.v17.leanback.widget.NonOverlappingLinearLayout>
-</androidx.leanback.widget.GuidedActionItemContainer> \ No newline at end of file
+</android.support.v17.leanback.widget.GuidedActionItemContainer> \ No newline at end of file
diff --git a/tuner/res/raw/ut_euro_dvbt_all b/tuner/res/raw/ut_euro_dvbt_all
index a2ff03b2..101ee3eb 100644
--- a/tuner/res/raw/ut_euro_dvbt_all
+++ b/tuner/res/raw/ut_euro_dvbt_all
@@ -1,6 +1,66 @@
# Euro DVB-T frequencies
# Only Germany and England frequencies are added now.
+# Frequencies from Germany
+T 474000000 QAM16
+T 474000000 QAM64
+T 482000000 QAM16
+T 490000000 QAM16
+T 498000000 QAM16
+T 498000000 QAM64
+T 506000000 QAM16
+T 506000000 QAM64
+T 514000000 QAM16
+T 522000000 QAM16
+T 522000000 QAM64
+T 530000000 QAM16
+T 538000000 QAM16
+T 538000000 QAM64
+T 546000000 QAM16
+T 554000000 QAM16
+T 554000000 QAM64
+T 562000000 QAM16
+T 562000000 QAM64
+T 570000000 QAM16
+T 578000000 QAM16
+T 578000000 QAM64
+T 586000000 QAM16
+T 594000000 QAM16
+T 602000000 QAM16
+T 602000000 QAM64
+T 610000000 QAM16
+T 610000000 QAM64
+T 618000000 QAM16
+T 618000000 QAM64
+T 626000000 QAM16
+T 634000000 QAM16
+T 634000000 QAM64
+T 642000000 QAM16
+T 650000000 QAM16
+T 658000000 QAM16
+T 666000000 QAM16
+T 674000000 QAM16
+T 674000000 QAM64
+T 682000000 QAM16
+T 690000000 QAM16
+T 690000000 QAM64
+T 698000000 QAM16
+T 698000000 QAM64
+T 706000000 QAM16
+T 722000000 QAM16
+T 730000000 QAM16
+T 730000000 QAM64
+T 738000000 QAM16
+T 738000000 QAM64
+T 746000000 QAM16
+T 746000000 QPSK
+T 754000000 QAM16
+T 762000000 QAM16
+T 770000000 QAM16
+T 778000000 QAM16
+T 786000000 QAM16
+
+# Frequencies from England
T 474000000 QAM16
T 474000000 QAM64
T 474167000 QAM16
@@ -70,7 +130,6 @@ T 562000000 QAM64
T 562167000 QAM16
T 569833000 QAM64
T 570000000 QAM16
-T 570000000 QAM64
T 570167000 QAM16
T 577833000 QAM16
T 578000000 QAM16
@@ -79,9 +138,7 @@ T 578166670 QAM16
T 578167000 QAM16
T 578167000 QAM64
T 586000000 QAM16
-T 586000000 QAM256
T 594000000 QAM16
-T 594000000 QAM64
T 602000000 QAM16
T 602000000 QAM64
T 610000000 QAM16
@@ -167,13 +224,11 @@ T 745833000 QAM64
T 746000000 QAM16
T 746000000 QAM64
T 746000000 QPSK
-T 746000000 QAM256
T 746167000 QAM64
T 753833000 QAM16
T 753833000 QAM64
T 754000000 QAM16
T 754000000 QAM64
-T 754000000 QAM256
T 754167000 QAM16
T 761833000 QAM16
T 761833000 QAM64
diff --git a/tuner/src/com/android/tv/tuner/dvb/DvbDeviceAccessor.java b/tuner/src/com/android/tv/tuner/DvbDeviceAccessor.java
index 8be27c91..217433d2 100644
--- a/tuner/src/com/android/tv/tuner/dvb/DvbDeviceAccessor.java
+++ b/tuner/src/com/android/tv/tuner/DvbDeviceAccessor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.tuner.dvb;
+package com.android.tv.tuner;
import android.content.Context;
import android.media.tv.TvInputManager;
diff --git a/tuner/src/com/android/tv/tuner/dvb/DvbTunerHal.java b/tuner/src/com/android/tv/tuner/DvbTunerHal.java
index 7f68e379..c802ebbb 100644
--- a/tuner/src/com/android/tv/tuner/dvb/DvbTunerHal.java
+++ b/tuner/src/com/android/tv/tuner/DvbTunerHal.java
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package com.android.tv.tuner.dvb;
+package com.android.tv.tuner;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import com.android.tv.common.compat.TvInputConstantCompat;
-import com.android.tv.tuner.TunerHal;
-import com.android.tv.tuner.dvb.DvbDeviceAccessor.DvbDeviceInfoWrapper;
+import com.android.tv.tuner.DvbDeviceAccessor.DvbDeviceInfoWrapper;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
diff --git a/tuner/src/com/android/tv/tuner/TunerHal.java b/tuner/src/com/android/tv/tuner/TunerHal.java
index 3f469d60..dce4f4c4 100644
--- a/tuner/src/com/android/tv/tuner/TunerHal.java
+++ b/tuner/src/com/android/tv/tuner/TunerHal.java
@@ -36,7 +36,6 @@ public abstract class TunerHal implements Tuner {
private static final int DEFAULT_QAM_TUNE_TIMEOUT_MS = 4000; // Some device takes time for
@DeliverySystemType private int mDeliverySystemType;
- @DeliverySystemType private int[] mDeliverySystemTypes;
private boolean mIsStreaming;
private int mFrequency;
private String mModulation;
@@ -58,16 +57,9 @@ public abstract class TunerHal implements Tuner {
}
protected void getDeliverySystemTypeFromDevice() {
- getDeliverySystemTypesFromDevice();
- }
-
- protected void getDeliverySystemTypesFromDevice() {
if (mDeliverySystemType == DELIVERY_SYSTEM_UNDEFINED) {
mDeliverySystemType = nativeGetDeliverySystemType(getDeviceId());
}
- if (mDeliverySystemTypes == null) {
- mDeliverySystemTypes = nativeGetDeliverySystemTypes(getDeviceId());
- }
}
/**
@@ -87,34 +79,18 @@ public abstract class TunerHal implements Tuner {
protected native void nativeFinalize(long deviceId);
- @Override
- public synchronized boolean tune(
- int frequency, @ModulationType String modulation,
- String channelNumber) {
- return tuneInternal(mDeliverySystemType, frequency, modulation, channelNumber);
- }
-
- @Override
- public synchronized boolean tune(
- int deliverySystemType, int frequency, @ModulationType String modulation,
- String channelNumber) {
- return tuneInternal(deliverySystemType, frequency, modulation, channelNumber);
- }
-
/**
* Sets the tuner channel. This should be called after acquiring a tuner device.
*
- * @param deliverySystemType a system delivery type of the channel to tune to
* @param frequency a frequency of the channel to tune to
* @param modulation a modulation method of the channel to tune to
* @param channelNumber channel number when channel number is already known. Some tuner HAL may
* use channelNumber instead of frequency for tune.
* @return {@code true} if the operation was successful, {@code false} otherwise
*/
- protected boolean tuneInternal(
- int deliverySystemType, int frequency, @ModulationType String modulation,
- String channelNumber) {
-
+ @Override
+ public synchronized boolean tune(
+ int frequency, @ModulationType String modulation, String channelNumber) {
if (!isDeviceOpen()) {
Log.e(TAG, "There's no available device");
return false;
@@ -123,76 +99,40 @@ public abstract class TunerHal implements Tuner {
nativeCloseAllPidFilters(getDeviceId());
mIsStreaming = false;
}
- if (mDeliverySystemTypes != null) {
- int i;
- for (i = 0; i < mDeliverySystemTypes.length; i++) {
- if (deliverySystemType == mDeliverySystemTypes[i]) {
- break;
- }
- }
-
- if (i == mDeliverySystemTypes.length) {
- Log.e(TAG, "Unsupported delivery system type for device");
- return 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);
- if (Tuner.isDvbDeliverySystem(deliverySystemType)) {
+ if (Tuner.isDvbDeliverySystem(mDeliverySystemType)) {
addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER);
addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER);
}
mIsStreaming = true;
return true;
}
-
int timeout_ms =
modulation.equals(MODULATION_8VSB)
? DEFAULT_VSB_TUNE_TIMEOUT_MS
: DEFAULT_QAM_TUNE_TIMEOUT_MS;
-
- boolean tuneStatus;
- switch(deliverySystemType) {
- case DELIVERY_SYSTEM_UNDEFINED:
- case DELIVERY_SYSTEM_ATSC:
- tuneStatus = nativeTune(getDeviceId(), frequency, modulation, timeout_ms);
- break;
- case DELIVERY_SYSTEM_DVBT:
- case DELIVERY_SYSTEM_DVBT2:
- tuneStatus = nativeTune(getDeviceId(), deliverySystemType, frequency, modulation,
- timeout_ms);
- break;
- default:
- Log.e(TAG, "Unsupported delivery system type for device");
- return false;
- }
-
- if (tuneStatus == true) {
+ if (nativeTune(getDeviceId(), frequency, modulation, timeout_ms)) {
addPidFilter(PID_PAT, FILTER_TYPE_OTHER);
addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
- if (Tuner.isDvbDeliverySystem(deliverySystemType)) {
+ if (Tuner.isDvbDeliverySystem(mDeliverySystemType)) {
addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER);
addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER);
}
mFrequency = frequency;
mModulation = modulation;
mIsStreaming = true;
+ return true;
}
-
- return tuneStatus;
+ return false;
}
protected native boolean nativeTune(
- long deviceId, int frequency,
- @ModulationType String modulation, int timeout_ms);
-
- protected native boolean nativeTune(
- long deviceId, int deliverySystemType, int frequency,
- @ModulationType String modulation, int timeout_ms);
+ long deviceId, int frequency, @ModulationType String modulation, int timeout_ms);
/**
* Sets a pid filter. This should be set after setting a channel.
@@ -222,8 +162,6 @@ public abstract class TunerHal implements Tuner {
protected native int nativeGetDeliverySystemType(long deviceId);
- protected native int[] nativeGetDeliverySystemTypes(long deviceId);
-
protected native int nativeGetSignalStrength(long deviceId);
/**
@@ -253,11 +191,6 @@ public abstract class TunerHal implements Tuner {
return mDeliverySystemType;
}
- @Override
- public int[] getDeliverySystemTypes() {
- return mDeliverySystemTypes;
- }
-
protected native void nativeStopTune(long deviceId);
/**
diff --git a/tuner/src/com/android/tv/tuner/api/ScanChannel.java b/tuner/src/com/android/tv/tuner/api/ScanChannel.java
index 1c7a6e79..56e5493c 100644
--- a/tuner/src/com/android/tv/tuner/api/ScanChannel.java
+++ b/tuner/src/com/android/tv/tuner/api/ScanChannel.java
@@ -15,15 +15,11 @@
*/
package com.android.tv.tuner.api;
-import android.util.Log;
-import com.android.tv.tuner.data.Channel;
-
+import com.android.tv.tuner.data.nano.Channel;
/** Channel information gathered from a <em>scan</em> */
public final class ScanChannel {
- private static final String TAG = "ScanChannel";
public final int type;
- public final Channel.DeliverySystemType deliverySystemType;
public final int frequency;
public final String modulation;
public final String filename;
@@ -35,60 +31,25 @@ public final class ScanChannel {
public final Integer radioFrequencyNumber;
public static ScanChannel forTuner(
- String deliverySystemType, int frequency, String modulation,
- Integer radioFrequencyNumber) {
+ int frequency, String modulation, Integer radioFrequencyNumber) {
return new ScanChannel(
- Channel.TunerType.TYPE_TUNER_VALUE, lookupDeliveryStringToInt(deliverySystemType),
- frequency, modulation, null, radioFrequencyNumber);
+ Channel.TunerType.TYPE_TUNER, frequency, modulation, null, radioFrequencyNumber);
}
public static ScanChannel forFile(int frequency, String filename) {
- return new ScanChannel(Channel.TunerType.TYPE_FILE_VALUE,
- Channel.DeliverySystemType.DELIVERY_SYSTEM_UNDEFINED, frequency, "file:",
- filename, null);
+ return new ScanChannel(Channel.TunerType.TYPE_FILE, frequency, "file:", filename, null);
}
private ScanChannel(
int type,
- Channel.DeliverySystemType deliverySystemType,
int frequency,
String modulation,
String filename,
Integer radioFrequencyNumber) {
this.type = type;
- this.deliverySystemType = deliverySystemType;
this.frequency = frequency;
this.modulation = modulation;
this.filename = filename;
this.radioFrequencyNumber = radioFrequencyNumber;
}
-
- private static Channel.DeliverySystemType lookupDeliveryStringToInt(String deliverySystemType) {
- Channel.DeliverySystemType ret;
- switch (deliverySystemType) {
- case "A":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_ATSC;
- break;
- case "C":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_DVBC;
- break;
- case "S":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_DVBS;
- break;
- case "S2":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_DVBS2;
- break;
- case "T":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_DVBT;
- break;
- case "T2":
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_DVBT2;
- break;
- default:
- Log.e(TAG, "Unknown delivery system type");
- ret = Channel.DeliverySystemType.DELIVERY_SYSTEM_UNDEFINED;
- break;
- }
- return ret;
- }
}
diff --git a/tuner/src/com/android/tv/tuner/api/Tuner.java b/tuner/src/com/android/tv/tuner/api/Tuner.java
index 02df3ca1..6f7e9d94 100644
--- a/tuner/src/com/android/tv/tuner/api/Tuner.java
+++ b/tuner/src/com/android/tv/tuner/api/Tuner.java
@@ -28,8 +28,6 @@ public interface Tuner extends AutoCloseable {
int FILTER_TYPE_VIDEO = 2;
int FILTER_TYPE_PCR = 3;
String MODULATION_8VSB = "8VSB";
- String MODULATION_QAM16 = "QAM16";
- String MODULATION_QAM64 = "QAM64";
String MODULATION_QAM256 = "QAM256";
int DELIVERY_SYSTEM_UNDEFINED = 0;
int DELIVERY_SYSTEM_ATSC = 1;
@@ -42,7 +40,6 @@ public interface Tuner extends AutoCloseable {
int TUNER_TYPE_USB = 2;
int TUNER_TYPE_NETWORK = 3;
int BUILT_IN_TUNER_TYPE_LINUX_DVB = 1;
- int BUILT_IN_TUNER_TYPE_ARCHER = 100;
/** Check a delivery system is for DVB or not. */
static boolean isDvbDeliverySystem(@DeliverySystemType int deliverySystemType) {
@@ -69,11 +66,6 @@ public interface Tuner extends AutoCloseable {
boolean tune(int frequency, @ModulationType String modulation, String channelNumber);
- default boolean tune(@DeliverySystemType int deliverySystemType, int frequency,
- @ModulationType String modulation, String channelNumber) {
- return tune(frequency, modulation, channelNumber);
- }
-
boolean addPidFilter(int pid, @FilterType int filterType);
void stopTune();
@@ -81,10 +73,6 @@ public interface Tuner extends AutoCloseable {
void setHasPendingTune(boolean hasPendingTune);
int getDeliverySystemType();
- default int[] getDeliverySystemTypes() {
- int[] deliverySystemTypes = {DELIVERY_SYSTEM_UNDEFINED};
- return deliverySystemTypes;
- };
int readTsStream(byte[] javaBuffer, int javaBufferSize);
@@ -96,7 +84,7 @@ public interface Tuner extends AutoCloseable {
public @interface FilterType {}
/** Modulation Type */
- @StringDef({MODULATION_8VSB, MODULATION_QAM256, MODULATION_QAM16, MODULATION_QAM64})
+ @StringDef({MODULATION_8VSB, MODULATION_QAM256})
@Retention(RetentionPolicy.SOURCE)
public @interface ModulationType {}
@@ -120,7 +108,6 @@ public interface Tuner extends AutoCloseable {
/** Built in tuner type */
@IntDef({
- BUILT_IN_TUNER_TYPE_ARCHER,
BUILT_IN_TUNER_TYPE_LINUX_DVB
})
@Retention(RetentionPolicy.SOURCE)
diff --git a/tuner/src/com/android/tv/tuner/dvb/DvbTunerHalFactory.java b/tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java
index 24d7e1fc..9a0be740 100644
--- a/tuner/src/com/android/tv/tuner/dvb/DvbTunerHalFactory.java
+++ b/tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java
@@ -14,29 +14,39 @@
* limitations under the License.
*/
-package com.android.tv.tuner.dvb;
+package com.android.tv.tuner.builtin;
import android.content.Context;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Pair;
-
+import com.android.tv.common.customization.CustomizationManager;
+import com.android.tv.common.feature.Model;
+import com.android.tv.tuner.DvbTunerHal;
import com.android.tv.tuner.api.Tuner;
import com.android.tv.tuner.api.TunerFactory;
+
/** TunerHal factory that creates all built in tuner types. */
-public final class DvbTunerHalFactory implements TunerFactory {
- private static final String TAG = "DvbTunerHalFactory";
+public final class BuiltInTunerHalFactory implements TunerFactory {
+ private static final String TAG = "BuiltInTunerHalFactory";
private static final boolean DEBUG = false;
- private final int mBuiltInTunerType = Tuner.BUILT_IN_TUNER_TYPE_LINUX_DVB;
+ private Integer mBuiltInTunerType;
- public static final TunerFactory INSTANCE = new DvbTunerHalFactory();
+ public static final TunerFactory INSTANCE = new BuiltInTunerHalFactory();
- private DvbTunerHalFactory() {}
+ private BuiltInTunerHalFactory() {}
@Tuner.BuiltInTunerType
private int getBuiltInTunerType(Context context) {
+ if (mBuiltInTunerType == null) {
+ mBuiltInTunerType = 0;
+ if (CustomizationManager.hasLinuxDvbBuiltInTuner(context)
+ && DvbTunerHal.getNumberOfDevices(context) > 0) {
+ mBuiltInTunerType = Tuner.BUILT_IN_TUNER_TYPE_LINUX_DVB;
+ }
+ }
return mBuiltInTunerType;
}
@@ -70,6 +80,17 @@ public final class DvbTunerHalFactory implements TunerFactory {
@Override
@WorkerThread
public Pair<Integer, Integer> getTunerTypeAndCount(Context context) {
- return Pair.create(Tuner.TUNER_TYPE_BUILT_IN, DvbTunerHal.getNumberOfDevices(context));
+ if (useBuiltInTuner(context)) {
+ if (getBuiltInTunerType(context) == Tuner.BUILT_IN_TUNER_TYPE_LINUX_DVB) {
+ return new Pair<>(
+ Tuner.TUNER_TYPE_BUILT_IN, DvbTunerHal.getNumberOfDevices(context));
+ }
+ } else {
+ int usbTunerCount = DvbTunerHal.getNumberOfDevices(context);
+ if (usbTunerCount > 0) {
+ return new Pair<>(Tuner.TUNER_TYPE_USB, usbTunerCount);
+ }
+ }
+ return new Pair<>(null, 0);
}
}
diff --git a/tuner/src/com/android/tv/tuner/cc/CaptionLayout.java b/tuner/src/com/android/tv/tuner/cc/CaptionLayout.java
index 62a4e157..eb9ad463 100644
--- a/tuner/src/com/android/tv/tuner/cc/CaptionLayout.java
+++ b/tuner/src/com/android/tv/tuner/cc/CaptionLayout.java
@@ -18,7 +18,7 @@ package com.android.tv.tuner.cc;
import android.content.Context;
import android.util.AttributeSet;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.layout.ScaledLayout;
/**
diff --git a/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java b/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
index 75776d6a..4a1c7c1b 100644
--- a/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
+++ b/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
@@ -27,7 +27,7 @@ import com.android.tv.tuner.data.Cea708Data.CaptionPenLocation;
import com.android.tv.tuner.data.Cea708Data.CaptionWindow;
import com.android.tv.tuner.data.Cea708Data.CaptionWindowAttr;
import com.android.tv.tuner.data.Cea708Parser;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import java.util.ArrayList;
/** Decodes and renders CEA-708. */
@@ -89,7 +89,7 @@ public class CaptionTrackRenderer implements Handler.Callback {
return;
}
if (DEBUG) {
- Log.d(TAG, "Start captionTrack " + captionTrack.getLanguage());
+ Log.d(TAG, "Start captionTrack " + captionTrack.language);
}
reset();
mCaptionLayout.setCaptionTrack(captionTrack);
diff --git a/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java b/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java
index 8c699d55..13c6ff47 100644
--- a/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java
+++ b/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java
@@ -459,14 +459,14 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout
private boolean isKoreanLanguageTrack() {
return mCaptionLayout != null
&& mCaptionLayout.getCaptionTrack() != null
- && mCaptionLayout.getCaptionTrack().hasLanguage()
- && "KOR".equalsIgnoreCase(mCaptionLayout.getCaptionTrack().getLanguage());
+ && mCaptionLayout.getCaptionTrack().language != null
+ && "KOR".compareToIgnoreCase(mCaptionLayout.getCaptionTrack().language) == 0;
}
private boolean isWideAspectRatio() {
return mCaptionLayout != null
&& mCaptionLayout.getCaptionTrack() != null
- && mCaptionLayout.getCaptionTrack().getWideAspectRatio();
+ && mCaptionLayout.getCaptionTrack().wideAspectRatio;
}
private void updateWidestChar() {
diff --git a/tuner/src/com/android/tv/tuner/data/Cea708Parser.java b/tuner/src/com/android/tv/tuner/data/Cea708Parser.java
index 7a5538c8..92834b27 100644
--- a/tuner/src/com/android/tv/tuner/data/Cea708Parser.java
+++ b/tuner/src/com/android/tv/tuner/data/Cea708Parser.java
@@ -138,7 +138,6 @@ public class Cea708Parser {
private long mLastDiscoveryLaunchedMs = SystemClock.elapsedRealtime();
private int mCommand = 0;
private int mListenServiceNumber = 0;
- private int mDtvCcPacketCalculatedSize = 0;
private boolean mDtvCcPacking = false;
private boolean mFirstServiceNumberDiscovered;
@@ -230,7 +229,6 @@ public class Cea708Parser {
mBuffer.setLength(0);
mDiscoveredNumBytes.clear();
mCommand = 0;
- mDtvCcPacketCalculatedSize = 0;
mDtvCcPacking = false;
}
@@ -286,33 +284,29 @@ public class Cea708Parser {
for (int i = 0; i < ccPacket.ccCount; ++i) {
boolean ccValid = (bytes[pos] & 0x04) != 0;
int ccType = bytes[pos] & 0x03;
+
+ // The dtvcc should be considered complete:
+ // - if either ccValid is set and ccType is 3
+ // - or ccValid is clear and ccType is 2 or 3.
if (ccValid) {
- // The dtvcc should be considered complete:
- // if ccType is 3 or if the packet size is reached.
if (ccType == CC_TYPE_DTVCC_PACKET_START) {
if (mDtvCcPacking) {
parseDtvCcPacket(mDtvCcPacket.buffer(), mDtvCcPacket.length());
mDtvCcPacket.clear();
- mDtvCcPacketCalculatedSize = 0;
}
mDtvCcPacking = true;
- int packetSize = bytes[pos + 1] & 0x3F; // last 6 bits
- if (packetSize == 0) {
- packetSize = DTVCC_MAX_PACKET_SIZE;
- }
- mDtvCcPacketCalculatedSize = packetSize * DTVCC_PACKET_SIZE_SCALE_FACTOR;
mDtvCcPacket.append(bytes[pos + 1]);
mDtvCcPacket.append(bytes[pos + 2]);
} else if (mDtvCcPacking && ccType == CC_TYPE_DTVCC_PACKET_DATA) {
mDtvCcPacket.append(bytes[pos + 1]);
mDtvCcPacket.append(bytes[pos + 2]);
}
+ } else {
if ((ccType == CC_TYPE_DTVCC_PACKET_START || ccType == CC_TYPE_DTVCC_PACKET_DATA)
- && mDtvCcPacking && mDtvCcPacket.length() == mDtvCcPacketCalculatedSize) {
+ && mDtvCcPacking) {
mDtvCcPacking = false;
parseDtvCcPacket(mDtvCcPacket.buffer(), mDtvCcPacket.length());
mDtvCcPacket.clear();
- mDtvCcPacketCalculatedSize = 0;
}
}
pos += 3;
diff --git a/tuner/src/com/android/tv/tuner/data/PsiData.java b/tuner/src/com/android/tv/tuner/data/PsiData.java
index 74f16035..9b7c2e2c 100644
--- a/tuner/src/com/android/tv/tuner/data/PsiData.java
+++ b/tuner/src/com/android/tv/tuner/data/PsiData.java
@@ -16,8 +16,8 @@
package com.android.tv.tuner.data;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import java.util.List;
/** Collection of MPEG PSI table items. */
diff --git a/tuner/src/com/android/tv/tuner/data/PsipData.java b/tuner/src/com/android/tv/tuner/data/PsipData.java
index 108ce3f2..d4af0934 100644
--- a/tuner/src/com/android/tv/tuner/data/PsipData.java
+++ b/tuner/src/com/android/tv/tuner/data/PsipData.java
@@ -20,8 +20,8 @@ import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.text.format.DateUtils;
import com.android.tv.common.util.StringUtils;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.util.ConvertUtils;
import java.util.ArrayList;
import java.util.HashMap;
@@ -495,10 +495,10 @@ public class PsipData {
public String toString() {
return String.format(
Locale.US,
- "AC3 audio stream sampleRateCode: %d, bsid: %d, bitRateCode: %d, surroundMode:"
- + " %d, bsmod: %d, numChannels: %d, fullSvc: %s, langCod: %d, langCod2:"
- + " %d, mainId: %d, priority: %d, avcflags: %d, text: %s, language: %s,"
- + " language2: %s",
+ "AC3 audio stream sampleRateCode: %d, bsid: %d, bitRateCode: %d, "
+ + "surroundMode: %d, bsmod: %d, numChannels: %d, fullSvc: %s, langCod: %d, "
+ + "langCod2: %d, mainId: %d, priority: %d, avcflags: %d, text: %s, language: %s"
+ + ", language2: %s",
mSampleRateCode,
mBsid,
mBitRateCode,
@@ -832,7 +832,7 @@ public class PsipData {
}
ArrayList<String> languages = new ArrayList<>();
for (AtscAudioTrack audioTrack : mAudioTracks) {
- languages.add(audioTrack.getLanguage());
+ languages.add(audioTrack.language);
}
return TextUtils.join(",", languages);
}
diff --git a/tuner/src/com/android/tv/tuner/data/SectionParser.java b/tuner/src/com/android/tv/tuner/data/SectionParser.java
index 3c16749e..d3dba6ba 100644
--- a/tuner/src/com/android/tv/tuner/data/SectionParser.java
+++ b/tuner/src/com/android/tv/tuner/data/SectionParser.java
@@ -24,8 +24,7 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
-import com.android.tv.common.feature.Model;
-import com.android.tv.tuner.data.Channel.AtscServiceType;
+
import com.android.tv.tuner.data.PsiData.PatItem;
import com.android.tv.tuner.data.PsiData.PmtItem;
import com.android.tv.tuner.data.PsipData.Ac3AudioDescriptor;
@@ -46,8 +45,9 @@ import com.android.tv.tuner.data.PsipData.ServiceDescriptor;
import com.android.tv.tuner.data.PsipData.ShortEventDescriptor;
import com.android.tv.tuner.data.PsipData.TsDescriptor;
import com.android.tv.tuner.data.PsipData.VctItem;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Channel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.util.ByteArrayBuffer;
import com.android.tv.tuner.util.ConvertUtils;
import java.io.UnsupportedEncodingException;
@@ -105,7 +105,7 @@ public class SectionParser {
private static final int RATING_REGION_US_TV = 1;
private static final int RATING_REGION_KR_TV = 4;
- // The following values are defined in the TV app.
+ // The following values are defined in the live channels app.
// See https://developer.android.com/reference/android/media/tv/TvContentRating.html.
private static final String RATING_DOMAIN = "com.android.tv";
private static final String RATING_REGION_RATING_SYSTEM_US_TV = "US_TV";
@@ -916,8 +916,8 @@ public class SectionParser {
Log.d(
TAG,
String.format(
- "Found channel [%s] %s - serviceType: %d tsid: 0x%x program: %d"
- + " channel: %d-%d encrypted: %b hidden: %b, descriptors: %d",
+ "Found channel [%s] %s - serviceType: %d tsid: 0x%x program: %d "
+ + "channel: %d-%d encrypted: %b hidden: %b, descriptors: %d",
shortName,
longName,
serviceType,
@@ -929,14 +929,14 @@ public class SectionParser {
hidden,
descriptors.size()));
}
- if ((serviceType == AtscServiceType.SERVICE_TYPE_ATSC_AUDIO_VALUE
+ if (!accessControlled
+ && !hidden
+ && (serviceType == Channel.AtscServiceType.SERVICE_TYPE_ATSC_AUDIO
|| serviceType
- == AtscServiceType.SERVICE_TYPE_ATSC_DIGITAL_TELEVISION_VALUE
+ == Channel.AtscServiceType.SERVICE_TYPE_ATSC_DIGITAL_TELEVISION
|| serviceType
- == AtscServiceType
- .SERVICE_TYPE_UNASSOCIATED_SMALL_SCREEN_SERVICE_VALUE)
- && !accessControlled
- && !hidden) {
+ == Channel.AtscServiceType
+ .SERVICE_TYPE_UNASSOCIATED_SMALL_SCREEN_SERVICE)) {
// Hide hidden, encrypted, or unsupported ATSC service type channels
results.add(
new VctItem(
@@ -1212,20 +1212,16 @@ public class SectionParser {
for (TsDescriptor descriptor : descriptors) {
if (descriptor instanceof Ac3AudioDescriptor) {
Ac3AudioDescriptor audioDescriptor = (Ac3AudioDescriptor) descriptor;
- String language = null;
+ AtscAudioTrack audioTrack = new AtscAudioTrack();
if (audioDescriptor.getLanguage() != null) {
- language = audioDescriptor.getLanguage();
+ audioTrack.language = audioDescriptor.getLanguage();
}
- if (language == null) {
- language = "";
+ if (audioTrack.language == null) {
+ audioTrack.language = "";
}
- AtscAudioTrack audioTrack =
- AtscAudioTrack.newBuilder()
- .setLanguage(language)
- .setAudioType(AtscAudioTrack.AudioType.AUDIOTYPE_UNDEFINED)
- .setChannelCount(audioDescriptor.getNumChannels())
- .setSampleRate(audioDescriptor.getSampleRate())
- .build();
+ audioTrack.audioType = AtscAudioTrack.AudioType.AUDIOTYPE_UNDEFINED;
+ audioTrack.channelCount = audioDescriptor.getNumChannels();
+ audioTrack.sampleRate = audioDescriptor.getSampleRate();
ac3Tracks.add(audioTrack);
}
}
@@ -1258,27 +1254,26 @@ public class SectionParser {
}
int size = Math.max(ac3Tracks.size(), iso639LanguageTracks.size());
for (int i = 0; i < size; ++i) {
- AtscAudioTrack.Builder audioTrack = null;
+ AtscAudioTrack audioTrack = null;
if (i < ac3Tracks.size()) {
- audioTrack = ac3Tracks.get(i).toBuilder();
+ audioTrack = ac3Tracks.get(i);
}
if (i < iso639LanguageTracks.size()) {
if (audioTrack == null) {
- audioTrack = iso639LanguageTracks.get(i).toBuilder();
+ audioTrack = iso639LanguageTracks.get(i);
} else {
AtscAudioTrack iso639LanguageTrack = iso639LanguageTracks.get(i);
- if (!audioTrack.hasLanguage()
- || TextUtils.equals(audioTrack.getLanguage(), "")) {
- audioTrack.setLanguage(iso639LanguageTrack.getLanguage());
+ if (audioTrack.language == null || TextUtils.equals(audioTrack.language, "")) {
+ audioTrack.language = iso639LanguageTrack.language;
}
- audioTrack.setAudioType(iso639LanguageTrack.getAudioType());
+ audioTrack.audioType = iso639LanguageTrack.audioType;
}
}
- String language = ISO_LANGUAGE_CODE_MAP.get(audioTrack.getLanguage());
+ String language = ISO_LANGUAGE_CODE_MAP.get(audioTrack.language);
if (language != null) {
- audioTrack = audioTrack.setLanguage(language);
+ audioTrack.language = language;
}
- tracks.add(audioTrack.build());
+ tracks.add(audioTrack);
}
return tracks;
}
@@ -1597,16 +1592,10 @@ public class SectionParser {
return null;
}
String language = new String(data, pos, 3);
- int audioTypeInt = data[pos + 3] & 0xff;
- AtscAudioTrack.AudioType audioType = AtscAudioTrack.AudioType.forNumber(audioTypeInt);
- if (audioType == null) {
- audioType = AtscAudioTrack.AudioType.AUDIOTYPE_UNDEFINED;
- }
- AtscAudioTrack audioTrack =
- AtscAudioTrack.newBuilder()
- .setLanguage(language)
- .setAudioType(audioType)
- .build();
+ int audioType = data[pos + 3] & 0xff;
+ AtscAudioTrack audioTrack = new AtscAudioTrack();
+ audioTrack.language = language;
+ audioTrack.audioType = audioType;
audioTracks.add(audioTrack);
pos += 4;
}
@@ -1645,13 +1634,11 @@ public class SectionParser {
reserved[0] |= (byte) ((data[pos + 1] & 0xc0) >>> 6);
reserved[1] = (byte) ((data[pos + 1] & 0x3f) << 2);
pos += 2;
- AtscCaptionTrack captionTrack =
- AtscCaptionTrack.newBuilder()
- .setLanguage(language)
- .setServiceNumber(captionServiceNumber)
- .setEasyReader(easyReader)
- .setWideAspectRatio(wideAspectRatio)
- .build();
+ AtscCaptionTrack captionTrack = new AtscCaptionTrack();
+ captionTrack.language = language;
+ captionTrack.serviceNumber = captionServiceNumber;
+ captionTrack.easyReader = easyReader;
+ captionTrack.wideAspectRatio = wideAspectRatio;
services.add(captionTrack);
}
return new CaptionServiceDescriptor(services);
@@ -2088,11 +2075,6 @@ public class SectionParser {
}
private static boolean checkSanity(byte[] data) {
- // Skipping CRC checking on Archer since TS data here was modified without updating CRC
- // value. For details, see b/28616908.
- if (Model.ARCHER.isEnabled()) {
- return true;
- }
if (data.length <= 1) {
return false;
}
diff --git a/tuner/src/com/android/tv/tuner/data/TunerChannel.java b/tuner/src/com/android/tv/tuner/data/TunerChannel.java
index 5872cd55..d20c343b 100644
--- a/tuner/src/com/android/tv/tuner/data/TunerChannel.java
+++ b/tuner/src/com/android/tv/tuner/data/TunerChannel.java
@@ -20,10 +20,12 @@ import android.database.Cursor;
import android.support.annotation.NonNull;
import android.util.Log;
import com.android.tv.common.util.StringUtils;
-import com.android.tv.tuner.data.Channel.DeliverySystemType;
-import com.android.tv.tuner.data.Channel.TunerChannelProto;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Channel;
+import com.android.tv.tuner.data.nano.Channel.TunerChannelProto;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
+import com.android.tv.tuner.util.Ints;
+import com.google.protobuf.nano.MessageNano;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,7 +55,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
"Extended Parameterized Service"
};
private static final String ATSC_SERVICE_TYPE_NAME_RESERVED =
- ATSC_SERVICE_TYPE_NAMES[Channel.AtscServiceType.SERVICE_TYPE_ATSC_RESERVED_VALUE];
+ ATSC_SERVICE_TYPE_NAMES[Channel.AtscServiceType.SERVICE_TYPE_ATSC_RESERVED];
public static final int INVALID_FREQUENCY = -1;
@@ -64,128 +66,93 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
public static final int INVALID_STREAMTYPE = -1;
// @GuardedBy(this) Writing operations and toByteArray will be guarded. b/34197766
- private TunerChannelProto mProto;
+ private final TunerChannelProto mProto;
private TunerChannel(
- PsipData.VctItem channel,
- int programNumber,
- List<PsiData.PmtItem> pmtItems,
- Channel.TunerType type) {
- String shortName = "";
- String longName = "";
- String description = "";
- int tsid = 0;
- int virtualMajor = 0;
- int virtualMinor = 0;
- Channel.AtscServiceType serviceType =
- Channel.AtscServiceType.SERVICE_TYPE_ATSC_DIGITAL_TELEVISION;
- if (channel != null) {
- shortName = channel.getShortName();
- tsid = channel.getChannelTsid();
- programNumber = channel.getProgramNumber();
- virtualMajor = channel.getMajorChannelNumber();
- virtualMinor = channel.getMinorChannelNumber();
- Channel.AtscServiceType chanServiceType =
- Channel.AtscServiceType.forNumber(channel.getServiceType());
- if (chanServiceType != null) {
- serviceType = chanServiceType;
+ PsipData.VctItem channel, int programNumber, List<PsiData.PmtItem> pmtItems, int type) {
+ mProto = new TunerChannelProto();
+ if (channel == null) {
+ mProto.shortName = "";
+ mProto.tsid = 0;
+ mProto.programNumber = programNumber;
+ mProto.virtualMajor = 0;
+ mProto.virtualMinor = 0;
+ } else {
+ mProto.shortName = channel.getShortName();
+ if (channel.getLongName() != null) {
+ mProto.longName = channel.getLongName();
}
- longName = (channel.getLongName() != null ? channel.getLongName() : longName);
- description =
- (channel.getDescription() != null ? channel.getDescription() : description);
+ mProto.tsid = channel.getChannelTsid();
+ mProto.programNumber = channel.getProgramNumber();
+ mProto.virtualMajor = channel.getMajorChannelNumber();
+ mProto.virtualMinor = channel.getMinorChannelNumber();
+ if (channel.getDescription() != null) {
+ mProto.description = channel.getDescription();
+ }
+ mProto.serviceType = channel.getServiceType();
}
- TunerChannelProto tunerChannelProto =
- TunerChannelProto.newBuilder()
- .setShortName(shortName)
- .setTsid(tsid)
- .setProgramNumber(programNumber)
- .setVirtualMajor(virtualMajor)
- .setVirtualMinor(virtualMinor)
- .setServiceType(serviceType)
- .setLongName(longName)
- .setDescription(description)
- .build();
- initProto(pmtItems, type, tunerChannelProto);
- }
-
- private void initProto(
- List<PsiData.PmtItem> pmtItems,
- Channel.TunerType type,
- TunerChannelProto tunerChannelProto) {
- int videoPid = INVALID_PID;
- int pcrPid = 0;
- Channel.VideoStreamType videoStreamType = Channel.VideoStreamType.UNSET;
+ initProto(pmtItems, type);
+ }
+
+ private void initProto(List<PsiData.PmtItem> pmtItems, int type) {
+ mProto.type = type;
+ mProto.channelId = -1L;
+ mProto.frequency = INVALID_FREQUENCY;
+ mProto.videoPid = INVALID_PID;
+ mProto.videoStreamType = INVALID_STREAMTYPE;
List<Integer> audioPids = new ArrayList<>();
- List<Channel.AudioStreamType> audioStreamTypes = new ArrayList<>();
+ List<Integer> audioStreamTypes = new ArrayList<>();
for (PsiData.PmtItem pmt : pmtItems) {
switch (pmt.getStreamType()) {
// MPEG ES stream video types
- case Channel.VideoStreamType.MPEG1_VALUE:
- case Channel.VideoStreamType.MPEG2_VALUE:
- case Channel.VideoStreamType.H263_VALUE:
- case Channel.VideoStreamType.H264_VALUE:
- case Channel.VideoStreamType.H265_VALUE:
- videoPid = pmt.getEsPid();
- videoStreamType = Channel.VideoStreamType.forNumber(pmt.getStreamType());
+ case Channel.VideoStreamType.MPEG1:
+ case Channel.VideoStreamType.MPEG2:
+ case Channel.VideoStreamType.H263:
+ case Channel.VideoStreamType.H264:
+ case Channel.VideoStreamType.H265:
+ mProto.videoPid = pmt.getEsPid();
+ mProto.videoStreamType = pmt.getStreamType();
break;
// MPEG ES stream audio types
- case Channel.AudioStreamType.MPEG1AUDIO_VALUE:
- case Channel.AudioStreamType.MPEG2AUDIO_VALUE:
- case Channel.AudioStreamType.MPEG2AACAUDIO_VALUE:
- case Channel.AudioStreamType.MPEG4LATMAACAUDIO_VALUE:
- case Channel.AudioStreamType.A52AC3AUDIO_VALUE:
- case Channel.AudioStreamType.EAC3AUDIO_VALUE:
+ case Channel.AudioStreamType.MPEG1AUDIO:
+ case Channel.AudioStreamType.MPEG2AUDIO:
+ case Channel.AudioStreamType.MPEG2AACAUDIO:
+ case Channel.AudioStreamType.MPEG4LATMAACAUDIO:
+ case Channel.AudioStreamType.A52AC3AUDIO:
+ case Channel.AudioStreamType.EAC3AUDIO:
audioPids.add(pmt.getEsPid());
- audioStreamTypes.add(Channel.AudioStreamType.forNumber(pmt.getStreamType()));
+ audioStreamTypes.add(pmt.getStreamType());
break;
// Non MPEG ES stream types
case 0x100: // PmtItem.ES_PID_PCR:
- pcrPid = pmt.getEsPid();
+ mProto.pcrPid = pmt.getEsPid();
break;
default:
// fall out
}
}
- mProto =
- TunerChannelProto.newBuilder(tunerChannelProto)
- .setType(type)
- .setChannelId(-1L)
- .setFrequency(INVALID_FREQUENCY)
- .setVideoPid(videoPid)
- .setVideoStreamType(videoStreamType)
- .addAllAudioPids(audioPids)
- .setAudioTrackIndex(audioPids.isEmpty() ? -1 : 0)
- .addAllAudioStreamTypes(audioStreamTypes)
- .setPcrPid(pcrPid)
- .build();
+ mProto.audioPids = Ints.toArray(audioPids);
+ mProto.audioStreamTypes = Ints.toArray(audioStreamTypes);
+ mProto.audioTrackIndex = (audioPids.size() > 0) ? 0 : -1;
}
private TunerChannel(
- int programNumber,
- Channel.TunerType type,
- PsipData.SdtItem channel,
- List<PsiData.PmtItem> pmtItems) {
- String shortName = "";
- Channel.AtscServiceType serviceType =
- Channel.AtscServiceType.SERVICE_TYPE_ATSC_DIGITAL_TELEVISION;
- if (channel != null) {
- shortName = channel.getServiceName();
- programNumber = channel.getServiceId();
- Channel.AtscServiceType chanServiceType =
- Channel.AtscServiceType.forNumber(channel.getServiceType());
- if (chanServiceType != null) {
- serviceType = chanServiceType;
- }
+ int programNumber, int type, PsipData.SdtItem channel, List<PsiData.PmtItem> pmtItems) {
+ mProto = new TunerChannelProto();
+ mProto.tsid = 0;
+ mProto.virtualMajor = 0;
+ mProto.virtualMinor = 0;
+ if (channel == null) {
+ mProto.shortName = "";
+ mProto.programNumber = programNumber;
+ } else {
+ mProto.shortName = channel.getServiceName();
+ mProto.programNumber = channel.getServiceId();
+ mProto.serviceType = channel.getServiceType();
}
- TunerChannelProto tunerChannelProto =
- TunerChannelProto.newBuilder()
- .setShortName(shortName)
- .setProgramNumber(programNumber)
- .setServiceType(serviceType)
- .build();
- initProto(pmtItems, type, tunerChannelProto);
+ initProto(pmtItems, type);
}
/** Initialize tuner channel with VCT items and PMT items. */
@@ -266,23 +233,23 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
public String getName() {
- return !mProto.getShortName().isEmpty() ? mProto.getShortName() : mProto.getLongName();
+ return (!mProto.shortName.isEmpty()) ? mProto.shortName : mProto.longName;
}
public String getShortName() {
- return mProto.getShortName();
+ return mProto.shortName;
}
public int getProgramNumber() {
- return mProto.getProgramNumber();
+ return mProto.programNumber;
}
public int getServiceType() {
- return mProto.getServiceType().getNumber();
+ return mProto.serviceType;
}
public String getServiceTypeName() {
- int serviceType = getServiceType();
+ int serviceType = mProto.serviceType;
if (serviceType >= 0 && serviceType < ATSC_SERVICE_TYPE_NAMES.length) {
return ATSC_SERVICE_TYPE_NAMES[serviceType];
}
@@ -290,129 +257,105 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
public int getVirtualMajor() {
- return mProto.getVirtualMajor();
+ return mProto.virtualMajor;
}
public int getVirtualMinor() {
- return mProto.getVirtualMinor();
- }
-
- public DeliverySystemType getDeliverySystemType() {
- return mProto.getDeliverySystemType();
+ return mProto.virtualMinor;
}
public int getFrequency() {
- return mProto.getFrequency();
+ return mProto.frequency;
}
public String getModulation() {
- return mProto.getModulation();
+ return mProto.modulation;
}
public int getTsid() {
- return mProto.getTsid();
+ return mProto.tsid;
}
public int getVideoPid() {
- return mProto.getVideoPid();
+ return mProto.videoPid;
}
public synchronized void setVideoPid(int videoPid) {
- mProto = mProto.toBuilder().setVideoPid(videoPid).build();
+ mProto.videoPid = videoPid;
}
public int getVideoStreamType() {
- return mProto.getVideoStreamType().getNumber();
+ return mProto.videoStreamType;
}
public int getAudioPid() {
- if (!mProto.hasAudioTrackIndex() || mProto.getAudioTrackIndex() == -1) {
+ if (mProto.audioTrackIndex == -1) {
return INVALID_PID;
}
- return mProto.getAudioPids(mProto.getAudioTrackIndex());
+ return mProto.audioPids[mProto.audioTrackIndex];
}
public int getAudioStreamType() {
- if (!mProto.hasAudioTrackIndex() || mProto.getAudioTrackIndex() == -1) {
+ if (mProto.audioTrackIndex == -1) {
return INVALID_STREAMTYPE;
}
- return mProto.getAudioStreamTypes(mProto.getAudioTrackIndex()).getNumber();
+ return mProto.audioStreamTypes[mProto.audioTrackIndex];
}
public List<Integer> getAudioPids() {
- return mProto.getAudioPidsList();
+ return Ints.asList(mProto.audioPids);
}
public synchronized void setAudioPids(List<Integer> audioPids) {
- mProto = mProto.toBuilder().clearAudioPids().addAllAudioPids(audioPids).build();
+ mProto.audioPids = Ints.toArray(audioPids);
}
public List<Integer> getAudioStreamTypes() {
- List<Channel.AudioStreamType> audioStreamTypes = mProto.getAudioStreamTypesList();
- List<Integer> audioStreamTypesValues = new ArrayList<>(audioStreamTypes.size());
-
- for (Channel.AudioStreamType audioStreamType : audioStreamTypes) {
- audioStreamTypesValues.add(audioStreamType.getNumber());
- }
- return audioStreamTypesValues;
+ return Ints.asList(mProto.audioStreamTypes);
}
- public synchronized void setAudioStreamTypes(List<Integer> audioStreamTypesValues) {
- List<Channel.AudioStreamType> audioStreamTypes =
- new ArrayList<>(audioStreamTypesValues.size());
-
- for (Integer audioStreamTypesValue : audioStreamTypesValues) {
- audioStreamTypes.add(Channel.AudioStreamType.forNumber(audioStreamTypesValue));
- }
- mProto =
- mProto.toBuilder()
- .clearAudioStreamTypes()
- .addAllAudioStreamTypes(audioStreamTypes)
- .build();
+ public synchronized void setAudioStreamTypes(List<Integer> audioStreamTypes) {
+ mProto.audioStreamTypes = Ints.toArray(audioStreamTypes);
}
public int getPcrPid() {
- return mProto.getPcrPid();
+ return mProto.pcrPid;
}
- public Channel.TunerType getType() {
- return mProto.getType();
+ public int getType() {
+ return mProto.type;
}
public synchronized void setFilepath(String filepath) {
- mProto = mProto.toBuilder().setFilepath(filepath == null ? "" : filepath).build();
+ mProto.filepath = filepath == null ? "" : filepath;
}
public String getFilepath() {
- return mProto.getFilepath();
+ return mProto.filepath;
}
public synchronized void setVirtualMajor(int virtualMajor) {
- mProto = mProto.toBuilder().setVirtualMajor(virtualMajor).build();
+ mProto.virtualMajor = virtualMajor;
}
public synchronized void setVirtualMinor(int virtualMinor) {
- mProto = mProto.toBuilder().setVirtualMinor(virtualMinor).build();
+ mProto.virtualMinor = virtualMinor;
}
public synchronized void setShortName(String shortName) {
- mProto = mProto.toBuilder().setShortName(shortName == null ? "" : shortName).build();
- }
-
- public synchronized void setDeliverySystemType(DeliverySystemType deliverySystemType) {
- mProto = mProto.toBuilder().setDeliverySystemType(deliverySystemType).build();
+ mProto.shortName = shortName == null ? "" : shortName;
}
public synchronized void setFrequency(int frequency) {
- mProto = mProto.toBuilder().setFrequency(frequency).build();
+ mProto.frequency = frequency;
}
public synchronized void setModulation(String modulation) {
- mProto = mProto.toBuilder().setModulation(modulation == null ? "" : modulation).build();
+ mProto.modulation = modulation == null ? "" : modulation;
}
public boolean hasVideo() {
- return mProto.hasVideoPid() && mProto.getVideoPid() != INVALID_PID;
+ return mProto.videoPid != INVALID_PID;
}
public boolean hasAudio() {
@@ -420,11 +363,11 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
public long getChannelId() {
- return mProto.getChannelId();
+ return mProto.channelId;
}
public synchronized void setChannelId(long channelId) {
- mProto = mProto.toBuilder().setChannelId(channelId).build();
+ mProto.channelId = channelId;
}
/**
@@ -436,11 +379,11 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
* href="https://developer.android.com/reference/android/media/tv/TvContract.Channels.html#COLUMN_LOCKED">link</a>
*/
public boolean isLocked() {
- return mProto.getLocked();
+ return mProto.locked;
}
public synchronized void setLocked(boolean locked) {
- mProto = mProto.toBuilder().setLocked(locked).build();
+ mProto.locked = locked;
}
public String getDisplayNumber() {
@@ -448,91 +391,92 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
public String getDisplayNumber(boolean ignoreZeroMinorNumber) {
- if (getVirtualMajor() != 0 && (getVirtualMinor() != 0 || !ignoreZeroMinorNumber)) {
+ if (mProto.virtualMajor != 0 && (mProto.virtualMinor != 0 || !ignoreZeroMinorNumber)) {
return String.format(
- "%d%c%d", getVirtualMajor(), CHANNEL_NUMBER_SEPARATOR, getVirtualMinor());
- } else if (getVirtualMajor() != 0) {
- return Integer.toString(getVirtualMajor());
+ "%d%c%d", mProto.virtualMajor, CHANNEL_NUMBER_SEPARATOR, mProto.virtualMinor);
+ } else if (mProto.virtualMajor != 0) {
+ return Integer.toString(mProto.virtualMajor);
} else {
- return Integer.toString(getProgramNumber());
+ return Integer.toString(mProto.programNumber);
}
}
public String getDescription() {
- return mProto.getDescription();
+ return mProto.description;
}
@Override
public synchronized void setHasCaptionTrack() {
- mProto = mProto.toBuilder().setHasCaptionTrack(true).build();
+ mProto.hasCaptionTrack = true;
}
@Override
public boolean hasCaptionTrack() {
- return mProto.getHasCaptionTrack();
+ return mProto.hasCaptionTrack;
}
@Override
public List<AtscAudioTrack> getAudioTracks() {
- return mProto.getAudioTracksList();
+ return Collections.unmodifiableList(Arrays.asList(mProto.audioTracks));
}
public synchronized void setAudioTracks(List<AtscAudioTrack> audioTracks) {
- mProto = mProto.toBuilder().clearAudioTracks().addAllAudioTracks(audioTracks).build();
+ mProto.audioTracks = audioTracks.toArray(new AtscAudioTrack[audioTracks.size()]);
}
@Override
public List<AtscCaptionTrack> getCaptionTracks() {
- return mProto.getCaptionTracksList();
+ return Collections.unmodifiableList(Arrays.asList(mProto.captionTracks));
}
public synchronized void setCaptionTracks(List<AtscCaptionTrack> captionTracks) {
- mProto = mProto.toBuilder().clearCaptionTracks().addAllCaptionTracks(captionTracks).build();
+ mProto.captionTracks = captionTracks.toArray(new AtscCaptionTrack[captionTracks.size()]);
}
public synchronized void selectAudioTrack(int index) {
- if (index < 0 || index >= mProto.getAudioPidsCount()) {
- index = -1;
+ if (0 <= index && index < mProto.audioPids.length) {
+ mProto.audioTrackIndex = index;
+ } else {
+ mProto.audioTrackIndex = -1;
}
- mProto = mProto.toBuilder().setAudioTrackIndex(index).build();
}
public synchronized void setRecordingProhibited(boolean recordingProhibited) {
- mProto = mProto.toBuilder().setRecordingProhibited(recordingProhibited).build();
+ mProto.recordingProhibited = recordingProhibited;
}
public boolean isRecordingProhibited() {
- return mProto.getRecordingProhibited();
+ return mProto.recordingProhibited;
}
public synchronized void setVideoFormat(String videoFormat) {
- mProto = mProto.toBuilder().setVideoFormat(videoFormat == null ? "" : videoFormat).build();
+ mProto.videoFormat = videoFormat == null ? "" : videoFormat;
}
public String getVideoFormat() {
- return mProto.getVideoFormat();
+ return mProto.videoFormat;
}
@Override
public String toString() {
- switch (getType()) {
- case TYPE_FILE:
+ switch (mProto.type) {
+ case Channel.TunerType.TYPE_FILE:
return String.format(
"{%d-%d %s} Filepath: %s, ProgramNumber %d",
- getVirtualMajor(),
- getVirtualMinor(),
- getShortName(),
- getFilepath(),
- getProgramNumber());
+ mProto.virtualMajor,
+ mProto.virtualMinor,
+ mProto.shortName,
+ mProto.filepath,
+ mProto.programNumber);
// case Channel.TunerType.TYPE_TUNER:
default:
return String.format(
"{%d-%d %s} Frequency: %d, ProgramNumber %d",
- getVirtualMajor(),
- getVirtualMinor(),
- getShortName(),
- getFrequency(),
- getProgramNumber());
+ mProto.virtualMajor,
+ mProto.virtualMinor,
+ mProto.shortName,
+ mProto.frequency,
+ mProto.programNumber);
}
}
@@ -551,9 +495,6 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
if (ret != 0) {
return ret;
}
- if (getDeliverySystemType() != channel.getDeliverySystemType()) {
- return 1;
- }
// For FileTsStreamer, file paths should be compared.
return StringUtils.compare(getFilepath(), channel.getFilepath());
}
@@ -568,21 +509,20 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
@Override
public int hashCode() {
- return Objects.hash(getDeliverySystemType(), getFrequency(), getProgramNumber(), getName(),
- getFilepath());
+ return Objects.hash(getFrequency(), getProgramNumber(), getName(), getFilepath());
}
// Serialization
public synchronized byte[] toByteArray() {
try {
- return mProto.toByteArray();
+ return MessageNano.toByteArray(mProto);
} catch (Exception e) {
// Retry toByteArray. b/34197766
Log.w(
TAG,
"TunerChannel or its variables are modified in multiple thread without lock",
e);
- return mProto.toByteArray();
+ return MessageNano.toByteArray(mProto);
}
}
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java b/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
index 2a22db17..e48cb03c 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
@@ -26,32 +26,32 @@ import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Pair;
-
import com.android.tv.tuner.exoplayer.audio.MpegTsDefaultAudioTrackRenderer;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer;
import com.android.tv.tuner.exoplayer.buffer.SimpleSampleBuffer;
-
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.MediaFormatHolder;
import com.google.android.exoplayer.SampleHolder;
+import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
+import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
+import com.google.android.exoplayer2.source.ExtractorMediaSource.EventListener;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
-import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.google.android.exoplayer2.upstream.TransferListener;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -72,6 +72,7 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
private final long mId;
private final Handler.Callback mSourceReaderWorker;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private BufferManager.SampleBuffer mSampleBuffer;
private Handler mSourceReaderHandler;
@@ -88,29 +89,13 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
private Handler mOnCompletionListenerHandler;
private IOException mError;
- /**
- * Factory for {@link ExoPlayerSampleExtractor}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public ExoPlayerSampleExtractor create(
- Uri uri,
- DataSource source,
- @Nullable BufferManager bufferManager,
- PlaybackBufferListener bufferListener,
- boolean isRecording);
- }
-
- @AutoFactory(implementing = Factory.class)
public ExoPlayerSampleExtractor(
Uri uri,
- DataSource source,
- @Nullable BufferManager bufferManager,
+ final DataSource source,
+ BufferManager bufferManager,
PlaybackBufferListener bufferListener,
boolean isRecording,
- @Provided RecordingSampleBuffer.Factory recordingSampleBufferFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlagsoncurrentDvrPlaybackFlags) {
this(
uri,
source,
@@ -119,7 +104,7 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
isRecording,
Looper.myLooper(),
new HandlerThread("SourceReaderThread"),
- recordingSampleBufferFactory);
+ concurrentDvrPlaybackFlagsoncurrentDvrPlaybackFlags);
}
@VisibleForTesting
@@ -132,35 +117,98 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
boolean isRecording,
Looper workerLooper,
HandlerThread sourceReaderThread,
- RecordingSampleBuffer.Factory recordingSampleBufferFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
// It'll be used as a timeshift file chunk name's prefix.
mId = System.currentTimeMillis();
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
+
+ EventListener eventListener =
+ new EventListener() {
+ @Override
+ public void onLoadError(IOException error) {
+ mError = error;
+ }
+ };
mSourceReaderThread = sourceReaderThread;
mSourceReaderWorker =
new SourceReaderWorker(
new ExtractorMediaSource(
uri,
- /* dataSourceFactory= */ () -> source,
+ new com.google.android.exoplayer2.upstream.DataSource.Factory() {
+ @Override
+ public com.google.android.exoplayer2.upstream.DataSource
+ createDataSource() {
+ // Returns an adapter implementation for ExoPlayer V2
+ // DataSource interface.
+ return new com.google.android.exoplayer2.upstream
+ .DataSource() {
+
+ private @Nullable Uri uri;
+
+ // TODO: uncomment once this is part of the public API.
+ // @Override
+ public void addTransferListener(
+ TransferListener transferListener) {
+ // Do nothing. Unsupported in V1.
+ }
+
+ @Override
+ public long open(DataSpec dataSpec) throws IOException {
+ this.uri = dataSpec.uri;
+ return source.open(
+ new com.google.android.exoplayer.upstream
+ .DataSpec(
+ dataSpec.uri,
+ dataSpec.postBody,
+ dataSpec.absoluteStreamPosition,
+ dataSpec.position,
+ dataSpec.length,
+ dataSpec.key,
+ dataSpec.flags));
+ }
+
+ @Override
+ public int read(
+ byte[] buffer, int offset, int readLength)
+ throws IOException {
+ return source.read(buffer, offset, readLength);
+ }
+
+ @Override
+ public @Nullable Uri getUri() {
+ return uri;
+ }
+
+ @Override
+ public void close() throws IOException {
+ source.close();
+ uri = null;
+ }
+ };
+ }
+ },
new ExoPlayerExtractorsFactory(),
new Handler(workerLooper),
- /* eventListener= */ error -> mError = error));
+ eventListener));
if (isRecording) {
mSampleBuffer =
- recordingSampleBufferFactory.create(
+ new RecordingSampleBuffer(
bufferManager,
bufferListener,
false,
+ mConcurrentDvrPlaybackFlags,
RecordingSampleBuffer.BUFFER_REASON_RECORDING);
} else {
if (bufferManager == null) {
mSampleBuffer = new SimpleSampleBuffer(bufferListener);
} else {
mSampleBuffer =
- recordingSampleBufferFactory.create(
+ new RecordingSampleBuffer(
bufferManager,
bufferListener,
true,
+ mConcurrentDvrPlaybackFlags,
RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK);
}
}
@@ -192,11 +240,15 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
public SourceReaderWorker(MediaSource sampleSource) {
mSampleSource = sampleSource;
mSampleSourceListener =
- (source, timeline, manifest) -> {
- // Dynamic stream change is not supported yet. b/28169263
- // For now, this will cause EOS and playback reset.
+ new MediaSource.SourceInfoRefreshListener() {
+ @Override
+ public void onSourceInfoRefreshed(
+ MediaSource source, Timeline timeline, Object manifest) {
+ // Dynamic stream change is not supported yet. b/28169263
+ // For now, this will cause EOS and playback reset.
+ }
};
- mSampleSource.prepareSource(mSampleSourceListener, null);
+ mSampleSource.prepareSource(null, false, mSampleSourceListener, null);
mDecoderInputBuffer =
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
@@ -313,8 +365,9 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
mMediaPeriod =
mSampleSource.createPeriod(
new MediaSource.MediaPeriodId(0),
- new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE),
- 0);
+ new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE)
+// AOSP_Comment_Out , 0
+ );
mMediaPeriod.prepare(this, 0);
try {
mMediaPeriod.maybeThrowPrepareError();
@@ -433,7 +486,7 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
sample.data.position(0);
sample.data.put(mDecoderInputBuffer.data);
sample.data.flip();
- mPendingSamples.add(Pair.create(index, sample));
+ mPendingSamples.add(new Pair<>(index, sample));
return;
}
mVideoTrackMet = true;
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java b/tuner/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
index aaca043b..9749e4ba 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
@@ -17,18 +17,14 @@
package com.android.tv.tuner.exoplayer;
import android.os.Handler;
-
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer;
-
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.MediaFormatHolder;
import com.google.android.exoplayer.MediaFormatUtil;
import com.google.android.exoplayer.SampleHolder;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -48,28 +44,16 @@ public class FileSampleExtractor implements SampleExtractor {
private final BufferManager mBufferManager;
private final PlaybackBufferListener mBufferListener;
private BufferManager.SampleBuffer mSampleBuffer;
- private final RecordingSampleBuffer.Factory mRecordingSampleBufferFactory;
-
- /**
- * Factory for {@link FileSampleExtractor}}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public FileSampleExtractor create(
- BufferManager bufferManager, PlaybackBufferListener bufferListener);
- }
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
- @AutoFactory(implementing = Factory.class)
public FileSampleExtractor(
BufferManager bufferManager,
PlaybackBufferListener bufferListener,
- @Provided RecordingSampleBuffer.Factory recordingSampleBufferFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
mBufferManager = bufferManager;
mBufferListener = bufferListener;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
mTrackCount = -1;
- mRecordingSampleBufferFactory = recordingSampleBufferFactory;
}
@Override
@@ -92,10 +76,11 @@ public class FileSampleExtractor implements SampleExtractor {
mTrackFormats.add(MediaFormatUtil.createMediaFormat(trackFormat.format));
}
mSampleBuffer =
- mRecordingSampleBufferFactory.create(
+ new RecordingSampleBuffer(
mBufferManager,
mBufferListener,
true,
+ mConcurrentDvrPlaybackFlags,
RecordingSampleBuffer.BUFFER_REASON_RECORDED_PLAYBACK);
mSampleBuffer.init(ids, mTrackFormats);
return true;
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
index 67cf992c..6781c616 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
@@ -43,8 +43,7 @@ import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.audio.AudioCapabilities;
import com.google.android.exoplayer.audio.AudioTrack;
-import com.google.android.exoplayer2.upstream.DataSource;
-
+import com.google.android.exoplayer.upstream.DataSource;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -148,7 +147,7 @@ public class MpegTsPlayer
*
* @param rendererBuilder the builder of track renderers
* @param handler the handler for the playback events in track renderers
- * @param sourceManager the manager for {@link TsDataSource}
+ * @param sourceManager the manager for {@link DataSource}
* @param capabilities the {@link AudioCapabilities} of the current device
* @param listener the listener for playback state changes
*/
@@ -215,7 +214,7 @@ public class MpegTsPlayer
}
/**
- * Creates renderers and {@link TsDataSource} and initializes player.
+ * Creates renderers and {@link DataSource} and initializes player.
*
* @param context a {@link Context} instance
* @param channel to play
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
index f860631c..e043907f 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
@@ -17,51 +17,33 @@
package com.android.tv.tuner.exoplayer;
import android.content.Context;
-import android.support.annotation.Nullable;
-
import com.android.tv.tuner.exoplayer.MpegTsPlayer.RendererBuilder;
import com.android.tv.tuner.exoplayer.MpegTsPlayer.RendererBuilderCallback;
import com.android.tv.tuner.exoplayer.audio.MpegTsDefaultAudioTrackRenderer;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
-
import com.google.android.exoplayer.MediaCodecSelector;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackRenderer;
-import com.google.android.exoplayer2.upstream.DataSource;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
+import com.google.android.exoplayer.upstream.DataSource;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/** Builder for renderer objects for {@link MpegTsPlayer}. */
public class MpegTsRendererBuilder implements RendererBuilder {
private final Context mContext;
private final BufferManager mBufferManager;
private final PlaybackBufferListener mBufferListener;
- private final MpegTsSampleExtractor.Factory mMpegTsSampleExtractorFactory;
-
- /**
- * Factory for {@link MpegTsRendererBuilder}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public MpegTsRendererBuilder create(
- Context context,
- @Nullable BufferManager bufferManager,
- PlaybackBufferListener bufferListener);
- }
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
- @AutoFactory(implementing = Factory.class)
public MpegTsRendererBuilder(
Context context,
- @Nullable BufferManager bufferManager,
+ BufferManager bufferManager,
PlaybackBufferListener bufferListener,
- @Provided MpegTsSampleExtractor.Factory mpegTsSampleExtractorFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
mContext = context;
mBufferManager = bufferManager;
mBufferListener = bufferListener;
- mMpegTsSampleExtractorFactory = mpegTsSampleExtractorFactory;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
}
@Override
@@ -70,9 +52,13 @@ public class MpegTsRendererBuilder implements RendererBuilder {
// Build the video and audio renderers.
SampleExtractor extractor =
dataSource == null
- ? mMpegTsSampleExtractorFactory.create(mBufferManager, mBufferListener)
- : mMpegTsSampleExtractorFactory.create(
- dataSource, mBufferManager, mBufferListener);
+ ? new MpegTsSampleExtractor(
+ mBufferManager, mBufferListener, mConcurrentDvrPlaybackFlags)
+ : new MpegTsSampleExtractor(
+ dataSource,
+ mBufferManager,
+ mBufferListener,
+ mConcurrentDvrPlaybackFlags);
SampleSource sampleSource = new MpegTsSampleSource(extractor);
MpegTsVideoTrackRenderer videoRenderer =
new MpegTsVideoTrackRenderer(
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsSampleExtractor.java b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsSampleExtractor.java
index 8d3668ef..582f18c5 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/MpegTsSampleExtractor.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/MpegTsSampleExtractor.java
@@ -18,21 +18,16 @@ package com.android.tv.tuner.exoplayer;
import android.net.Uri;
import android.os.Handler;
-import android.support.annotation.Nullable;
-
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
import com.android.tv.tuner.exoplayer.buffer.SamplePool;
-
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.upstream.DataSource;
import com.google.android.exoplayer.util.MimeTypes;
-import com.google.android.exoplayer2.upstream.DataSource;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -64,37 +59,27 @@ public final class MpegTsSampleExtractor implements SampleExtractor {
}
/**
- * Factory for {@link MpegTsSampleExtractor}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public MpegTsSampleExtractor create(
- BufferManager bufferManager, PlaybackBufferListener bufferListener);
-
- public MpegTsSampleExtractor create(
- DataSource source,
- @Nullable BufferManager bufferManager,
- PlaybackBufferListener bufferListener);
- }
-
- /**
- * Creates MpegTsSampleExtractor for a {@link DataSource}.
+ * Creates MpegTsSampleExtractor for {@link DataSource}.
*
* @param source the {@link DataSource} to extract from
* @param bufferManager the manager for reading & writing samples backed by physical storage
* @param bufferListener the {@link PlaybackBufferListener} to notify buffer storage status
+ * @param concurrentDvrPlaybackFlags
*/
- @AutoFactory(implementing = Factory.class)
public MpegTsSampleExtractor(
DataSource source,
- @Nullable BufferManager bufferManager,
+ BufferManager bufferManager,
PlaybackBufferListener bufferListener,
- @Provided ExoPlayerSampleExtractor.Factory exoPlayerSampleExtractorFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+
mSampleExtractor =
- exoPlayerSampleExtractorFactory.create(
- Uri.EMPTY, source, bufferManager, bufferListener, false);
+ new ExoPlayerSampleExtractor(
+ Uri.EMPTY,
+ source,
+ bufferManager,
+ bufferListener,
+ false,
+ concurrentDvrPlaybackFlags);
init();
}
@@ -105,12 +90,12 @@ public final class MpegTsSampleExtractor implements SampleExtractor {
* @param bufferListener the {@link PlaybackBufferListener} to notify buffer storage status
* change
*/
- @AutoFactory(implementing = Factory.class)
public MpegTsSampleExtractor(
BufferManager bufferManager,
PlaybackBufferListener bufferListener,
- @Provided FileSampleExtractor.Factory fileSampleExtractorFactory) {
- mSampleExtractor = fileSampleExtractorFactory.create(bufferManager, bufferListener);
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ mSampleExtractor =
+ new FileSampleExtractor(bufferManager, bufferListener, concurrentDvrPlaybackFlags);
init();
}
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java b/tuner/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java
index fb88e5b7..bab74c9d 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java
@@ -246,7 +246,6 @@ public class MpegTsDefaultAudioTrackRenderer extends TrackRenderer implements Me
mSource.seekToUs(positionUs);
AUDIO_TRACK.reset();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
- // b/21824483 workaround
// resetSessionId() will create a new framework AudioTrack instead of reusing old one.
AUDIO_TRACK.resetSessionId();
}
@@ -285,7 +284,6 @@ public class MpegTsDefaultAudioTrackRenderer extends TrackRenderer implements Me
// Ensure playback stops, after EoS was notified.
// Sometimes MediaCodecTrackRenderer does not fetch EoS timely
// after EoS was notified here long before.
- // see b/21909113
long diff = SystemClock.elapsedRealtime() - mEndOfStreamMs;
if (diff >= KEEP_ALIVE_AFTER_EOS_DURATION_MS && !mIsStopped) {
throw new ExoPlaybackException("Much time has elapsed after EoS");
@@ -594,7 +592,6 @@ public class MpegTsDefaultAudioTrackRenderer extends TrackRenderer implements Me
}
mCurrentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
} else {
- // TODO: Remove this workaround when b/22023809 is resolved.
if (mPreviousPositionUs
> audioTrackCurrentPositionUs + BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US) {
Log.e(
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java b/tuner/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
index b8d85230..c32540c1 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
@@ -23,13 +23,10 @@ import android.support.annotation.VisibleForTesting;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
-
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.tuner.exoplayer.SampleExtractor;
-
import com.google.android.exoplayer.SampleHolder;
-
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -403,13 +400,13 @@ public class BufferManager {
SampleChunk sampleChunk =
mSampleChunkCreator.createSampleChunk(
samplePool, file, positionUs, mChunkCallback);
- map.put(positionUs, Pair.create(sampleChunk, 0));
+ map.put(positionUs, new Pair(sampleChunk, 0));
if (updateIndexFile) {
mStorageManager.updateIndexFile(id, map.size(), positionUs, sampleChunk, 0);
}
return sampleChunk;
} else {
- map.put(positionUs, Pair.create(currentChunk, currentOffset));
+ map.put(positionUs, new Pair(currentChunk, currentOffset));
if (updateIndexFile) {
mStorageManager.updateIndexFile(
id, map.size(), positionUs, currentChunk, currentOffset);
@@ -450,7 +447,7 @@ public class BufferManager {
chunk);
basePositionUs = position.basePositionUs;
}
- map.put(position.positionUs, Pair.create(chunk, position.offset));
+ map.put(position.positionUs, new Pair(chunk, position.offset));
}
}
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java b/tuner/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
index 0e1cbe9f..f19756ec 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
@@ -19,7 +19,8 @@ package com.android.tv.tuner.exoplayer.buffer;
import android.media.MediaFormat;
import android.util.Log;
import android.util.Pair;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
+import com.google.protobuf.nano.MessageNano;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -368,7 +369,7 @@ public class DvrStorageManager implements BufferManager.StorageManager {
META_FILE_TYPE_CAPTION + ((i == 0) ? META_FILE_SUFFIX : (i + META_FILE_SUFFIX));
File file = new File(getBufferDir(), fileName);
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
- track.writeTo(out);
+ out.write(MessageNano.toByteArray(track));
} catch (Exception e) {
Log.e(TAG, "Fail to write caption info to files", e);
}
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java b/tuner/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
index df2cd2e6..d95642c2 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
@@ -20,18 +20,14 @@ import android.os.ConditionVariable;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.util.Log;
-
import com.android.tv.tuner.exoplayer.MpegTsPlayer;
import com.android.tv.tuner.exoplayer.SampleExtractor;
-
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.util.Assertions;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -73,7 +69,7 @@ public class RecordingSampleBuffer
private final BufferManager mBufferManager;
private final PlaybackBufferListener mBufferListener;
private final @BufferReason int mBufferReason;
- private final SampleChunkIoHelper.Factory mSampleChunkIoHelperFactory;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private int mTrackCount;
private boolean[] mTrackSelected;
@@ -102,42 +98,28 @@ public class RecordingSampleBuffer
};
/**
- * Factory for {@link RecordingSampleBuffer}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public RecordingSampleBuffer create(
- BufferManager bufferManager,
- PlaybackBufferListener bufferListener,
- boolean enableTrickplay,
- @BufferReason int bufferReason);
- }
-
- /**
* Creates {@link BufferManager.SampleBuffer} with cached I/O backed by physical storage (e.g.
* trickplay,recording,recorded-playback).
*
* @param bufferManager the manager of {@link SampleChunk}
* @param bufferListener the listener for buffer I/O event
* @param enableTrickplay {@code true} when trickplay should be enabled
+ * @param concurrentDvrPlaybackFlags
* @param bufferReason the reason for caching samples {@link BufferReason}
*/
- @AutoFactory(implementing = Factory.class)
public RecordingSampleBuffer(
BufferManager bufferManager,
PlaybackBufferListener bufferListener,
boolean enableTrickplay,
- @BufferReason int bufferReason,
- @Provided SampleChunkIoHelper.Factory sampleChunkIoHelperFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ @BufferReason int bufferReason) {
mBufferManager = bufferManager;
mBufferListener = bufferListener;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
if (bufferListener != null) {
bufferListener.onBufferStateChanged(enableTrickplay);
}
mBufferReason = bufferReason;
- mSampleChunkIoHelperFactory = sampleChunkIoHelperFactory;
}
@Override
@@ -150,8 +132,14 @@ public class RecordingSampleBuffer
mTrackSelected = new boolean[mTrackCount];
mReadSampleQueues = new ArrayList<>();
mSampleChunkIoHelper =
- mSampleChunkIoHelperFactory.create(
- ids, mediaFormats, mBufferReason, mBufferManager, mSamplePool, mIoCallback);
+ new SampleChunkIoHelper(
+ ids,
+ mediaFormats,
+ mBufferReason,
+ mBufferManager,
+ mSamplePool,
+ mIoCallback,
+ mConcurrentDvrPlaybackFlags);
for (int i = 0; i < mTrackCount; ++i) {
mReadSampleQueues.add(i, new SampleQueue(mSamplePool));
}
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java b/tuner/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
index 82bf0df8..f4d3bf8e 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
@@ -24,17 +24,12 @@ import android.os.Message;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
-
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.flags.DvrFlags;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer.BufferReason;
-
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.util.MimeTypes;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -69,7 +64,7 @@ public class SampleChunkIoHelper implements Handler.Callback {
private final BufferManager mBufferManager;
private final SamplePool mSamplePool;
private final IoCallback mIoCallback;
- private final DvrFlags mDvrFlags;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private Handler mIoHandler;
private final ConcurrentLinkedQueue<SampleHolder> mReadSampleBuffers[];
@@ -118,22 +113,6 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
/**
- * Factory for {@link SampleChunkIoHelper}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public SampleChunkIoHelper create(
- List<String> ids,
- List<MediaFormat> mediaFormats,
- @BufferReason int bufferReason,
- BufferManager bufferManager,
- SamplePool samplePool,
- IoCallback ioCallback);
- }
-
- /**
* Creates {@link SampleChunk} I/O handler.
*
* @param ids track names
@@ -142,8 +121,8 @@ public class SampleChunkIoHelper implements Handler.Callback {
* @param bufferManager manager of {@link SampleChunk} collections
* @param samplePool allocator for a sample
* @param ioCallback listeners for I/O events
+ * @param concurrentDvrPlaybackFlags
*/
- @AutoFactory(implementing = Factory.class)
public SampleChunkIoHelper(
List<String> ids,
List<MediaFormat> mediaFormats,
@@ -151,7 +130,7 @@ public class SampleChunkIoHelper implements Handler.Callback {
BufferManager bufferManager,
SamplePool samplePool,
IoCallback ioCallback,
- @Provided DvrFlags dvrFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
mTrackCount = ids.size();
mIds = ids;
mMediaFormats = mediaFormats;
@@ -159,7 +138,7 @@ public class SampleChunkIoHelper implements Handler.Callback {
mBufferManager = bufferManager;
mSamplePool = samplePool;
mIoCallback = ioCallback;
- mDvrFlags = dvrFlags;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
mReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
mHandlerReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
@@ -205,7 +184,9 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
try {
- if (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING && mTrackCount > 0) {
+ if (mConcurrentDvrPlaybackFlags.enabled()
+ && mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING
+ && mTrackCount > 0) {
// Saves meta information for recording.
List<BufferManager.TrackFormat> audios = new ArrayList<>(mTrackCount);
List<BufferManager.TrackFormat> videos = new ArrayList<>(mTrackCount);
@@ -213,14 +194,6 @@ public class SampleChunkIoHelper implements Handler.Callback {
android.media.MediaFormat format =
mMediaFormats.get(i).getFrameworkMediaFormatV16();
format.setLong(android.media.MediaFormat.KEY_DURATION, mBufferDurationUs);
- if (mDvrFlags.storeVideoAspectRatio() &&
- mMediaFormats.get(i).pixelWidthHeightRatio > 0) {
- // MediaFormats doesn't store aspect ratio so updating the width
- // to maintain aspect ratio.
- format.setInteger(android.media.MediaFormat.KEY_WIDTH,
- (int) (mMediaFormats.get(i).width *
- mMediaFormats.get(i).pixelWidthHeightRatio));
- }
if (MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
audios.add(new BufferManager.TrackFormat(mIds.get(i), format));
} else if (MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
@@ -329,14 +302,6 @@ public class SampleChunkIoHelper implements Handler.Callback {
android.media.MediaFormat format =
mMediaFormats.get(i).getFrameworkMediaFormatV16();
format.setLong(android.media.MediaFormat.KEY_DURATION, mBufferDurationUs);
- if (mDvrFlags.storeVideoAspectRatio() &&
- mMediaFormats.get(i).pixelWidthHeightRatio > 0) {
- // MediaFormats doesn't store aspect ratio so updating the width
- // to maintain aspect ratio.
- format.setInteger(android.media.MediaFormat.KEY_WIDTH,
- (int) (mMediaFormats.get(i).width *
- mMediaFormats.get(i).pixelWidthHeightRatio));
- }
if (MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
audios.add(new BufferManager.TrackFormat(mIds.get(i), format));
} else if (MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
@@ -419,7 +384,8 @@ public class SampleChunkIoHelper implements Handler.Callback {
private void doOpenWrite(int index) throws IOException {
boolean updateIndexFile =
- (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING)
+ mConcurrentDvrPlaybackFlags.enabled()
+ && (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING)
&& (MimeTypes.isVideo(mMediaFormats.get(index).mimeType)
|| MimeTypes.isAudio(mMediaFormats.get(index).mimeType));
@@ -460,10 +426,13 @@ public class SampleChunkIoHelper implements Handler.Callback {
SampleHolder sample = mReadIoStates[index].read();
if (sample != null) {
mHandlerReadSampleBuffers[index].offer(sample);
- mReadChunkOffset[index] = mReadIoStates[index].getOffset();
- mReadChunkPositionUs[index] = sample.timeUs;
+ if (mConcurrentDvrPlaybackFlags.enabled()) {
+ mReadChunkOffset[index] = mReadIoStates[index].getOffset();
+ mReadChunkPositionUs[index] = sample.timeUs;
+ }
} else {
- if (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDED_PLAYBACK) {
+ if (mConcurrentDvrPlaybackFlags.enabled()
+ && mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDED_PLAYBACK) {
// Update Index, to load new Samples
updateIndex(index, mReadChunkOffset[index]);
}
@@ -516,7 +485,9 @@ public class SampleChunkIoHelper implements Handler.Callback {
: mWriteIoStates[params.index].getChunk();
int currentOffset = (int) mWriteIoStates[params.index].getOffset();
boolean updateIndexFile =
- (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING)
+ mConcurrentDvrPlaybackFlags.enabled()
+ && (mBufferReason
+ == RecordingSampleBuffer.BUFFER_REASON_RECORDING)
&& (MimeTypes.isVideo(mMediaFormats.get(index).mimeType)
|| MimeTypes.isAudio(
mMediaFormats.get(index).mimeType));
diff --git a/tuner/src/com/android/tv/tuner/exoplayer2/VideoRendererExoV2.java b/tuner/src/com/android/tv/tuner/exoplayer2/VideoRendererExoV2.java
index a71352f3..12039002 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer2/VideoRendererExoV2.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer2/VideoRendererExoV2.java
@@ -24,6 +24,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
+import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.lang.reflect.Field;
@@ -47,8 +48,8 @@ public class VideoRendererExoV2 extends MediaCodecVideoRenderer {
private static final String SOFTWARE_DECODER_NAME_PREFIX = "OMX.google.";
private static final long ALLOWED_JOINING_TIME_MS = 5000;
private static final int DROPPED_FRAMES_NOTIFICATION_THRESHOLD = 10;
- // private static final int MIN_HD_HEIGHT = 720;
- private static Field sRenderedFirstFrameField;
+ private static final int MIN_HD_HEIGHT = 720;
+ private static Field sRenderedFirstFrameField;
private final boolean mIsSwCodecEnabled;
private boolean mCodecIsSwPreferred;
@@ -107,18 +108,16 @@ public class VideoRendererExoV2 extends MediaCodecVideoRenderer {
return decoderInfos;
}
- // TODO: Uncomment once ExoPlayer v2.10.0 is released [Internal ref: b/130625979].
- // @Override
- // protected void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
- // Format format = formatHolder.format;
- // mCodecIsSwPreferred =
- // MimeTypes.VIDEO_MPEG2.equals(format.sampleMimeType)
- // && format.height < MIN_HD_HEIGHT;
- // super.onInputFormatChanged(format);
- // }
+ @Override
+ protected void onInputFormatChanged(Format format) throws ExoPlaybackException {
+ mCodecIsSwPreferred =
+ MimeTypes.VIDEO_MPEG2.equals(format.sampleMimeType)
+ && format.height < MIN_HD_HEIGHT;
+ super.onInputFormatChanged(format);
+ }
- @Override
- protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
+ @Override
+ protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
super.onPositionReset(positionUs, joining);
// Disabling pre-rendering of the first frame in order to avoid a frozen picture when
// starting the playback. We do this only once, when the renderer is enabled at first, since
diff --git a/tuner/src/com/android/tv/tuner/features/TunerFeatures.java b/tuner/src/com/android/tv/tuner/features/TunerFeatures.java
index 6ee5aa8c..6033a3a6 100644
--- a/tuner/src/com/android/tv/tuner/features/TunerFeatures.java
+++ b/tuner/src/com/android/tv/tuner/features/TunerFeatures.java
@@ -19,9 +19,9 @@ package com.android.tv.tuner.features;
import static com.android.tv.common.feature.FeatureUtils.OFF;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.DeveloperPreferenceFeature;
import com.android.tv.common.feature.Feature;
import com.android.tv.common.feature.Model;
+import com.android.tv.common.feature.PropertyFeature;
import com.android.tv.common.feature.Sdk;
/**
@@ -39,11 +39,10 @@ public class TunerFeatures extends CommonFeatures {
* <p>Prefer software based codec for SD channels.
*/
public static final Feature USE_SW_CODEC_FOR_SD =
- DeveloperPreferenceFeature.create(
+ PropertyFeature.create(
"use_sw_codec_for_sd",
- // On Nexus Player, SW codec is better than HW codec in terms of picture
- // quality.
- Model.NEXUS_PLAYER.isEnabled());
+ false
+ );
/**
* Does the TvProvider on the installed device allow systems inserts to the programs table.
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunChannelScan.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunChannelScan.java
deleted file mode 100644
index 38610dd1..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunChannelScan.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.os.ConditionVariable;
-import android.util.Log;
-import android.util.Xml;
-import com.android.tv.tuner.api.ChannelScanListener;
-import com.android.tv.tuner.data.TunerChannel;
-import com.android.tv.tuner.ts.EventDetector.EventListener;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.regex.Pattern;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/** A helper class to perform channel scan on HDHomeRun tuner. */
-public class HdHomeRunChannelScan {
- private static final String TAG = "HdHomeRunChannelScan";
- private static final boolean DEBUG = false;
-
- private static final String LINEUP_FILENAME = "lineup.xml";
- private static final String NAME_LINEUP = "Lineup";
- private static final String NAME_PROGRAM = "Program";
- private static final String NAME_GUIDE_NUMBER = "GuideNumber";
- private static final String NAME_GUIDE_NAME = "GuideName";
- private static final String NAME_HD = "HD";
- private static final String NAME_TAGS = "Tags";
- private static final String NAME_DRM = "DRM";
-
- private final Context mContext;
- private final ChannelScanListener mEventListener;
- private final HdHomeRunTunerHal mTunerHal;
- private int mProgramCount;
-
- public HdHomeRunChannelScan(
- Context context, EventListener eventListener, HdHomeRunTunerHal hal) {
- mContext = context;
- mEventListener = eventListener;
- mTunerHal = hal;
- }
-
- public void scan(ConditionVariable conditionStopped) {
- String urlString = "http://" + mTunerHal.getIpAddress() + "/" + LINEUP_FILENAME;
- if (DEBUG) Log.d(TAG, "Reading " + urlString);
- URL url;
- HttpURLConnection connection = null;
- InputStream inputStream;
- try {
- url = new URL(urlString);
- connection = (HttpURLConnection) url.openConnection();
- connection.setReadTimeout(HdHomeRunTunerHal.READ_TIMEOUT_MS_FOR_URLCONNECTION);
- connection.setConnectTimeout(HdHomeRunTunerHal.CONNECTION_TIMEOUT_MS_FOR_URLCONNECTION);
- connection.setRequestMethod("GET");
- connection.setDoInput(true);
- connection.connect();
- inputStream = connection.getInputStream();
- } catch (IOException e) {
- Log.e(TAG, "Connection failed: " + urlString, e);
- if (connection != null) {
- connection.disconnect();
- }
- return;
- }
- if (conditionStopped.block(-1)) {
- try {
- inputStream.close();
- } catch (IOException e) {
- // Does nothing.
- }
- connection.disconnect();
- return;
- }
-
- XmlPullParser parser = Xml.newPullParser();
- try {
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
- parser.setInput(inputStream, null);
- parser.nextTag();
- parser.require(XmlPullParser.START_TAG, null, NAME_LINEUP);
- while (parser.next() != XmlPullParser.END_TAG) {
- if (conditionStopped.block(-1)) {
- break;
- }
- if (parser.getEventType() != XmlPullParser.START_TAG) {
- continue;
- }
- String name = parser.getName();
- // Starts by looking for the program tag
- if (name.equals(NAME_PROGRAM)) {
- readProgram(parser);
- } else {
- skip(parser);
- }
- }
- inputStream.close();
- } catch (IOException | XmlPullParserException e) {
- Log.e(TAG, "Parse error", e);
- }
- connection.disconnect();
- mTunerHal.markAsScannedDevice(mContext);
- }
-
- private void readProgram(XmlPullParser parser) throws XmlPullParserException, IOException {
- parser.require(XmlPullParser.START_TAG, null, NAME_PROGRAM);
- String guideNumber = "";
- String guideName = "";
- String videoFormat = null;
- String tags = "";
- boolean recordingProhibited = false;
- while (parser.next() != XmlPullParser.END_TAG) {
- if (parser.getEventType() != XmlPullParser.START_TAG) {
- continue;
- }
- String name = parser.getName();
- if (name.equals(NAME_GUIDE_NUMBER)) {
- guideNumber = readText(parser, NAME_GUIDE_NUMBER);
- } else if (name.equals(NAME_GUIDE_NAME)) {
- guideName = readText(parser, NAME_GUIDE_NAME);
- } else if (name.equals(NAME_HD)) {
- videoFormat = TvContract.Channels.VIDEO_FORMAT_720P;
- skip(parser);
- } else if (name.equals(NAME_TAGS)) {
- tags = readText(parser, NAME_TAGS);
- } else if (name.equals(NAME_DRM)) {
- String drm = readText(parser, NAME_DRM);
- try {
- recordingProhibited = (Integer.parseInt(drm)) != 0;
- } catch (NumberFormatException e) {
- Log.e(TAG, "Load DRM property failed: illegal number: " + drm);
- // If DRM property is present, we treat it as copy-once or copy-never.
- recordingProhibited = true;
- }
- } else {
- skip(parser);
- }
- }
- if (!tags.isEmpty()) {
- // Skip encrypted channels since we don't know how to decrypt them.
- return;
- }
- int major;
- int minor = 0;
- final String separator = Character.toString(HdHomeRunTunerHal.VCHANNEL_SEPARATOR);
- if (guideNumber.contains(separator)) {
- String[] parts = guideNumber.split(Pattern.quote(separator));
- major = Integer.parseInt(parts[0]);
- minor = Integer.parseInt(parts[1]);
- } else {
- major = Integer.parseInt(guideNumber);
- }
- // Need to assign a unique program number (i.e. mProgramCount) to avoid being duplicated.
- mEventListener.onChannelDetected(
- TunerChannel.forNetwork(
- major, minor, mProgramCount++, guideName, recordingProhibited, videoFormat),
- true);
- }
-
- private String readText(XmlPullParser parser, String name)
- throws IOException, XmlPullParserException {
- String result = "";
- parser.require(XmlPullParser.START_TAG, null, name);
- if (parser.next() == XmlPullParser.TEXT) {
- result = parser.getText();
- parser.nextTag();
- }
- parser.require(XmlPullParser.END_TAG, null, name);
- if (DEBUG) Log.d(TAG, "<" + name + ">=" + result);
- return result;
- }
-
- private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
- if (parser.getEventType() != XmlPullParser.START_TAG) {
- throw new IllegalStateException();
- }
- int depth = 1;
- while (depth != 0) {
- switch (parser.next()) {
- case XmlPullParser.END_TAG:
- depth--;
- break;
- case XmlPullParser.START_TAG:
- depth++;
- break;
- }
- }
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunControlSocket.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunControlSocket.java
deleted file mode 100644
index ce7c5180..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunControlSocket.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.support.annotation.Nullable;
-import android.util.Log;
-import android.util.Pair;
-import com.android.tv.tuner.hdhomerun.HdHomeRunDiscover.HdHomeRunDiscoverDevice;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A class to send/receive control commands and results to/from HDHomeRun devices via TCP sockets.
- * {@link #close()} method should be called after usage to close the TCP socket.
- */
-class HdHomeRunControlSocket implements AutoCloseable {
- private static final String TAG = "HdHomeRunControlSocket";
- private static final boolean DEBUG = false;
-
- private int mDesiredDeviceId;
- private int mDesiredDeviceIp;
- private int mActualDeviceId;
- private int mActualDeviceIp;
- private Socket mSocket;
-
- HdHomeRunControlSocket(int deviceId, int deviceIp) {
- mDesiredDeviceId = deviceId;
- mDesiredDeviceIp = deviceIp;
- mActualDeviceId = 0;
- mActualDeviceIp = 0;
- }
-
- /**
- * Gets control settings from HDHomeRun devices.
- *
- * @param name the name of the field whose value we want to get.
- */
- @Nullable
- String get(String name) {
- byte[] data = new byte[name.length() + 3];
- ByteBuffer buffer = ByteBuffer.wrap(data);
- buffer.put(HdHomeRunUtils.HDHOMERUN_TAG_GETSET_NAME);
- buffer.put((byte) (name.length() + 1));
- buffer.put(name.getBytes());
-
- // Send & Receive.
- byte[] result =
- sendAndReceive(
- data,
- HdHomeRunUtils.HDHOMERUN_TYPE_GETSET_REQUEST,
- HdHomeRunUtils.HDHOMERUN_CONTROL_RECEIVE_TIMEOUT_MS);
- if (result == null) {
- if (DEBUG) Log.d(TAG, "Cannot get result for " + name);
- return null;
- }
-
- // Response.
- buffer = ByteBuffer.wrap(result);
- while (true) {
- Pair<Byte, byte[]> tagAndValue = HdHomeRunUtils.readTaggedValue(buffer);
- if (tagAndValue == null) {
- break;
- }
- switch (tagAndValue.first) {
- case HdHomeRunUtils.HDHOMERUN_TAG_GETSET_VALUE:
- // Removes the 0 tail.
- return new String(
- Arrays.copyOfRange(
- tagAndValue.second, 0, tagAndValue.second.length - 1));
- case HdHomeRunUtils.HDHOMERUN_TAG_ERROR_MESSAGE:
- return null;
- }
- }
- return null;
- }
-
- /** Gets ID of HDHomeRun devices. */
- int getDeviceId() {
- if (!connectAndUpdateDeviceInfo()) {
- return 0;
- }
- return mActualDeviceId;
- }
-
- private boolean connectAndUpdateDeviceInfo() {
- if (mSocket != null) {
- return true;
- }
- if ((mDesiredDeviceId == 0) && (mDesiredDeviceIp == 0)) {
- if (DEBUG) Log.d(TAG, "Desired ID and IP cannot be both zero.");
- return false;
- }
- if (HdHomeRunUtils.isIpMulticast(mDesiredDeviceIp)) {
- if (DEBUG) Log.d(TAG, "IP cannot be multicast IP.");
- return false;
- }
-
- // Find device.
- List<HdHomeRunDiscoverDevice> result =
- HdHomeRunUtils.findHdHomeRunDevices(
- mDesiredDeviceIp,
- HdHomeRunUtils.HDHOMERUN_DEVICE_TYPE_WILDCARD,
- mDesiredDeviceId,
- 1);
- if (result.isEmpty()) {
- if (DEBUG) Log.d(TAG, "Cannot find device on: " + mDesiredDeviceIp);
- return false;
- }
- mActualDeviceIp = result.get(0).mIpAddress;
- mActualDeviceId = result.get(0).mDeviceId;
-
- // Create socket and initiate connection.
- mSocket = new Socket();
- try {
- mSocket.connect(
- new InetSocketAddress(
- HdHomeRunUtils.intToAddress(mActualDeviceIp),
- HdHomeRunUtils.HDHOMERUN_CONTROL_TCP_PORT),
- HdHomeRunUtils.HDHOMERUN_CONTROL_CONNECT_TIMEOUT_MS);
- } catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Cannot connect to socket: " + mSocket);
- mSocket = null;
- return false;
- }
-
- // Success.
- Log.i(TAG, "Connected to socket: " + mSocket);
- return true;
- }
-
- private byte[] sendAndReceive(byte[] data, short type, int timeout) {
- byte[] sealedData = HdHomeRunUtils.sealFrame(data, type);
- for (int i = 0; i < 2; i++) {
- if (mSocket == null && !connectAndUpdateDeviceInfo()) {
- return null;
- }
- if (!send(sealedData)) {
- continue;
- }
- Pair<Short, byte[]> receivedData = receive(timeout);
- if (receivedData == null || receivedData.first == null) {
- continue;
- }
- if (receivedData.first != type + 1) {
- if (DEBUG) Log.d(TAG, "Returned type incorrect: " + receivedData.first);
- close();
- continue;
- }
- return receivedData.second;
- }
- return null;
- }
-
- private boolean send(byte[] data) {
- try {
- OutputStream out = mSocket.getOutputStream();
- mSocket.setSoTimeout(HdHomeRunUtils.HDHOMERUN_CONTROL_SEND_TIMEOUT_MS);
- out.write(data);
- } catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Cannot send packet to socket: " + mSocket);
- close();
- return false;
- }
- return true;
- }
-
- private Pair<Short, byte[]> receive(int timeout) {
- byte[] receivedData = new byte[3074];
- try {
- InputStream input = mSocket.getInputStream();
- mSocket.setSoTimeout(timeout);
- int index = 0;
- long startTime = System.currentTimeMillis();
- while (System.currentTimeMillis() - startTime < timeout) {
- int length = receivedData.length - index;
- index += input.read(receivedData, index, length);
- Pair<Short, byte[]> result = HdHomeRunUtils.openFrame(receivedData, index);
- if (result != null) {
- if (result.first == HdHomeRunUtils.HDHOMERUN_TYPE_INVALID) {
- if (DEBUG) Log.d(TAG, "Returned type is invalid.");
- close();
- return null;
- }
- return result;
- }
- if (DEBUG) Log.d(TAG, "Received result is null!");
- }
- } catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Cannot receive from socket: " + mSocket);
- close();
- }
- return null;
- }
-
- @Override
- public void close() {
- if (mSocket != null) {
- try {
- mSocket.close();
- } catch (IOException e) {
- // Do nothing
- }
- mSocket = null;
- }
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDevice.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDevice.java
deleted file mode 100644
index dcf87cad..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDevice.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-/**
- * An HDHomeRun device detected on the network. This abstraction only contains network data
- * necessary to establish a connection with the device and does not represent a communication
- * channel with the device itself. Currently, we only support devices with HTTP streaming
- * functionality.
- */
-public class HdHomeRunDevice implements Parcelable {
- private int mIpAddress;
- private int mDeviceType;
- private int mDeviceId;
- private int mTunerIndex;
- private String mDeviceModel;
-
- /**
- * Creates {@code HdHomeRunDevice} object from a parcel.
- *
- * @param parcel The parcel to create {@code HdHomeRunDevice} object from.
- */
- public HdHomeRunDevice(Parcel parcel) {
- mIpAddress = parcel.readInt();
- mDeviceType = parcel.readInt();
- mDeviceId = parcel.readInt();
- mTunerIndex = parcel.readInt();
- mDeviceModel = parcel.readString();
- }
-
- /**
- * Creates {@code HdHomeRunDevice} object from IP address, device type, device ID and tuner
- * index.
- *
- * @param ipAddress The IP address to create {@code HdHomeRunDevice} object from.
- * @param deviceType The device type to create {@code HdHomeRunDevice} object from.
- * @param deviceId The device ID to create {@code HdHomeRunDevice} object from.
- * @param tunerIndex The tuner index to {@code HdHomeRunDevice} object from.
- */
- public HdHomeRunDevice(
- int ipAddress, int deviceType, int deviceId, int tunerIndex, String deviceModel) {
- mIpAddress = ipAddress;
- mDeviceType = deviceType;
- mDeviceId = deviceId;
- mTunerIndex = tunerIndex;
- mDeviceModel = deviceModel;
- }
-
- /**
- * Returns the IP address.
- *
- * @return the IP address of this homerun device.
- */
- public int getIpAddress() {
- return mIpAddress;
- }
-
- /**
- * Returns the device type.
- *
- * @return the type of device for this homerun device.
- */
- public int getDeviceType() {
- return mDeviceType;
- }
-
- /**
- * Returns the device ID.
- *
- * @return the device ID of this homerun device.
- */
- public int getDeviceId() {
- return mDeviceId;
- }
-
- /**
- * Returns the tuner index.
- *
- * @return the tuner index of this homerun device.
- */
- public int getTunerIndex() {
- return mTunerIndex;
- }
-
- /**
- * Returns the device model.
- *
- * @return the device model of this homerun device.
- */
- public String getDeviceModel() {
- return mDeviceModel;
- }
-
- @Override
- public String toString() {
- String ipAddress =
- ""
- + ((mIpAddress >>> 24) & 0xff)
- + "."
- + ((mIpAddress >>> 16) & 0xff)
- + "."
- + ((mIpAddress >>> 8) & 0xff)
- + "."
- + (mIpAddress & 0xff);
- return String.format("[%x-%d:%s]", mDeviceId, mTunerIndex, ipAddress);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mIpAddress);
- out.writeInt(mDeviceType);
- out.writeInt(mDeviceId);
- out.writeInt(mTunerIndex);
- out.writeString(mDeviceModel);
- }
-
- @Override
- public int hashCode() {
- int hash = 17;
- hash = hash * 31 + getIpAddress();
- hash = hash * 31 + getDeviceType();
- hash = hash * 31 + getDeviceId();
- hash = hash * 31 + getTunerIndex();
- return hash;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof HdHomeRunDevice)) {
- return false;
- }
- HdHomeRunDevice rhs = (HdHomeRunDevice) o;
- return rhs != null
- && getIpAddress() == rhs.getIpAddress()
- && getDeviceType() == rhs.getDeviceType()
- && getDeviceId() == rhs.getDeviceId()
- && getTunerIndex() == rhs.getTunerIndex()
- && TextUtils.equals(getDeviceModel(), rhs.getDeviceModel());
- }
-
- public static final Parcelable.Creator<HdHomeRunDevice> CREATOR =
- new Parcelable.Creator<HdHomeRunDevice>() {
-
- @Override
- public HdHomeRunDevice createFromParcel(Parcel in) {
- return new HdHomeRunDevice(in);
- }
-
- @Override
- public HdHomeRunDevice[] newArray(int size) {
- return new HdHomeRunDevice[size];
- }
- };
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDiscover.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDiscover.java
deleted file mode 100644
index 85b3450e..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunDiscover.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.support.annotation.NonNull;
-import android.util.Log;
-import android.util.Pair;
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-
-/** A class to discover HDHomeRun devices on the network with UDP broadcasting. */
-class HdHomeRunDiscover {
- private static final String TAG = "HdHomeRunDiscover";
- private static final boolean DEBUG = false;
-
- private static final int HDHOMERUN_DISCOVER_MAX_SOCK_COUNT = 16;
- private static final int HDHOMERUN_DISCOVER_RETRY_LIMIT = 2;
- private static final int HDHOMERUN_DISCOVER_TIMEOUT_MS = 500;
- private static final int HDHOMERUN_DISCOVER_RECEIVE_WAITE_TIME_MS = 10;
-
- private List<HdHomeRunDiscoverSocket> mSockets = new ArrayList<>();
-
- /** Creates a discover object. If cannot add a default socket, return {@code null}. */
- static HdHomeRunDiscover create() {
- HdHomeRunDiscover hdHomeRunDiscover = new HdHomeRunDiscover();
- // Create a routable socket (always first entry).
- if (!hdHomeRunDiscover.addSocket(0, 0)) {
- return null;
- }
- return hdHomeRunDiscover;
- }
-
- /** Closes and releases all sockets required by this discover object. */
- void close() {
- for (HdHomeRunDiscoverSocket discoverSocket : mSockets) {
- discoverSocket.close();
- }
- }
-
- /** Finds HDHomeRun devices. */
- @NonNull
- List<HdHomeRunDiscoverDevice> findDevices(
- int targetIp, int deviceType, int deviceId, int maxCount) {
- List<HdHomeRunDiscoverDevice> resultList = new ArrayList<>();
- resetLocalIpSockets();
- for (int retry = 0;
- retry < HDHOMERUN_DISCOVER_RETRY_LIMIT && resultList.isEmpty();
- retry++) {
- int localIpSent = send(targetIp, deviceType, deviceId);
- if (localIpSent == 0) {
- if (DEBUG) {
- Log.d(TAG, "Cannot send to target ip: " + HdHomeRunUtils.getIpString(targetIp));
- }
- continue;
- }
- long timeout = System.currentTimeMillis() + HDHOMERUN_DISCOVER_TIMEOUT_MS * localIpSent;
- while (System.currentTimeMillis() < timeout) {
- HdHomeRunDiscoverDevice result = new HdHomeRunDiscoverDevice();
- if (!receive(result)) {
- continue;
- }
- // Filter.
- if (deviceType != HdHomeRunUtils.HDHOMERUN_DEVICE_TYPE_WILDCARD
- && deviceType != result.mDeviceType) {
- continue;
- }
- if (deviceId != HdHomeRunUtils.HDHOMERUN_DEVICE_ID_WILDCARD
- && deviceId != result.mDeviceId) {
- continue;
- }
- if (isObsoleteDevice(deviceId)) {
- continue;
- }
- // Ensure not already in list.
- if (resultList.contains(result)) {
- continue;
- }
- // Add to list.
- resultList.add(result);
- if (resultList.size() >= maxCount) {
- break;
- }
- }
- }
- return resultList;
- }
-
- private boolean addSocket(int localIp, int subnetMask) {
- for (int i = 1; i < mSockets.size(); i++) {
- HdHomeRunDiscoverSocket discoverSocket = mSockets.get(i);
- if ((discoverSocket.mLocalIp == localIp)
- && (discoverSocket.mSubnetMask == subnetMask)) {
- discoverSocket.mDetected = true;
- return true;
- }
- }
- if (mSockets.size() >= HDHOMERUN_DISCOVER_MAX_SOCK_COUNT) {
- return false;
- }
- DatagramSocket socket;
- try {
- socket = new DatagramSocket(0, HdHomeRunUtils.intToAddress(localIp));
- socket.setBroadcast(true);
- } catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Cannot create socket: " + HdHomeRunUtils.getIpString(localIp));
- return false;
- }
- // Write socket entry.
- mSockets.add(new HdHomeRunDiscoverSocket(socket, true, localIp, subnetMask));
- return true;
- }
-
- private void resetLocalIpSockets() {
- for (int i = 1; i < mSockets.size(); i++) {
- mSockets.get(i).mDetected = false;
- mSockets.get(i).mDiscoverPacketSent = false;
- }
- List<LocalIpInfo> ipInfoList = getLocalIpInfo(HDHOMERUN_DISCOVER_MAX_SOCK_COUNT);
- for (LocalIpInfo ipInfo : ipInfoList) {
- if (DEBUG) {
- Log.d(
- TAG,
- "Add local IP: "
- + HdHomeRunUtils.getIpString(ipInfo.mIpAddress)
- + ", "
- + HdHomeRunUtils.getIpString(ipInfo.mSubnetMask));
- }
- addSocket(ipInfo.mIpAddress, ipInfo.mSubnetMask);
- }
- Iterator<HdHomeRunDiscoverSocket> iterator = mSockets.iterator();
- while (iterator.hasNext()) {
- HdHomeRunDiscoverSocket discoverSocket = iterator.next();
- if (!discoverSocket.mDetected) {
- discoverSocket.close();
- iterator.remove();
- }
- }
- }
-
- private List<LocalIpInfo> getLocalIpInfo(int maxCount) {
- Enumeration<NetworkInterface> interfaces;
- try {
- interfaces = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e) {
- return Collections.emptyList();
- }
- List<LocalIpInfo> result = new ArrayList<>();
- while (interfaces.hasMoreElements()) {
- NetworkInterface networkInterface = interfaces.nextElement();
- for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
- InetAddress inetAddress = interfaceAddress.getAddress();
- if (!inetAddress.isAnyLocalAddress()
- && !inetAddress.isLinkLocalAddress()
- && !inetAddress.isLoopbackAddress()
- && !inetAddress.isMulticastAddress()) {
- LocalIpInfo localIpInfo = new LocalIpInfo();
- localIpInfo.mIpAddress = HdHomeRunUtils.addressToInt(inetAddress.getAddress());
- localIpInfo.mSubnetMask =
- (0x7fffffff >> (31 - interfaceAddress.getNetworkPrefixLength()));
- result.add(localIpInfo);
- if (result.size() >= maxCount) {
- return result;
- }
- }
- }
- }
- return result;
- }
-
- private int send(int targetIp, int deviceType, int deviceId) {
- return targetIp == 0
- ? sendWildcardIp(deviceType, deviceId)
- : sendTargetIp(targetIp, deviceType, deviceId);
- }
-
- private int sendWildcardIp(int deviceType, int deviceId) {
- int localIpSent = 0;
-
- // Send subnet broadcast using each local ip socket.
- // This will work with multiple separate 169.254.x.x interfaces.
- for (int i = 1; i < mSockets.size(); i++) {
- HdHomeRunDiscoverSocket discoverSocket = mSockets.get(i);
- int targetIp = discoverSocket.mLocalIp | ~discoverSocket.mSubnetMask;
- if (DEBUG) Log.d(TAG, "Send: " + HdHomeRunUtils.getIpString(targetIp));
- localIpSent += discoverSocket.send(targetIp, deviceType, deviceId) ? 1 : 0;
- }
- // If no local ip sockets then fall back to sending a global broadcast letting
- // the OS choose the interface.
- if (localIpSent == 0) {
- if (DEBUG) Log.d(TAG, "Send: " + HdHomeRunUtils.getIpString(0xFFFFFFFF));
- localIpSent = mSockets.get(0).send(0xFFFFFFFF, deviceType, deviceId) ? 1 : 0;
- }
- return localIpSent;
- }
-
- private int sendTargetIp(int targetIp, int deviceType, int deviceId) {
- int localIpSent = 0;
-
- // Send targeted packet from any local ip that is in the same subnet.
- // This will work with multiple separate 169.254.x.x interfaces.
- for (int i = 1; i < mSockets.size(); i++) {
- HdHomeRunDiscoverSocket discoverSocket = mSockets.get(i);
- if (discoverSocket.mSubnetMask == 0) {
- continue;
- }
- if ((targetIp & discoverSocket.mSubnetMask)
- != (discoverSocket.mLocalIp & discoverSocket.mSubnetMask)) {
- continue;
- }
- localIpSent += discoverSocket.send(targetIp, deviceType, deviceId) ? 1 : 0;
- }
- // If target IP does not match a local subnet then fall back to letting the OS choose
- // the gateway interface.
- if (localIpSent == 0) {
- localIpSent = mSockets.get(0).send(targetIp, deviceType, deviceId) ? 1 : 0;
- }
- return localIpSent;
- }
-
- private boolean receive(HdHomeRunDiscoverDevice result) {
- for (HdHomeRunDiscoverSocket discoverSocket : mSockets) {
- if (discoverSocket.mDiscoverPacketSent && discoverSocket.receive(result)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean isObsoleteDevice(int deviceId) {
- switch (deviceId >> 20) {
- case 0x100: /* TECH-US/TECH3-US */
- return (deviceId < 0x10040000);
- case 0x120: /* TECH3-EU */
- return (deviceId < 0x12030000);
- case 0x101: /* HDHR-US */
- case 0x102: /* HDHR-T1-US */
- case 0x103: /* HDHR3-US */
- case 0x111: /* HDHR3-DT */
- case 0x121: /* HDHR-EU */
- case 0x122: /* HDHR3-EU */
- return true;
- default:
- return false;
- }
- }
-
- static class HdHomeRunDiscoverDevice {
- int mIpAddress;
- int mDeviceType;
- int mDeviceId;
- int mTunerCount;
- String mBaseUrl;
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof HdHomeRunDiscoverDevice) {
- HdHomeRunDiscoverDevice o = (HdHomeRunDiscoverDevice) other;
- return mIpAddress == o.mIpAddress
- && mDeviceType == o.mDeviceType
- && mDeviceId == o.mDeviceId;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- int result = mIpAddress;
- result = 31 * result + mDeviceType;
- result = 31 * result + mDeviceId;
- return result;
- }
- }
-
- private static class HdHomeRunDiscoverSocket {
- DatagramSocket mSocket;
- boolean mDetected;
- boolean mDiscoverPacketSent;
- int mLocalIp;
- int mSubnetMask;
-
- private HdHomeRunDiscoverSocket(
- DatagramSocket socket, boolean detected, int localIp, int subnetMask) {
- mSocket = socket;
- mDetected = detected;
- mLocalIp = localIp;
- mSubnetMask = subnetMask;
- }
-
- private boolean send(int targetIp, int deviceType, int deviceId) {
- byte[] data = new byte[12];
- ByteBuffer buffer = ByteBuffer.wrap(data);
- buffer.put(HdHomeRunUtils.HDHOMERUN_TAG_DEVICE_TYPE);
- buffer.put((byte) 4);
- buffer.putInt(deviceType);
- buffer.put(HdHomeRunUtils.HDHOMERUN_TAG_DEVICE_ID);
- buffer.put((byte) 4);
- buffer.putInt(deviceId);
- data = HdHomeRunUtils.sealFrame(data, HdHomeRunUtils.HDHOMERUN_TYPE_DISCOVER_REQUEST);
- try {
- DatagramPacket packet =
- new DatagramPacket(
- data,
- data.length,
- HdHomeRunUtils.intToAddress(targetIp),
- HdHomeRunUtils.HDHOMERUN_DISCOVER_UDP_PORT);
- mSocket.send(packet);
- if (DEBUG) {
- Log.d(TAG, "Discover packet sent to: " + HdHomeRunUtils.getIpString(targetIp));
- }
- mDiscoverPacketSent = true;
- } catch (IOException e) {
- if (DEBUG) {
- Log.d(
- TAG,
- "Cannot send discover packet to socket("
- + HdHomeRunUtils.getIpString(mLocalIp)
- + ")");
- }
- mDiscoverPacketSent = false;
- }
- return mDiscoverPacketSent;
- }
-
- private boolean receive(HdHomeRunDiscoverDevice result) {
- DatagramPacket packet = new DatagramPacket(new byte[3074], 3074);
- try {
- mSocket.setSoTimeout(HDHOMERUN_DISCOVER_RECEIVE_WAITE_TIME_MS);
- mSocket.receive(packet);
- if (DEBUG) Log.d(TAG, "Received packet, size: " + packet.getLength());
- } catch (IOException e) {
- if (DEBUG) {
- Log.d(
- TAG,
- "Cannot receive from socket("
- + HdHomeRunUtils.getIpString(mLocalIp)
- + ")");
- }
- return false;
- }
-
- Pair<Short, byte[]> data =
- HdHomeRunUtils.openFrame(packet.getData(), packet.getLength());
- if (data == null
- || data.first == null
- || data.first != HdHomeRunUtils.HDHOMERUN_TYPE_DISCOVER_REPLY) {
- if (DEBUG) Log.d(TAG, "Ill-formed packet: " + Arrays.toString(packet.getData()));
- return false;
- }
- result.mIpAddress = HdHomeRunUtils.addressToInt(packet.getAddress().getAddress());
- if (DEBUG) {
- Log.d(TAG, "Get Device IP: " + HdHomeRunUtils.getIpString(result.mIpAddress));
- }
- ByteBuffer buffer = ByteBuffer.wrap(data.second);
- while (true) {
- Pair<Byte, byte[]> tagAndValue = HdHomeRunUtils.readTaggedValue(buffer);
- if (tagAndValue == null) {
- break;
- }
- switch (tagAndValue.first) {
- case HdHomeRunUtils.HDHOMERUN_TAG_DEVICE_TYPE:
- if (tagAndValue.second.length != 4) {
- break;
- }
- result.mDeviceType = ByteBuffer.wrap(tagAndValue.second).getInt();
- if (DEBUG) Log.d(TAG, "Get Device Type: " + result.mDeviceType);
- break;
- case HdHomeRunUtils.HDHOMERUN_TAG_DEVICE_ID:
- if (tagAndValue.second.length != 4) {
- break;
- }
- result.mDeviceId = ByteBuffer.wrap(tagAndValue.second).getInt();
- if (DEBUG) Log.d(TAG, "Get Device ID: " + result.mDeviceId);
- break;
- case HdHomeRunUtils.HDHOMERUN_TAG_TUNER_COUNT:
- if (tagAndValue.second.length != 1) {
- break;
- }
- result.mTunerCount = tagAndValue.second[0];
- if (DEBUG) Log.d(TAG, "Get Tuner Count: " + result.mTunerCount);
- break;
- case HdHomeRunUtils.HDHOMERUN_TAG_BASE_URL:
- result.mBaseUrl = new String(tagAndValue.second);
- if (DEBUG) Log.d(TAG, "Get Base URL: " + result.mBaseUrl);
- break;
- default:
- break;
- }
- }
- // Fixup for old firmware.
- if (result.mTunerCount == 0) {
- switch (result.mDeviceId >> 20) {
- case 0x102:
- result.mTunerCount = 1;
- break;
- case 0x100:
- case 0x101:
- case 0x121:
- result.mTunerCount = 2;
- break;
- default:
- break;
- }
- }
- return true;
- }
-
- private void close() {
- if (mSocket != null) {
- mSocket.close();
- }
- }
- }
-
- private static class LocalIpInfo {
- int mIpAddress;
- int mSubnetMask;
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunInterface.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunInterface.java
deleted file mode 100644
index 2928aba7..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunInterface.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.WorkerThread;
-import android.util.Log;
-import com.android.tv.tuner.hdhomerun.HdHomeRunDiscover.HdHomeRunDiscoverDevice;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** An interface class provides methods to access physical HDHomeRun devices. */
-@WorkerThread
-public class HdHomeRunInterface {
- private static final String TAG = "HdHomeRunInterface";
- private static final boolean DEBUG = false;
-
- private static final int FETCH_DEVICE_NAME_TRY_NUM = 2;
- private static final int MAX_DEVICES = 1;
- private static final boolean DISABLE_CABLE = false;
-
- /**
- * Scans for HDHomeRun devices on the network.
- *
- * @param deviceId The target device ID we want to find, scans for all available devices if
- * {@code null} or the given ID cannot be found.
- * @return A set of HDHomeRun devices
- */
- @NonNull
- public static Set<HdHomeRunDevice> scanDevices(Integer deviceId) {
- List<HdHomeRunDiscoverDevice> discoveredDevices = null;
- if (deviceId != null) {
- discoveredDevices =
- HdHomeRunUtils.findHdHomeRunDevices(
- 0, HdHomeRunUtils.HDHOMERUN_DEVICE_TYPE_TUNER, deviceId, 1);
- if (discoveredDevices.isEmpty()) {
- Log.i(TAG, "Can't find device with ID: " + deviceId);
- }
- }
- if (discoveredDevices == null || discoveredDevices.isEmpty()) {
- discoveredDevices =
- HdHomeRunUtils.findHdHomeRunDevices(
- 0,
- HdHomeRunUtils.HDHOMERUN_DEVICE_TYPE_TUNER,
- HdHomeRunUtils.HDHOMERUN_DEVICE_ID_WILDCARD,
- MAX_DEVICES);
- if (DEBUG) Log.d(TAG, "Found " + discoveredDevices.size() + " devices");
- }
- Set<HdHomeRunDevice> result = new HashSet<>();
- for (HdHomeRunDiscoverDevice discoveredDevice : discoveredDevices) {
- String model =
- fetchDeviceModel(discoveredDevice.mDeviceId, discoveredDevice.mIpAddress);
- if (model == null) {
- Log.e(TAG, "Fetching device model failed: " + discoveredDevice.mDeviceId);
- continue;
- } else if (DEBUG) {
- Log.d(TAG, "Fetch Device Model: " + model);
- }
- if (DISABLE_CABLE) {
- if (model != null && model.contains("cablecard")) {
- // filter out CableCARD devices
- continue;
- }
- }
- for (int i = 0; i < discoveredDevice.mTunerCount; i++) {
- result.add(
- new HdHomeRunDevice(
- discoveredDevice.mIpAddress,
- discoveredDevice.mDeviceType,
- discoveredDevice.mDeviceId,
- i,
- model));
- }
- }
- return result;
- }
-
- /**
- * Returns {@code true} if the given device IP, ID and tuner index is available for use.
- *
- * @param deviceId The target device ID, 0 denotes a wildcard match.
- * @param deviceIp The target device IP.
- * @param tunerIndex The target tuner index of the target device. This parameter is only
- * meaningful when the target device has multiple tuners.
- */
- public static boolean isDeviceAvailable(int deviceId, int deviceIp, int tunerIndex) {
- // TODO: check the lock state for the given tuner.
- if ((deviceId == 0) && (deviceIp == 0)) {
- return false;
- }
- if (HdHomeRunUtils.isIpMulticast(deviceIp)) {
- return false;
- }
- if ((deviceId == 0) || (deviceId == HdHomeRunUtils.HDHOMERUN_DEVICE_ID_WILDCARD)) {
- try (HdHomeRunControlSocket controlSock =
- new HdHomeRunControlSocket(deviceId, deviceIp)) {
- deviceId = controlSock.getDeviceId();
- }
- }
- return deviceId != 0;
- }
-
- @Nullable
- private static String fetchDeviceModel(int deviceId, int deviceIp) {
- for (int i = 0; i < FETCH_DEVICE_NAME_TRY_NUM; i++) {
- try (HdHomeRunControlSocket controlSock =
- new HdHomeRunControlSocket(deviceId, deviceIp)) {
- String model = controlSock.get("/sys/model");
- if (model != null) {
- return model;
- }
- }
- }
- return null;
- }
-
- private HdHomeRunInterface() {}
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHal.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHal.java
deleted file mode 100644
index 81682991..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHal.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.compat.TvInputConstantCompat;
-import com.android.tv.tuner.api.Tuner;
-import com.android.tv.tuner.data.TunerChannel;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-
-/** Tuner implementation for HdHomeRun */
-public class HdHomeRunTunerHal implements Tuner {
- private static final String TAG = "HdHomeRunTunerHal";
- private static final boolean DEBUG = false;
-
- private static final String CABLECARD_MODEL = "cablecard";
- private static final String ATSC_MODEL = "atsc";
- private static final String DVBC_MODEL = "dvbc";
- private static final String DVBT_MODEL = "dvbt";
-
- private final HdHomeRunTunerManager mTunerManager;
- private HdHomeRunDevice mDevice;
- private BufferedInputStream mInputStream;
- private HttpURLConnection mConnection;
- private String mHttpConnectionAddress;
- private final Context mContext;
-
- @DeliverySystemType private int mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
-
- public static final char VCHANNEL_SEPARATOR = '.';
- public static final int CONNECTION_TIMEOUT_MS_FOR_URLCONNECTION = 3000; // 3 sec
- public static final int READ_TIMEOUT_MS_FOR_URLCONNECTION = 10000; // 10 sec
-
- public HdHomeRunTunerHal(Context context) {
- mTunerManager = HdHomeRunTunerManager.getInstance();
- mContext = context;
- }
-
- @Override
- public boolean openFirstAvailable() {
- SoftPreconditions.checkState(mDevice == null);
- try {
- mDevice = mTunerManager.acquireDevice(mContext);
- if (mDevice != null) {
- if (mDeliverySystemType == DELIVERY_SYSTEM_UNDEFINED) {
- mDeliverySystemType = nativeGetDeliverySystemType(getDeviceId());
- }
- }
- return mDevice != null;
- } catch (Exception e) {
- Log.w(TAG, "Failed to open first available device", e);
- return false;
- }
- }
-
- @Override
- public boolean isDeviceOpen() {
- return mDevice != null;
- }
-
- @Override
- public boolean isReusable() {
- return false;
- }
-
- @Override
- public long getDeviceId() {
- return mDevice == null ? 0 : mDevice.getDeviceId();
- }
-
- @Override
- public void close() throws Exception {
- closeInputStreamAndDisconnect();
- if (mDevice != null) {
- mTunerManager.releaseDevice(mDevice);
- mDevice = null;
- }
- }
-
- @Override
- public synchronized boolean tune(
- int frequency, @ModulationType String modulation, String channelNumber) {
- if (DEBUG) {
- Log.d(
- TAG,
- "tune(frequency="
- + frequency
- + ", modulation="
- + modulation
- + ", channelNumber="
- + channelNumber
- + ")");
- }
- closeInputStreamAndDisconnect();
- if (TextUtils.isEmpty(channelNumber)) {
- return false;
- }
- channelNumber =
- channelNumber.replace(TunerChannel.CHANNEL_NUMBER_SEPARATOR, VCHANNEL_SEPARATOR);
- mHttpConnectionAddress = "http://" + getIpAddress() + ":5004/auto/v" + channelNumber;
- return connectAndOpenInputStream();
- }
-
- private boolean connectAndOpenInputStream() {
- URL url;
- try {
- url = new URL(mHttpConnectionAddress);
- } catch (MalformedURLException e) {
- Log.e(TAG, "Invalid address: " + mHttpConnectionAddress, e);
- return false;
- }
- URLConnection connection;
- try {
- connection = url.openConnection();
- connection.setConnectTimeout(CONNECTION_TIMEOUT_MS_FOR_URLCONNECTION);
- connection.setReadTimeout(READ_TIMEOUT_MS_FOR_URLCONNECTION);
- if (connection instanceof HttpURLConnection) {
- mConnection = (HttpURLConnection) connection;
- }
- } catch (IOException e) {
- Log.e(TAG, "Connection failed: " + mHttpConnectionAddress, e);
- return false;
- }
- try {
- mInputStream = new BufferedInputStream(connection.getInputStream());
- } catch (IOException e) {
- closeInputStreamAndDisconnect();
- Log.e(TAG, "Failed to get input stream from " + mHttpConnectionAddress, e);
- return false;
- }
- if (DEBUG) Log.d(TAG, "tuning to " + mHttpConnectionAddress);
- return true;
- }
-
- @Override
- public synchronized boolean addPidFilter(int pid, @FilterType int filterType) {
- // no-op
- return true;
- }
-
- @Override
- public synchronized void stopTune() {
- closeInputStreamAndDisconnect();
- }
-
- @Override
- public synchronized int readTsStream(byte[] javaBuffer, int javaBufferSize) {
- if (mInputStream != null) {
- try {
- // Note: this call sometimes take more than 500ms, because the data is
- // streamed through network unlike connected tuner devices.
- return mInputStream.read(javaBuffer, 0, javaBufferSize);
- } catch (IOException e) {
- Log.e(TAG, "Failed to read stream", e);
- closeInputStreamAndDisconnect();
- }
- }
- if (connectAndOpenInputStream()) {
- Log.w(TAG, "Tuned by http connection again");
- } else {
- Log.e(TAG, "Tuned by http connection again failed");
- }
- return 0;
- }
-
- @Override
- public void setHasPendingTune(boolean hasPendingTune) {
- // no-op
- }
-
- protected int nativeGetDeliverySystemType(long deviceId) {
- String deviceModel = mDevice.getDeviceModel();
- if (SoftPreconditions.checkState(!TextUtils.isEmpty(deviceModel))) {
- if (deviceModel.contains(CABLECARD_MODEL) || deviceModel.contains(ATSC_MODEL)) {
- return DELIVERY_SYSTEM_ATSC;
- } else if (deviceModel.contains(DVBC_MODEL)) {
- return DELIVERY_SYSTEM_DVBC;
- } else if (deviceModel.contains(DVBT_MODEL)) {
- return DELIVERY_SYSTEM_DVBT;
- }
- }
- return DELIVERY_SYSTEM_UNDEFINED;
- }
-
- private void closeInputStreamAndDisconnect() {
- if (mInputStream != null) {
- try {
- mInputStream.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close input stream", e);
- }
- mInputStream = null;
- }
- if (mConnection != null) {
- mConnection.disconnect();
- mConnection = null;
- }
- }
-
- /** Gets the number of tuners in a given HDHomeRun devices. */
- public static int getNumberOfDevices() {
- return HdHomeRunTunerManager.getInstance().getTunerCount();
- }
-
- /** Returns the IP address. */
- public String getIpAddress() {
- return HdHomeRunUtils.getIpString(mDevice.getIpAddress());
- }
-
- /**
- * Marks the device associated to this instance as a scanned device. Scanned device has higher
- * priority among multiple HDHomeRun devices.
- */
- public void markAsScannedDevice(Context context) {
- HdHomeRunTunerManager.markAsScannedDevice(context, mDevice);
- }
-
- @Override
- @DeliverySystemType
- public int getDeliverySystemType() {
- return Tuner.DELIVERY_SYSTEM_UNDEFINED;
- }
-
- @Override
- public int getSignalStrength() {
- return TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED;
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHalFactory.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHalFactory.java
deleted file mode 100644
index 6f6b1864..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerHalFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.content.Context;
-import android.support.annotation.WorkerThread;
-import android.util.Pair;
-
-import com.android.tv.tuner.api.Tuner;
-import com.android.tv.tuner.api.TunerFactory;
-
-/** TunerHal factory that creates all built in tuner types. */
-public final class HdHomeRunTunerHalFactory implements TunerFactory {
- public static final TunerFactory INSTANCE = new HdHomeRunTunerHalFactory();
-
- private HdHomeRunTunerHalFactory() {}
- /**
- * Creates a TunerHal instance.
- *
- * @param context context for creating the TunerHal instance
- * @return the TunerHal instance
- */
- @Override
- @WorkerThread
- public synchronized Tuner createInstance(Context context) {
- Tuner tunerHal = null;
- if (tunerHal == null) {
- tunerHal = new HdHomeRunTunerHal(context);
- }
- return tunerHal.openFirstAvailable() ? tunerHal : null;
- }
-
- /**
- * Returns if tuner input service would use built-in tuners instead of USB tuners or network
- * tuners.
- */
- @Override
- public boolean useBuiltInTuner(Context context) {
- return false;
- }
-
- /** Gets the number of tuner devices currently present. */
- @Override
- @WorkerThread
- public Pair<Integer, Integer> getTunerTypeAndCount(Context context) {
- return Pair.create(Tuner.TUNER_TYPE_NETWORK, HdHomeRunTunerHal.getNumberOfDevices());
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerManager.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerManager.java
deleted file mode 100644
index 9e3ea595..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunTunerManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.support.annotation.WorkerThread;
-import android.util.Log;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A class to manage tuner resources of HDHomeRun devices. It handles tuner resource acquisition and
- * release.
- */
-class HdHomeRunTunerManager {
- private static final String TAG = "HdHomeRunTunerManager";
- private static final boolean DEBUG = false;
-
- private static final String PREF_KEY_SCANNED_DEVICE_ID = "scanned_device_id";
-
- private static HdHomeRunTunerManager sInstance;
-
- private final Set<HdHomeRunDevice> mHdHomeRunDevices = new HashSet<>();
- private final Set<HdHomeRunDevice> mUsedDevices = new HashSet<>();
-
- private HdHomeRunTunerManager() {}
-
- /** Returns the instance of this manager. */
- public static synchronized HdHomeRunTunerManager getInstance() {
- if (sInstance == null) {
- sInstance = new HdHomeRunTunerManager();
- }
- return sInstance;
- }
-
- /** Returns number of tuners. */
- @WorkerThread
- synchronized int getTunerCount() {
- updateDevicesLocked(null);
- if (DEBUG) Log.d(TAG, "getTunerCount: " + mHdHomeRunDevices.size());
- return mHdHomeRunDevices.size();
- }
-
- /** Creates an HDHomeRun device. If there is no available one, returns {@code null}. */
- @WorkerThread
- synchronized HdHomeRunDevice acquireDevice(Context context) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- int scannedDeviceId = sp.getInt(PREF_KEY_SCANNED_DEVICE_ID, 0);
- updateDevicesLocked(scannedDeviceId == 0 ? null : scannedDeviceId);
- if (DEBUG) Log.d(TAG, "createDevice: device count = " + mHdHomeRunDevices.size());
- HdHomeRunDevice availableDevice = null;
- // Use the device used for scanning first since other devices might have different line-up.
- if (scannedDeviceId != 0) {
- for (HdHomeRunDevice device : mHdHomeRunDevices) {
- if (!mUsedDevices.contains(device) && scannedDeviceId == device.getDeviceId()) {
- if (!HdHomeRunInterface.isDeviceAvailable(
- device.getDeviceId(), device.getIpAddress(), device.getTunerIndex())) {
- if (DEBUG) Log.d(TAG, "Device not available: " + device);
- continue;
- }
- availableDevice = device;
- break;
- }
- }
- }
- if (availableDevice == null) {
- for (HdHomeRunDevice device : mHdHomeRunDevices) {
- if (!mUsedDevices.contains(device)) {
- if (!HdHomeRunInterface.isDeviceAvailable(
- device.getDeviceId(), device.getIpAddress(), device.getTunerIndex())) {
- if (DEBUG) Log.d(TAG, "Device not available: " + device);
- continue;
- }
- availableDevice = device;
- break;
- }
- }
- }
- if (availableDevice != null) {
- if (DEBUG) Log.d(TAG, "created device " + availableDevice);
- mUsedDevices.add(availableDevice);
- return availableDevice;
- }
- return null;
- }
-
- /** Releases a created device by {@link #acquireDevice(Context)}. */
- synchronized void releaseDevice(HdHomeRunDevice device) {
- if (DEBUG) Log.d(TAG, "releaseDevice: " + device);
- mUsedDevices.remove(device);
- }
-
- /**
- * Marks the device associated to this instance as a scanned device. Scanned device has higher
- * priority among multiple HDHomeRun devices.
- */
- static void markAsScannedDevice(Context context, HdHomeRunDevice device) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- sp.edit().putInt(PREF_KEY_SCANNED_DEVICE_ID, device.getDeviceId()).apply();
- }
-
- private void updateDevicesLocked(Integer deviceId) {
- mHdHomeRunDevices.clear();
- mHdHomeRunDevices.addAll(HdHomeRunInterface.scanDevices(deviceId));
- }
-}
diff --git a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunUtils.java b/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunUtils.java
deleted file mode 100644
index 733fc96f..00000000
--- a/tuner/src/com/android/tv/tuner/hdhomerun/HdHomeRunUtils.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.hdhomerun;
-
-import android.support.annotation.NonNull;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.tv.tuner.hdhomerun.HdHomeRunDiscover.HdHomeRunDiscoverDevice;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.zip.CRC32;
-
-class HdHomeRunUtils {
- private static final String TAG = "HdHomeRunUtils";
- private static final boolean DEBUG = false;
-
- static final int HDHOMERUN_DEVICE_TYPE_WILDCARD = 0xFFFFFFFF;
- static final int HDHOMERUN_DEVICE_TYPE_TUNER = 0x00000001;
- static final int HDHOMERUN_DEVICE_ID_WILDCARD = 0xFFFFFFFF;
-
- static final int HDHOMERUN_DISCOVER_UDP_PORT = 65001;
- static final int HDHOMERUN_CONTROL_TCP_PORT = 65001;
-
- static final short HDHOMERUN_TYPE_INVALID = -1;
- static final short HDHOMERUN_TYPE_DISCOVER_REQUEST = 0x0002;
- static final short HDHOMERUN_TYPE_DISCOVER_REPLY = 0x0003;
- static final short HDHOMERUN_TYPE_GETSET_REQUEST = 0x0004;
- static final short HDHOMERUN_TYPE_GETSET_REPLY = 0x0005;
-
- static final byte HDHOMERUN_TAG_DEVICE_TYPE = 0x01;
- static final byte HDHOMERUN_TAG_DEVICE_ID = 0x02;
- static final byte HDHOMERUN_TAG_GETSET_NAME = 0x03;
- static final int HDHOMERUN_TAG_GETSET_VALUE = 0x04;
- static final int HDHOMERUN_TAG_ERROR_MESSAGE = 0x05;
- static final int HDHOMERUN_TAG_TUNER_COUNT = 0x10;
- static final int HDHOMERUN_TAG_BASE_URL = 0x2A;
-
- static final int HDHOMERUN_CONTROL_CONNECT_TIMEOUT_MS = 2500;
- static final int HDHOMERUN_CONTROL_SEND_TIMEOUT_MS = 2500;
- static final int HDHOMERUN_CONTROL_RECEIVE_TIMEOUT_MS = 2500;
-
- /**
- * Finds HDHomeRun devices with given IP, type, and ID.
- *
- * @param targetIp {@code 0} to find target devices with broadcasting.
- * @param deviceType The type of target devices.
- * @param deviceId The ID of target devices.
- * @param maxCount Maximum number of devices should be returned.
- */
- @NonNull
- static List<HdHomeRunDiscoverDevice> findHdHomeRunDevices(
- int targetIp, int deviceType, int deviceId, int maxCount) {
- if (isIpMulticast(targetIp)) {
- if (DEBUG) Log.d(TAG, "Target IP cannot be multicast IP.");
- return Collections.emptyList();
- }
- try {
- HdHomeRunDiscover ds = HdHomeRunDiscover.create();
- if (ds == null) {
- if (DEBUG) Log.d(TAG, "Cannot create discover object.");
- return Collections.emptyList();
- }
- List<HdHomeRunDiscoverDevice> result =
- ds.findDevices(targetIp, deviceType, deviceId, maxCount);
- ds.close();
- return result;
- } catch (Exception e) {
- Log.w(TAG, "Failed to find HdHomeRun Devices", e);
- return Collections.emptyList();
- }
- }
-
- /** Returns {@code true} if the given IP is a multi-cast IP. */
- static boolean isIpMulticast(long ip) {
- return (ip >= 0xE0000000) && (ip < 0xF0000000);
- }
-
- /** Translates a {@code byte[]} address to its integer representation. */
- static int addressToInt(byte[] address) {
- return ByteBuffer.wrap(address).order(ByteOrder.LITTLE_ENDIAN).getInt();
- }
-
- /** Translates an {@code int} address to a corresponding {@link InetAddress}. */
- static InetAddress intToAddress(int address) throws UnknownHostException {
- return InetAddress.getByAddress(
- ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(address).array());
- }
-
- /** Gets {@link String} representation of an {@code int} address. */
- static String getIpString(int ip) {
- return String.format(
- "%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
- }
-
- /**
- * Opens the packet returned from HDHomeRun devices to acquire the real content and verify it.
- */
- static Pair<Short, byte[]> openFrame(byte[] data, int length) {
- if (length < 4) {
- return null;
- }
- ByteBuffer buffer = ByteBuffer.wrap(data);
- short resultType = buffer.getShort();
- int dataLength = buffer.getShort() & 0xffff;
-
- if (dataLength + 8 > length) {
- // Not finished yet.
- return null;
- }
- byte[] result = new byte[dataLength];
- buffer.get(result);
- byte[] calculatedCrc = getCrcFromBytes(Arrays.copyOfRange(data, 0, dataLength + 4));
- byte[] packetCrc = new byte[4];
- buffer.get(packetCrc);
-
- if (!Arrays.equals(calculatedCrc, packetCrc)) {
- return Pair.create(HDHOMERUN_TYPE_INVALID, null);
- }
-
- return Pair.create(resultType, result);
- }
-
- /** Seals the contents in a packet to send to HDHomeRun devices. */
- static byte[] sealFrame(byte[] data, short frameType) {
- byte[] result = new byte[data.length + 8];
- ByteBuffer buffer = ByteBuffer.wrap(result);
- buffer.putShort(frameType);
- buffer.putShort((short) data.length);
- buffer.put(data);
- buffer.put(getCrcFromBytes(Arrays.copyOfRange(result, 0, data.length + 4)));
- return result;
- }
-
- /** Reads a (tag, value) pair from packets returned from HDHomeRun devices. */
- static Pair<Byte, byte[]> readTaggedValue(ByteBuffer buffer) {
- try {
- Byte tag = buffer.get();
- byte[] value = readVarLength(buffer);
- return Pair.create(tag, value);
- } catch (BufferUnderflowException e) {
- return null;
- }
- }
-
- private static byte[] readVarLength(ByteBuffer buffer) {
- short length;
- Byte lengthByte1 = buffer.get();
- if ((lengthByte1 & 0x80) != 0) {
- length = buffer.get();
- length = (short) ((length << 7) + (lengthByte1 & 0x7F));
- } else {
- length = lengthByte1;
- }
- byte[] result = new byte[length];
- buffer.get(result);
- return result;
- }
-
- private static byte[] getCrcFromBytes(byte[] data) {
- CRC32 crc32 = new CRC32();
- crc32.update(data);
- long crc = crc32.getValue();
- byte[] result = new byte[4];
- for (int offset = 0; offset < 4; offset++) {
- result[offset] = (byte) (crc & 0xFF);
- crc >>= 8;
- }
- return result;
- }
-
- private HdHomeRunUtils() {}
-}
diff --git a/tuner/src/com/android/tv/tuner/modules/TunerModule.java b/tuner/src/com/android/tv/tuner/modules/TunerModule.java
index ff86e09f..4843f383 100644
--- a/tuner/src/com/android/tv/tuner/modules/TunerModule.java
+++ b/tuner/src/com/android/tv/tuner/modules/TunerModule.java
@@ -15,86 +15,9 @@
*/
package com.android.tv.tuner.modules;
-import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractor;
-import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractorFactory;
-import com.android.tv.tuner.exoplayer.FileSampleExtractor;
-import com.android.tv.tuner.exoplayer.FileSampleExtractorFactory;
-import com.android.tv.tuner.exoplayer.MpegTsRendererBuilder;
-import com.android.tv.tuner.exoplayer.MpegTsRendererBuilderFactory;
-import com.android.tv.tuner.exoplayer.MpegTsSampleExtractor;
-import com.android.tv.tuner.exoplayer.MpegTsSampleExtractorFactory;
-import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer;
-import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBufferFactory;
-import com.android.tv.tuner.exoplayer.buffer.SampleChunkIoHelper;
-import com.android.tv.tuner.exoplayer.buffer.SampleChunkIoHelperFactory;
import com.android.tv.tuner.source.TunerSourceModule;
-import com.android.tv.tuner.tvinput.TunerRecordingSessionFactoryImpl;
-import com.android.tv.tuner.tvinput.TunerRecordingSessionWorker;
-import com.android.tv.tuner.tvinput.TunerRecordingSessionWorkerFactory;
-import com.android.tv.tuner.tvinput.TunerSessionExoV2Factory;
-import com.android.tv.tuner.tvinput.TunerSessionV1Factory;
-import com.android.tv.tuner.tvinput.TunerSessionWorker;
-import com.android.tv.tuner.tvinput.TunerSessionWorkerExoV2;
-import com.android.tv.tuner.tvinput.TunerSessionWorkerExoV2Factory;
-import com.android.tv.tuner.tvinput.TunerSessionWorkerFactory;
-import com.android.tv.tuner.tvinput.factory.TunerRecordingSessionFactory;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
-
-import dagger.Binds;
import dagger.Module;
-import dagger.Provides;
-
-import com.android.tv.common.flags.TunerFlags;
/** Dagger module for TV Tuners. */
@Module(includes = {TunerSingletonsModule.class, TunerSourceModule.class})
-public abstract class TunerModule {
-
- @Provides
- static TunerSessionFactory tunerSessionFactory(
- TunerFlags tunerFlags,
- TunerSessionV1Factory tunerSessionFactory,
- TunerSessionExoV2Factory tunerSessionExoV2Factory) {
- return tunerFlags.useExoplayerV2() ? tunerSessionExoV2Factory : tunerSessionFactory;
- }
-
- @Binds
- abstract TunerRecordingSessionWorker.Factory tunerRecordingSessionWorkerFactory(
- TunerRecordingSessionWorkerFactory tunerRecordingSessionWorkerFactory);
-
- @Binds
- abstract TunerSessionWorker.Factory tunerSessionWorkerFactory(
- TunerSessionWorkerFactory tunerSessionWorkerFactory);
-
- @Binds
- abstract TunerSessionWorkerExoV2.Factory tunerSessionWorkerExoV2Factory(
- TunerSessionWorkerExoV2Factory tunerSessionWorkerExoV2Factory);
-
- @Binds
- abstract TunerRecordingSessionFactory tunerRecordingSessionFactory(
- TunerRecordingSessionFactoryImpl impl);
-
- @Binds
- abstract MpegTsRendererBuilder.Factory mpegTsRendererBuilderFactory(
- MpegTsRendererBuilderFactory mpegTsRendererBuilderFactory);
-
- @Binds
- abstract MpegTsSampleExtractor.Factory mpegTsSampleExtractorFactory(
- MpegTsSampleExtractorFactory mpegTsSampleExtractorFactory);
-
- @Binds
- abstract FileSampleExtractor.Factory fileSampleExtractorFactory(
- FileSampleExtractorFactory fileSampleExtractorFactory);
-
- @Binds
- abstract RecordingSampleBuffer.Factory recordingSampleBufferFactory(
- RecordingSampleBufferFactory recordingSampleBufferFactory);
-
- @Binds
- abstract ExoPlayerSampleExtractor.Factory exoPlayerSampleExtractorFactory(
- ExoPlayerSampleExtractorFactory exoPlayerSampleExtractorFactory);
-
- @Binds
- abstract SampleChunkIoHelper.Factory sampleChunkIoHelperFactory(
- SampleChunkIoHelperFactory sampleChunkIoHelperFactory);
-}
+public class TunerModule {}
diff --git a/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java b/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java
index 05026907..44f689bf 100644
--- a/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java
+++ b/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java
@@ -75,14 +75,11 @@ public abstract class BaseTunerSetupActivity extends SetupActivity {
R.raw.ut_kr_cable_standard_center_frequencies_qam256,
R.raw.ut_kr_all,
R.raw.ut_kr_dev_cj_cable_center_frequencies_qam256,
+ R.raw.ut_euro_dvbt_all,
+ R.raw.ut_euro_dvbt_all,
R.raw.ut_euro_dvbt_all
- /* these two resource files are obsolete and removed, so comment them out
- R.raw.ut_euro_all,
- R.raw.ut_euro_all */
};
- protected final String mInputId;
-
protected ScanFragment mLastScanFragment;
protected Integer mTunerType;
protected boolean mNeedToShowPostalCodeFragment;
@@ -93,10 +90,6 @@ public abstract class BaseTunerSetupActivity extends SetupActivity {
private TunerHalCreator mTunerHalCreator;
- protected BaseTunerSetupActivity(String mInputId) {
- this.mInputId = mInputId;
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG) {
@@ -229,7 +222,6 @@ public abstract class BaseTunerSetupActivity extends SetupActivity {
args1.putInt(
ScanFragment.EXTRA_FOR_CHANNEL_SCAN_FILE, CHANNEL_MAP_SCAN_FILE[actionId]);
args1.putInt(KEY_TUNER_TYPE, mTunerType);
- args1.putString(ScanFragment.EXTRA_FOR_INPUT_ID, mInputId);
mLastScanFragment.setArguments(args1);
showFragment(mLastScanFragment, true);
return true;
diff --git a/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java b/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
index 2e782705..43c584ed 100644
--- a/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
+++ b/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
@@ -56,7 +56,6 @@ public final class ChannelScanFileParser {
}
scanChannelList.add(
ScanChannel.forTuner(
- tokens[0],
Integer.parseInt(tokens[1]),
tokens[2],
tokens.length == 4 ? Integer.parseInt(tokens[3]) : null));
diff --git a/tuner/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java b/tuner/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
index db297426..ebe4e41e 100644
--- a/tuner/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
@@ -18,12 +18,14 @@ package com.android.tv.tuner.setup;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.tuner.R;
import java.util.List;
+import java.util.TimeZone;
/** A fragment for connection type selection. */
public class ConnectionTypeFragment extends SetupMultiPaneFragment {
@@ -65,6 +67,7 @@ public class ConnectionTypeFragment extends SetupMultiPaneFragment {
/** The content fragment of {@link ConnectionTypeFragment}. */
public static class ContentFragment extends SetupGuidedStepFragment {
+
@NonNull
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
diff --git a/tuner/src/com/android/tv/tuner/setup/LineupFragment.java b/tuner/src/com/android/tv/tuner/setup/LineupFragment.java
index 224237d9..41f755df 100644
--- a/tuner/src/com/android/tv/tuner/setup/LineupFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/LineupFragment.java
@@ -20,8 +20,8 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
import android.view.View;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
diff --git a/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java b/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java
new file mode 100644
index 00000000..741edc78
--- /dev/null
+++ b/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.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.tuner.setup;
+
+import android.app.FragmentManager;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.view.KeyEvent;
+import com.android.tv.common.util.PostalCodeUtils;
+import dagger.android.ContributesAndroidInjector;
+
+/** An activity that serves tuner setup process. */
+public class LiveTvTunerSetupActivity extends BaseTunerSetupActivity {
+ private static final String TAG = "LiveTvTunerSetupActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // TODO(shubang): use LocationFragment
+ if (checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ // No need to check the request result.
+ requestPermissions(
+ new String[] {android.Manifest.permission.ACCESS_COARSE_LOCATION},
+ PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
+ }
+ }
+
+ @Override
+ protected void executeGetTunerTypeAndCountAsyncTask() {
+ new AsyncTask<Void, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Void... arg0) {
+ return mTunerFactory.getTunerTypeAndCount(LiveTvTunerSetupActivity.this).first;
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ if (!LiveTvTunerSetupActivity.this.isDestroyed()) {
+ mTunerType = result;
+ if (result == null) {
+ finish();
+ } else if (!mActivityStopped) {
+ showInitialFragment();
+ } else {
+ mPendingShowInitialFragment = true;
+ }
+ }
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ @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) {
+ String secondLastTag = manager.getBackStackEntryAt(count - 2).getName();
+ if (ScanFragment.class.getCanonicalName().equals(secondLastTag)) {
+ // Pops fragment including ScanFragment.
+ manager.popBackStack(
+ secondLastTag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+ return true;
+ }
+ } else if (ScanFragment.class.getCanonicalName().equals(lastTag)) {
+ mLastScanFragment.finishScan(true);
+ return true;
+ }
+ }
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(
+ int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ try {
+ // Updating postal code takes time, therefore we should update postal code
+ // right after the permission is granted, so that the subsequent operations,
+ // especially EPG fetcher, could get the newly updated postal code.
+ PostalCodeUtils.updatePostalCode(this);
+ } catch (Exception e) {
+ // Do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * Exports {@link LiveTvTunerSetupActivity} for Dagger codegen to create the appropriate
+ * injector.
+ */
+ @dagger.Module
+ public abstract static class Module {
+ @ContributesAndroidInjector
+ abstract LiveTvTunerSetupActivity contributeLiveTvTunerSetupActivityInjector();
+ }
+}
diff --git a/tuner/src/com/android/tv/tuner/setup/LocationFragment.java b/tuner/src/com/android/tv/tuner/setup/LocationFragment.java
index f950405f..1234ae20 100644
--- a/tuner/src/com/android/tv/tuner/setup/LocationFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/LocationFragment.java
@@ -23,14 +23,16 @@ import android.location.Address;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+
import com.android.tv.common.ui.setup.SetupActionHelper;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.common.util.LocationUtils;
import com.android.tv.tuner.R;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -38,7 +40,7 @@ import java.util.List;
/** A fragment shows the rationale of location permission */
public class LocationFragment extends SetupMultiPaneFragment {
private static final String TAG = "com.android.tv.tuner.setup.LocationFragment";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
public static final String ACTION_CATEGORY = "com.android.tv.tuner.setup.LocationFragment";
public static final String KEY_POSTAL_CODE = "key_postal_code";
@@ -77,7 +79,8 @@ public class LocationFragment extends SetupMultiPaneFragment {
() -> {
synchronized (mPostalCodeLock) {
if (DEBUG) {
- Log.d(TAG, "get location timeout. mPostalCode=" + mPostalCode);
+ Log.d(TAG,
+ "get location timeout. mPostalCode=" + mPostalCode);
}
if (mPostalCode == null) {
// timeout. setup activity will get null postal code
@@ -118,7 +121,8 @@ public class LocationFragment extends SetupMultiPaneFragment {
.id(ACTION_GETTING_LOCATION)
.title(getString(R.string.location_choices_getting_location))
.focusable(false)
- .build());
+ .build()
+ );
}
@Override
@@ -143,8 +147,8 @@ public class LocationFragment extends SetupMultiPaneFragment {
}
@Override
- public void onRequestPermissionsResult(
- int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
diff --git a/tuner/src/com/android/tv/tuner/setup/PostalCodeFragment.java b/tuner/src/com/android/tv/tuner/setup/PostalCodeFragment.java
index f9ea1675..52247972 100644
--- a/tuner/src/com/android/tv/tuner/setup/PostalCodeFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/PostalCodeFragment.java
@@ -18,9 +18,9 @@ package com.android.tv.tuner.setup;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.text.InputFilter;
import android.text.InputFilter.AllCaps;
import android.view.View;
diff --git a/tuner/src/com/android/tv/tuner/setup/ScanFragment.java b/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
index 87a79e35..7d59284c 100644
--- a/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
@@ -40,9 +40,11 @@ import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.tuner.R;
import com.android.tv.tuner.api.ScanChannel;
import com.android.tv.tuner.api.Tuner;
-import com.android.tv.tuner.data.Channel.TunerType;
import com.android.tv.tuner.data.PsipData;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
+
+
import com.android.tv.tuner.prefs.TunerPreferences;
import com.android.tv.tuner.source.FileTsStreamer;
import com.android.tv.tuner.source.TsDataSource;
@@ -72,13 +74,7 @@ public class ScanFragment extends SetupFragment {
public static final int ACTION_FINISH = 2;
public static final String EXTRA_FOR_CHANNEL_SCAN_FILE = "scan_file_choice";
- public static final String EXTRA_FOR_INPUT_ID = "input_id";
public static final String KEY_CHANNEL_NUMBERS = "channel_numbers";
-
- // Allows adding audio-only channels (CJ music channel) for which VCT is not present.
- private static final boolean ADD_CJ_MUSIC_CHANNELS = false;
- private static final int CJ_MUSIC_CHANNEL_FREQUENCY = 585000000;
-
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;
@@ -103,6 +99,8 @@ public class ScanFragment extends SetupFragment {
if (DEBUG) Log.d(TAG, "onCreateView");
View view = super.onCreateView(inflater, container, savedInstanceState);
mChannelNumbers = new ArrayList<>();
+ mChannelDataManager = new ChannelDataManager(getActivity().getApplicationContext());
+ mChannelDataManager.checkDataVersion(getActivity());
mAdapter = new ChannelAdapter();
mProgressBar = (ProgressBar) view.findViewById(R.id.tune_progress);
mScanningMessage = (TextView) view.findViewById(R.id.tune_description);
@@ -124,6 +122,8 @@ public class ScanFragment extends SetupFragment {
});
Bundle args = getArguments();
int tunerType = (args == null ? 0 : args.getInt(BaseTunerSetupActivity.KEY_TUNER_TYPE, 0));
+ // TODO: Handle the case when the fragment is restored.
+ startScan(args == null ? 0 : args.getInt(EXTRA_FOR_CHANNEL_SCAN_FILE, 0));
TextView scanTitleView = (TextView) view.findViewById(R.id.tune_title);
switch (tunerType) {
case Tuner.TUNER_TYPE_USB:
@@ -139,28 +139,6 @@ public class ScanFragment extends SetupFragment {
}
@Override
- public void onStart() {
- super.onStart();
- Bundle args = getArguments();
- String inputId = args == null ? null : args.getString(ScanFragment.EXTRA_FOR_INPUT_ID);
- if (inputId == null) {
- Log.w(TAG, "No input ID, stopping setup activity.");
- getActivity().finish();
- }
-
- mChannelDataManager = new ChannelDataManager(getContext().getApplicationContext(), inputId);
- mChannelDataManager.checkDataVersion(getActivity());
- }
-
- @Override
- public void onStop() {
- if (mChannelDataManager != null) {
- mChannelDataManager.release();
- }
- super.onStop();
- }
-
- @Override
protected int getLayoutResourceId() {
return R.layout.ut_channel_scan;
}
@@ -176,13 +154,6 @@ public class ScanFragment extends SetupFragment {
}
@Override
- public void onResume() {
- Bundle args = getArguments();
- startScan(args == null ? 0 : args.getInt(EXTRA_FOR_CHANNEL_SCAN_FILE, 0));
- super.onResume();
- }
-
- @Override
public void onPause() {
Log.d(TAG, "onPause");
if (mChannelScanTask != null) {
@@ -279,7 +250,6 @@ public class ScanFragment extends SetupFragment {
private final Activity mActivity;
private final int mChannelMapId;
-// AOSP_Comment_Out private final com.android.tv.tuner.hdhomerun.HdHomeRunTunerHal mNetworkTuner;
private final TsStreamer mScanTsStreamer;
private final TsStreamer mFileTsStreamer;
private final ConditionVariable mConditionStopped;
@@ -300,13 +270,6 @@ public class ScanFragment extends SetupFragment {
if (hal == null) {
throw new RuntimeException("Failed to open a DVB device");
}
- /* Begin_AOSP_Comment_Out
- if (hal instanceof com.android.tv.tuner.hdhomerun.HdHomeRunTunerHal) {
- mNetworkTuner = (com.android.tv.tuner.hdhomerun.HdHomeRunTunerHal) hal;
- } else {
- mNetworkTuner = null;
- }
- End_AOSP_Comment_Out */
mScanTsStreamer = new TunerTsStreamer(hal, this);
}
mFileTsStreamer = SCAN_LOCAL_STREAMS ? new FileTsStreamer(this, mActivity) : null;
@@ -351,18 +314,6 @@ public class ScanFragment extends SetupFragment {
@Override
protected Void doInBackground(Void... params) {
- /* Begin_AOSP_Comment_Out
- if (mNetworkTuner != null) {
- mChannelDataManager.notifyScanStarted();
- com.android.tv.tuner.hdhomerun.HdHomeRunChannelScan hdHomeRunChannelScan =
- new com.android.tv.tuner.hdhomerun.HdHomeRunChannelScan(
- mActivity.getApplicationContext(), this, mNetworkTuner);
- hdHomeRunChannelScan.scan(mConditionStopped);
- mChannelDataManager.notifyScanCompleted();
- publishProgress(MAX_PROGRESS);
- return null;
- }
- End_AOSP_Comment_Out */
mScanChannelList.clear();
if (SCAN_LOCAL_STREAMS) {
FileTsStreamer.addLocalStreamFiles(mScanChannelList);
@@ -425,10 +376,6 @@ public class ScanFragment extends SetupFragment {
e);
}
streamer.stopStream();
-
- if (ADD_CJ_MUSIC_CHANNELS) {
- addCjMusicChannel(frequency, modulation);
- }
addChannelsWithoutVct(scanChannel);
if (System.currentTimeMillis() > startMs + CHANNEL_SCAN_SHOW_DELAY_MS
&& !mChannelListVisible) {
@@ -447,24 +394,6 @@ public class ScanFragment extends SetupFragment {
if (DEBUG) Log.i(TAG, "Channel scan ended");
}
- private void addCjMusicChannel(int frequency, String modulation) {
- if (frequency == CJ_MUSIC_CHANNEL_FREQUENCY
- && mChannelMapId == R.raw.ut_kr_dev_cj_cable_center_frequencies_qam256) {
- List<TunerChannel> incompleteChannels =
- mScanTsStreamer instanceof TunerTsStreamer
- ? ((TunerTsStreamer) mScanTsStreamer).getMalFormedChannels()
- : new ArrayList<>();
- for (TunerChannel tunerChannel : incompleteChannels) {
- if ((tunerChannel.getVideoPid() == TunerChannel.INVALID_PID)
- && (tunerChannel.getAudioPid() != TunerChannel.INVALID_PID)) {
- tunerChannel.setFrequency(frequency);
- tunerChannel.setModulation(modulation);
- onChannelDetected(tunerChannel, true);
- }
- }
- }
- }
-
private void addChannelsWithoutVct(ScanChannel scanChannel) {
if (scanChannel.radioFrequencyNumber == null
|| !(mScanTsStreamer instanceof TunerTsStreamer)) {
@@ -474,7 +403,6 @@ public class ScanFragment extends SetupFragment {
((TunerTsStreamer) mScanTsStreamer).getMalFormedChannels()) {
if ((tunerChannel.getVideoPid() != TunerChannel.INVALID_PID)
&& (tunerChannel.getAudioPid() != TunerChannel.INVALID_PID)) {
- tunerChannel.setDeliverySystemType(scanChannel.deliverySystemType);
tunerChannel.setFrequency(scanChannel.frequency);
tunerChannel.setModulation(scanChannel.modulation);
tunerChannel.setShortName(
@@ -492,9 +420,9 @@ public class ScanFragment extends SetupFragment {
private TsStreamer getStreamer(int type) {
switch (type) {
- case TunerType.TYPE_TUNER_VALUE:
+ case Channel.TunerType.TYPE_TUNER:
return mScanTsStreamer;
- case TunerType.TYPE_FILE_VALUE:
+ case Channel.TunerType.TYPE_FILE:
return mFileTsStreamer;
default:
return null;
diff --git a/tuner/src/com/android/tv/tuner/setup/ScanResultFragment.java b/tuner/src/com/android/tv/tuner/setup/ScanResultFragment.java
index 01bcc9f2..bd3f9ad9 100644
--- a/tuner/src/com/android/tv/tuner/setup/ScanResultFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/ScanResultFragment.java
@@ -20,8 +20,8 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+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.tv.tuner.R;
diff --git a/tuner/src/com/android/tv/tuner/setup/WelcomeFragment.java b/tuner/src/com/android/tv/tuner/setup/WelcomeFragment.java
index dfa994b6..2a414df7 100644
--- a/tuner/src/com/android/tv/tuner/setup/WelcomeFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/WelcomeFragment.java
@@ -19,8 +19,8 @@ package com.android.tv.tuner.setup;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+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.tv.tuner.R;
diff --git a/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java b/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
index dfe9005b..48b17dcb 100644
--- a/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
+++ b/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
@@ -18,17 +18,4 @@ package com.android.tv.tuner.singletons;
import com.android.tv.common.singletons.HasTvInputId;
/** Singletons used in tuner applications */
-public interface TunerSingletons extends HasTvInputId {
-
- /*
- * Do not add any new methods here.
- *
- * To move a getter to Injection.
- * 1. Make a type injectable @Singleton.
- * 2. Mark the getter here as deprecated.
- * 3. Lazily inject the object in TvApplication.
- * 4. Move easy usages of getters to injection instead.
- * 5. Delete the method when all usages are migrated.
- */
-
-}
+public interface TunerSingletons extends HasTvInputId {}
diff --git a/tuner/src/com/android/tv/tuner/source/FileSourceEventDetector.java b/tuner/src/com/android/tv/tuner/source/FileSourceEventDetector.java
index 5ee897bb..85932c8c 100644
--- a/tuner/src/com/android/tv/tuner/source/FileSourceEventDetector.java
+++ b/tuner/src/com/android/tv/tuner/source/FileSourceEventDetector.java
@@ -24,9 +24,9 @@ import com.android.tv.tuner.data.PsiData.PmtItem;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.PsipData.SdtItem;
import com.android.tv.tuner.data.PsipData.VctItem;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.android.tv.tuner.ts.TsParser;
import java.util.ArrayList;
diff --git a/tuner/src/com/android/tv/tuner/source/FileTsStreamer.java b/tuner/src/com/android/tv/tuner/source/FileTsStreamer.java
index 15f3458a..99d37e39 100644
--- a/tuner/src/com/android/tv/tuner/source/FileTsStreamer.java
+++ b/tuner/src/com/android/tv/tuner/source/FileTsStreamer.java
@@ -17,9 +17,7 @@
package com.android.tv.tuner.source;
import android.content.Context;
-import android.net.Uri;
import android.os.Environment;
-import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SparseBooleanArray;
import com.android.tv.common.SoftPreconditions;
@@ -28,8 +26,8 @@ import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.features.TunerFeatures;
import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.android.tv.tuner.ts.TsParser;
-import com.google.android.exoplayer2.upstream.DataSpec;
-import com.google.android.exoplayer2.upstream.TransferListener;
+import com.google.android.exoplayer.C;
+import com.google.android.exoplayer.upstream.DataSpec;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -73,7 +71,6 @@ public class FileTsStreamer implements TsStreamer {
public static class FileDataSource extends TsDataSource {
private final FileTsStreamer mTsStreamer;
private final AtomicLong mLastReadPosition = new AtomicLong(0);
- private Uri mUri;
private long mStartBufferedPosition;
private FileDataSource(FileTsStreamer tsStreamer) {
@@ -99,10 +96,9 @@ public class FileTsStreamer implements TsStreamer {
}
@Override
- public long open(DataSpec dataSpec) {
- mUri = dataSpec.uri;
+ public long open(DataSpec dataSpec) throws IOException {
mLastReadPosition.set(0);
- return com.google.android.exoplayer2.C.LENGTH_UNSET;
+ return C.LENGTH_UNBOUNDED;
}
@Override
@@ -121,19 +117,6 @@ public class FileTsStreamer implements TsStreamer {
}
return ret;
}
-
- // ExoPlayer V2 DataSource implementation.
-
- @Override
- public void addTransferListener(TransferListener transferListener) {
- // TODO: Implement to support metrics collection.
- }
-
- @Nullable
- @Override
- public Uri getUri() {
- return mUri;
- }
}
/**
diff --git a/tuner/src/com/android/tv/tuner/source/TsDataSource.java b/tuner/src/com/android/tv/tuner/source/TsDataSource.java
index 18f4458b..cf3c25d9 100644
--- a/tuner/src/com/android/tv/tuner/source/TsDataSource.java
+++ b/tuner/src/com/android/tv/tuner/source/TsDataSource.java
@@ -17,7 +17,7 @@
package com.android.tv.tuner.source;
import com.android.tv.common.compat.TvInputConstantCompat;
-import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer.upstream.DataSource;
/** {@link DataSource} for MPEG-TS stream, which will be used by {@link TsExtractor}. */
public abstract class TsDataSource implements DataSource {
diff --git a/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java b/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
index 3c00b5cc..28756a93 100644
--- a/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
+++ b/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
@@ -19,8 +19,8 @@ package com.android.tv.tuner.source;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import com.android.tv.tuner.api.Tuner;
-import com.android.tv.tuner.data.Channel;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
diff --git a/tuner/src/com/android/tv/tuner/source/TunerTsStreamer.java b/tuner/src/com/android/tv/tuner/source/TunerTsStreamer.java
index 19058c8a..9e68c910 100644
--- a/tuner/src/com/android/tv/tuner/source/TunerTsStreamer.java
+++ b/tuner/src/com/android/tv/tuner/source/TunerTsStreamer.java
@@ -17,11 +17,8 @@
package com.android.tv.tuner.source;
import android.content.Context;
-import android.net.Uri;
-import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
-
import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.api.ScanChannel;
import com.android.tv.tuner.api.Tuner;
@@ -29,10 +26,8 @@ import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.prefs.TunerPreferences;
import com.android.tv.tuner.ts.EventDetector;
import com.android.tv.tuner.ts.EventDetector.EventListener;
-
-import com.google.android.exoplayer2.C;
-import com.google.android.exoplayer2.upstream.DataSpec;
-import com.google.android.exoplayer2.upstream.TransferListener;
+import com.google.android.exoplayer.C;
+import com.google.android.exoplayer.upstream.DataSpec;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -71,7 +66,6 @@ public class TunerTsStreamer implements TsStreamer {
private final TunerTsStreamer mTsStreamer;
private final AtomicLong mLastReadPosition = new AtomicLong(0);
private long mStartBufferedPosition;
- private Uri mUri;
private TunerDataSource(TunerTsStreamer tsStreamer) {
mTsStreamer = tsStreamer;
@@ -96,16 +90,13 @@ public class TunerTsStreamer implements TsStreamer {
}
@Override
- public long open(DataSpec dataSpec) {
- mUri = dataSpec.uri;
+ public long open(DataSpec dataSpec) throws IOException {
mLastReadPosition.set(0);
- return C.LENGTH_UNSET;
+ return C.LENGTH_UNBOUNDED;
}
@Override
- public void close() {
- mUri = null;
- }
+ public void close() {}
@Override
public int read(byte[] buffer, int offset, int readLength) throws IOException {
@@ -135,18 +126,6 @@ public class TunerTsStreamer implements TsStreamer {
public int getSignalStrength() {
return mTsStreamer.getSignalStrength();
}
-
- @Override
- public void addTransferListener(TransferListener transferListener) {
- // TODO: Implement to support metrics collection.
- }
-
- @Nullable
- @Override
- public Uri getUri() {
- return mUri;
- }
-
}
/**
* Creates {@link TsStreamer} for playing or recording the specified channel.
@@ -173,8 +152,7 @@ public class TunerTsStreamer implements TsStreamer {
@Override
public boolean startStream(TunerChannel channel) {
if (mTunerHal.tune(
- channel.getDeliverySystemType().getNumber(), channel.getFrequency(),
- channel.getModulation(), channel.getDisplayNumber(false))) {
+ channel.getFrequency(), channel.getModulation(), channel.getDisplayNumber(false))) {
if (channel.hasVideo()) {
mTunerHal.addPidFilter(channel.getVideoPid(), Tuner.FILTER_TYPE_VIDEO);
}
@@ -192,7 +170,6 @@ public class TunerTsStreamer implements TsStreamer {
mTunerHal.addPidFilter(channel.getPcrPid(), Tuner.FILTER_TYPE_PCR);
if (mEventDetector != null) {
mEventDetector.startDetecting(
- channel.getDeliverySystemType(),
channel.getFrequency(),
channel.getModulation(),
channel.getProgramNumber());
@@ -222,11 +199,9 @@ public class TunerTsStreamer implements TsStreamer {
@Override
public boolean startStream(ScanChannel channel) {
- if (mTunerHal.tune(channel.deliverySystemType.getNumber(), channel.frequency,
- channel.modulation, null)) {
+ if (mTunerHal.tune(channel.frequency, channel.modulation, null)) {
mEventDetector.startDetecting(
- channel.deliverySystemType, channel.frequency, channel.modulation,
- EventDetector.ALL_PROGRAM_NUMBERS);
+ channel.frequency, channel.modulation, EventDetector.ALL_PROGRAM_NUMBERS);
synchronized (mCircularBufferMonitor) {
if (mStreaming) {
Log.w(TAG, "Streaming should be stopped before start streaming");
@@ -320,7 +295,7 @@ public class TunerTsStreamer implements TsStreamer {
public void registerListener(EventListener listener) {
if (mEventDetector != null && listener != null) {
synchronized (mEventListenerActions) {
- mEventListenerActions.add(Pair.create(listener, true));
+ mEventListenerActions.add(new Pair<>(listener, true));
}
}
}
diff --git a/tuner/src/com/android/tv/tuner/ts/EventDetector.java b/tuner/src/com/android/tv/tuner/ts/EventDetector.java
index 3a2d835e..6d1fc277 100644
--- a/tuner/src/com/android/tv/tuner/ts/EventDetector.java
+++ b/tuner/src/com/android/tv/tuner/ts/EventDetector.java
@@ -20,13 +20,12 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.tv.tuner.api.Tuner;
-import com.android.tv.tuner.data.Channel.DeliverySystemType;
import com.android.tv.tuner.data.PsiData;
import com.android.tv.tuner.data.PsipData;
import com.android.tv.tuner.data.PsipData.EitItem;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -52,7 +51,6 @@ public class EventDetector {
private final SparseBooleanArray mVctCaptionTracksFound = new SparseBooleanArray();
private final SparseBooleanArray mEitCaptionTracksFound = new SparseBooleanArray();
private final List<EventListener> mEventListeners = new ArrayList<>();
- private DeliverySystemType mDeliverySystemType;
private int mFrequency;
private String mModulation;
private int mProgramNumber = ALL_PROGRAM_NUMBERS;
@@ -172,7 +170,6 @@ public class EventDetector {
}
tunerChannel.setAudioTracks(audioTracks);
tunerChannel.setCaptionTracks(captionTracks);
- tunerChannel.setDeliverySystemType(mDeliverySystemType);
tunerChannel.setFrequency(mFrequency);
tunerChannel.setModulation(mModulation);
mChannelMap.put(tunerChannel.getProgramNumber(), tunerChannel);
@@ -212,7 +209,6 @@ public class EventDetector {
int channelProgramNumber = channel.getServiceId();
tunerChannel.setAudioTracks(audioTracks);
tunerChannel.setCaptionTracks(captionTracks);
- tunerChannel.setDeliverySystemType(mDeliverySystemType);
tunerChannel.setFrequency(mFrequency);
tunerChannel.setModulation(mModulation);
mChannelMap.put(tunerChannel.getProgramNumber(), tunerChannel);
@@ -256,18 +252,10 @@ public class EventDetector {
private void reset() {
// TODO: Use TsParser.reset()
- int[] deliverySystemTypes = mTunerHal.getDeliverySystemTypes();
- boolean isDvbSignal = false;
- for (int i = 0; i < deliverySystemTypes.length; i++) {
- if (Tuner.isDvbDeliverySystem(deliverySystemTypes[i])) {
- isDvbSignal = true;
- break;
- }
- }
mTsParser =
new TsParser(
mTsOutputListener,
- isDvbSignal);
+ Tuner.isDvbDeliverySystem(mTunerHal.getDeliverySystemType()));
mPidSet.clear();
mVctProgramNumberSet.clear();
mSdtProgramNumberSet.clear();
@@ -284,10 +272,8 @@ public class EventDetector {
* @param programNumber The program number if this is for handling tune request. For scanning
* purpose, supply {@link #ALL_PROGRAM_NUMBERS}.
*/
- public void startDetecting(DeliverySystemType deliverySystemType, int frequency,
- String modulation, int programNumber) {
+ public void startDetecting(int frequency, String modulation, int programNumber) {
reset();
- mDeliverySystemType = deliverySystemType;
mFrequency = frequency;
mModulation = modulation;
mProgramNumber = programNumber;
diff --git a/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java b/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
index e47162ad..d22b6399 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
@@ -21,26 +21,17 @@ import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.media.tv.TvInputService;
-import android.net.Uri;
import android.util.Log;
-
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-import com.android.tv.tuner.tvinput.factory.TunerRecordingSessionFactory;
import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.cache.RemovalListener;
-
import dagger.android.AndroidInjection;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
-
import javax.inject.Inject;
/** {@link BaseTunerTvInputService} serves TV channels coming from a tuner device. */
@@ -51,19 +42,10 @@ public class BaseTunerTvInputService extends TvInputService {
private static final int DVR_STORAGE_CLEANUP_JOB_ID = 100;
private final Set<Session> mTunerSessions = Collections.newSetFromMap(new WeakHashMap<>());
- private final Set<RecordingSession> mTunerRecordingSession =
- Collections.newSetFromMap(new WeakHashMap<>());
+ private ChannelDataManager mChannelDataManager;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TsDataSourceManager.Factory mTsDataSourceManagerFactory;
@Inject TunerSessionFactory mTunerSessionFactory;
- @Inject TunerRecordingSessionFactory mTunerRecordingSessionFactory;
-
- LoadingCache<String, ChannelDataManager> mChannelDataManagers;
- RemovalListener<String, ChannelDataManager> mChannelDataManagerRemovalListener =
- notification -> {
- ChannelDataManager cdm = notification.getValue();
- if (cdm != null) {
- cdm.release();
- }
- };
@Override
public void onCreate() {
@@ -75,17 +57,7 @@ public class BaseTunerTvInputService extends TvInputService {
AndroidInjection.inject(this);
super.onCreate();
if (DEBUG) Log.d(TAG, "onCreate");
- mChannelDataManagers =
- CacheBuilder.newBuilder()
- .weakValues()
- .removalListener(mChannelDataManagerRemovalListener)
- .build(
- new CacheLoader<String, ChannelDataManager>() {
- @Override
- public ChannelDataManager load(String inputId) {
- return createChannelDataManager(inputId);
- }
- });
+ mChannelDataManager = new ChannelDataManager(getApplicationContext());
if (CommonFeatures.DVR.isEnabled(this)) {
JobScheduler jobScheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
@@ -105,24 +77,21 @@ public class BaseTunerTvInputService extends TvInputService {
}
}
- private ChannelDataManager createChannelDataManager(String inputId) {
- return new ChannelDataManager(getApplicationContext(), inputId);
- }
-
@Override
public void onDestroy() {
if (DEBUG) Log.d(TAG, "onDestroy");
super.onDestroy();
- mChannelDataManagers.invalidateAll();
+ mChannelDataManager.release();
}
@Override
public RecordingSession onCreateRecordingSession(String inputId) {
- RecordingSession session =
- mTunerRecordingSessionFactory.create(
- inputId, this::onReleased, mChannelDataManagers.getUnchecked(inputId));
- mTunerRecordingSession.add(session);
- return session;
+ return new TunerRecordingSession(
+ this,
+ inputId,
+ mChannelDataManager,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
}
@Override
@@ -134,12 +103,8 @@ public class BaseTunerTvInputService extends TvInputService {
Log.d(TAG, "abort creating an session");
return null;
}
-
final Session session =
- mTunerSessionFactory.create(
- mChannelDataManagers.getUnchecked(inputId),
- this::onReleased,
- this::getRecordingUri);
+ mTunerSessionFactory.create(this, mChannelDataManager, this::onReleased);
mTunerSessions.add(session);
session.setOverlayViewEnabled(true);
return session;
@@ -150,22 +115,7 @@ public class BaseTunerTvInputService extends TvInputService {
}
}
- private Uri getRecordingUri(Uri channelUri) {
- for (RecordingSession session : mTunerRecordingSession) {
- TunerRecordingSession tunerSession = (TunerRecordingSession) session;
- if (tunerSession.getChannelUri().equals(channelUri)) {
- return tunerSession.getRecordingUri();
- }
- }
- return null;
- }
-
private void onReleased(Session session) {
mTunerSessions.remove(session);
- mChannelDataManagers.cleanUp();
- }
-
- private void onReleased(RecordingSession session) {
- mTunerRecordingSession.remove(session);
}
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
index ed61f71b..55616931 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
@@ -22,40 +22,33 @@ import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
-
import com.android.tv.common.compat.RecordingSessionCompat;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-import com.android.tv.tuner.tvinput.factory.TunerRecordingSessionFactory;
-import com.android.tv.tuner.tvinput.factory.TunerRecordingSessionFactory.RecordingSessionReleasedCallback;
-
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/** Processes DVR recordings, and deletes the previously recorded contents. */
-@AutoFactory(
- className = "TunerRecordingSessionFactoryImpl",
- implementing = TunerRecordingSessionFactory.class)
public class TunerRecordingSession extends RecordingSessionCompat {
private static final String TAG = "TunerRecordingSession";
private static final boolean DEBUG = false;
private final TunerRecordingSessionWorker mSessionWorker;
- private final RecordingSessionReleasedCallback mReleasedCallback;
- private Uri mChannelUri;
- private Uri mRecordingUri;
public TunerRecordingSession(
- @Provided @ApplicationContext Context context,
+ Context context,
String inputId,
- RecordingSessionReleasedCallback releasedCallback,
ChannelDataManager channelDataManager,
- @Provided TunerRecordingSessionWorker.Factory tunerRecordingSessionWorkerFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
- mReleasedCallback = releasedCallback;
mSessionWorker =
- tunerRecordingSessionWorkerFactory.create(
- context, inputId, channelDataManager, this);
+ new TunerRecordingSessionWorker(
+ context,
+ inputId,
+ channelDataManager,
+ this,
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
}
// RecordingSession
@@ -76,7 +69,6 @@ public class TunerRecordingSession extends RecordingSessionCompat {
Log.d(TAG, "Requesting recording session release.");
}
mSessionWorker.release();
- mReleasedCallback.onReleased(this);
}
@MainThread
@@ -103,7 +95,6 @@ public class TunerRecordingSession extends RecordingSessionCompat {
if (DEBUG) {
Log.d(TAG, "Notifying recording session tuned.");
}
- mChannelUri = channelUri;
notifyTuned(channelUri);
}
@@ -121,7 +112,6 @@ public class TunerRecordingSession extends RecordingSessionCompat {
if (DEBUG) {
Log.d(TAG, "Notifying record successfully finished.");
}
- mRecordingUri = null;
notifyRecordingStopped(recordedProgramUri);
}
@@ -130,19 +120,4 @@ public class TunerRecordingSession extends RecordingSessionCompat {
Log.w(TAG, "Notifying recording error: " + reason);
notifyError(reason);
}
-
- public void onRecordingStatePartial(Uri recUri) {
- if (DEBUG) {
- Log.d(TAG, "Updating recording session state to Partial");
- }
- mRecordingUri = recUri;
- }
-
- public Uri getChannelUri() {
- return mChannelUri;
- }
-
- public Uri getRecordingUri() {
- return mRecordingUri;
- }
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
index 97cd0572..2c0c09a6 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
@@ -37,19 +37,17 @@ import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
-
import androidx.tvprovider.media.tv.Program;
-
import com.android.tv.common.BaseApplication;
import com.android.tv.common.data.RecordedProgramState;
import com.android.tv.common.recording.RecordingCapability;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.tuner.DvbDeviceAccessor;
import com.android.tv.tuner.data.PsipData;
import com.android.tv.tuner.data.PsipData.EitItem;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
-import com.android.tv.tuner.dvb.DvbDeviceAccessor;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractor;
import com.android.tv.tuner.exoplayer.SampleExtractor;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
@@ -59,11 +57,8 @@ import com.android.tv.tuner.source.TsDataSource;
import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-
import com.google.android.exoplayer.C;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
@@ -147,6 +142,7 @@ public class TunerRecordingSessionWorker
private static final long CHANNEL_ID_NONE = -1;
private static final int MAX_TUNING_RETRY = 6;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
@@ -172,31 +168,15 @@ public class TunerRecordingSessionWorker
private PsipData.EitItem mCurrenProgram;
private List<AtscCaptionTrack> mCaptionTracks;
private DvrStorageManager mDvrStorageManager;
- private final ExoPlayerSampleExtractor.Factory mExoPlayerSampleExtractorFactory;
- /**
- * Factory for {@link TunerRecordingSessionWorker}}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- TunerRecordingSessionWorker create(
- Context context,
- String inputId,
- ChannelDataManager dataManager,
- TunerRecordingSession session);
- }
-
- @AutoFactory(implementing = Factory.class)
public TunerRecordingSessionWorker(
Context context,
String inputId,
ChannelDataManager dataManager,
TunerRecordingSession session,
- @Provided ExoPlayerSampleExtractor.Factory exoPlayerSampleExtractorFactory,
- @Provided TsDataSourceManager.Factory tsDataSourceManagerFactory) {
- mExoPlayerSampleExtractorFactory = exoPlayerSampleExtractorFactory;
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
mRandom.setSeed(System.nanoTime());
mContext = context;
HandlerThread handlerThread = new HandlerThread(TAG);
@@ -237,7 +217,7 @@ public class TunerRecordingSessionWorker
if (mChannel == null || mChannel.compareTo(channel) != 0) {
return;
}
- mHandler.obtainMessage(MSG_UPDATE_CC_INFO, Pair.create(channel, items)).sendToTarget();
+ mHandler.obtainMessage(MSG_UPDATE_CC_INFO, new Pair<>(channel, items)).sendToTarget();
mChannelDataManager.notifyEventDetected(channel, items);
}
@@ -382,7 +362,7 @@ public class TunerRecordingSessionWorker
}
case MSG_UPDATE_PARTIAL_STATE:
{
- updateRecordedProgramStatePartial();
+ updateRecordedProgram(RecordedProgramState.PARTIAL, -1, -1);
return true;
}
}
@@ -476,30 +456,36 @@ public class TunerRecordingSessionWorker
mRecordStartTime = System.currentTimeMillis();
mDvrStorageManager = new DvrStorageManager(mStorageDir, true);
mRecorder =
- mExoPlayerSampleExtractorFactory.create(
- Uri.EMPTY, mTunerSource, new BufferManager(mDvrStorageManager), this, true);
+ new ExoPlayerSampleExtractor(
+ Uri.EMPTY,
+ mTunerSource,
+ new BufferManager(mDvrStorageManager),
+ this,
+ true,
+ mConcurrentDvrPlaybackFlags);
mRecorder.setOnCompletionListener(this, mHandler);
mProgramUri = programUri;
mSessionState = STATE_RECORDING;
mRecorderRunning = true;
- mRecordedProgramUri =
- insertRecordedProgram(
- getRecordedProgram(),
- mChannel.getChannelId(),
- Uri.fromFile(mStorageDir).toString(),
- calculateRecordingSizeInBytes(),
- mRecordStartTime,
- mRecordStartTime);
- if (mRecordedProgramUri == null) {
- new DeleteRecordingTask().execute(mStorageDir);
- mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
- Log.e(TAG, "Inserting a recording to DB failed");
- return false;
+ if (mConcurrentDvrPlaybackFlags.enabled()) {
+ mRecordedProgramUri =
+ insertRecordedProgram(
+ getRecordedProgram(),
+ mChannel.getChannelId(),
+ Uri.fromFile(mStorageDir).toString(),
+ calculateRecordingSizeInBytes(),
+ mRecordStartTime,
+ mRecordStartTime);
+ if (mRecordedProgramUri == null) {
+ new DeleteRecordingTask().execute(mStorageDir);
+ mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
+ Log.e(TAG, "Inserting a recording to DB failed");
+ return false;
+ }
+ mSession.onRecordingUri(mRecordedProgramUri.toString());
+ mHandler.sendEmptyMessageDelayed(
+ MSG_UPDATE_PARTIAL_STATE, MIN_PARTIAL_RECORDING_DURATION_MS);
}
- mSession.onRecordingUri(mRecordedProgramUri.toString());
- mHandler.sendEmptyMessageDelayed(
- MSG_UPDATE_PARTIAL_STATE, MIN_PARTIAL_RECORDING_DURATION_MS);
-
mHandler.sendEmptyMessage(MSG_PREPARE_RECODER);
mHandler.removeMessages(MSG_MONITOR_STORAGE_STATUS);
mHandler.sendEmptyMessageDelayed(MSG_MONITOR_STORAGE_STATUS, STORAGE_MONITOR_INTERVAL_MS);
@@ -606,7 +592,7 @@ public class TunerRecordingSessionWorker
if (checkRecordedProgramTable(COLUMN_SERIES_ID)) {
values.put(COLUMN_SERIES_ID, mSeriesId);
}
- if (checkRecordedProgramTable(COLUMN_STATE)) {
+ if (mConcurrentDvrPlaybackFlags.enabled() && checkRecordedProgramTable(COLUMN_STATE)) {
values.put(COLUMN_STATE, RecordedProgramState.STARTED.name());
}
if (program != null) {
@@ -616,24 +602,18 @@ public class TunerRecordingSessionWorker
.insert(TvContract.RecordedPrograms.CONTENT_URI, values);
}
- private void updateRecordedProgramStateFinished(long endTime, long totalBytes) {
+ private void updateRecordedProgram(RecordedProgramState state, long endTime, long totalBytes) {
ContentValues values = new ContentValues();
- values.put(RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, totalBytes);
- values.put(RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS, endTime - mRecordStartTime);
- values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, endTime);
if (checkRecordedProgramTable(COLUMN_STATE)) {
- values.put(COLUMN_STATE, RecordedProgramState.FINISHED.name());
+ values.put(COLUMN_STATE, state.name());
}
- mContext.getContentResolver().update(mRecordedProgramUri, values, null, null);
- }
-
- private void updateRecordedProgramStatePartial() {
- mSession.onRecordingStatePartial(mRecordedProgramUri);
- if (checkRecordedProgramTable(COLUMN_STATE)) {
- ContentValues values = new ContentValues();
- values.put(COLUMN_STATE, RecordedProgramState.PARTIAL.name());
- mContext.getContentResolver().update(mRecordedProgramUri, values, null, null);
+ if (state.equals(RecordedProgramState.FINISHED)) {
+ values.put(RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, totalBytes);
+ values.put(
+ RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS, endTime - mRecordStartTime);
+ values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, endTime);
}
+ mContext.getContentResolver().update(mRecordedProgramUri, values, null, null);
}
private void onRecordingResult(boolean success, long lastExtractedPositionUs) {
@@ -660,7 +640,25 @@ public class TunerRecordingSessionWorker
(lastExtractedPositionUs == C.UNKNOWN_TIME_US)
? System.currentTimeMillis()
: mRecordStartTime + lastExtractedPositionUs / 1000;
- updateRecordedProgramStateFinished(recordEndTime, calculateRecordingSizeInBytes());
+ if (!mConcurrentDvrPlaybackFlags.enabled()) {
+ mRecordedProgramUri =
+ insertRecordedProgram(
+ getRecordedProgram(),
+ mChannel.getChannelId(),
+ Uri.fromFile(mStorageDir).toString(),
+ calculateRecordingSizeInBytes(),
+ mRecordStartTime,
+ recordEndTime);
+ if (mRecordedProgramUri == null) {
+ new DeleteRecordingTask().execute(mStorageDir);
+ mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
+ Log.e(TAG, "Inserting a recording to DB failed");
+ return;
+ }
+ } else {
+ updateRecordedProgram(
+ RecordedProgramState.FINISHED, recordEndTime, calculateRecordingSizeInBytes());
+ }
mDvrStorageManager.writeCaptionInfoFiles(mCaptionTracks);
mSession.onRecordFinished(mRecordedProgramUri);
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
index eb3a7d0c..fedb5f6b 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
@@ -27,24 +27,18 @@ import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import android.view.View;
-
import com.android.tv.common.CommonPreferences.CommonPreferencesChangedListener;
import com.android.tv.common.compat.TisSessionCompat;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.tuner.prefs.TunerPreferences;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory.SessionRecordingCallback;
import com.android.tv.tuner.tvinput.factory.TunerSessionFactory.SessionReleasedCallback;
-
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/**
* Provides a tuner TV input session. Main tuner input functions are implemented in {@link
* TunerSessionWorker}.
*/
-@AutoFactory(className = "TunerSessionV1Factory", implementing = TunerSessionFactory.class)
public class TunerSession extends TisSessionCompat implements CommonPreferencesChangedListener {
private static final String TAG = "TunerSession";
@@ -53,26 +47,26 @@ public class TunerSession extends TisSessionCompat implements CommonPreferencesC
private final TunerSessionOverlay mTunerSessionOverlay;
private final TunerSessionWorker mSessionWorker;
private final SessionReleasedCallback mReleasedCallback;
- private final SessionRecordingCallback mRecordingCallback;
private boolean mPlayPaused;
private long mTuneStartTimestamp;
public TunerSession(
- @Provided @ApplicationContext Context context,
+ Context context,
ChannelDataManager channelDataManager,
SessionReleasedCallback releasedCallback,
- SessionRecordingCallback recordingCallback,
- @Provided TunerSessionWorker.Factory tunerSessionWorkerFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
mReleasedCallback = releasedCallback;
- mRecordingCallback = recordingCallback;
mTunerSessionOverlay = new TunerSessionOverlay(context);
mSessionWorker =
- tunerSessionWorkerFactory.create(
+ new TunerSessionWorker(
context,
channelDataManager,
this,
- mTunerSessionOverlay);
+ mTunerSessionOverlay,
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
TunerPreferences.setCommonPreferencesChangedListener(this);
}
@@ -210,8 +204,4 @@ public class TunerSession extends TisSessionCompat implements CommonPreferencesC
public void onCommonPreferencesChanged() {
mSessionWorker.sendMessage(TunerSessionWorker.MSG_TUNER_PREFERENCES_CHANGED);
}
-
- public Uri getRecordingUri(Uri channelUri) {
- return mRecordingCallback.getRecordingUri(channelUri);
- }
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
index 7ebb2b21..4eca44d6 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
@@ -27,21 +27,15 @@ import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import android.view.View;
-
import com.android.tv.common.CommonPreferences.CommonPreferencesChangedListener;
import com.android.tv.common.compat.TisSessionCompat;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.tuner.prefs.TunerPreferences;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory.SessionRecordingCallback;
import com.android.tv.tuner.tvinput.factory.TunerSessionFactory.SessionReleasedCallback;
-
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/** Provides a tuner TV input session. */
-@AutoFactory(implementing = TunerSessionFactory.class)
public class TunerSessionExoV2 extends TisSessionCompat
implements CommonPreferencesChangedListener {
@@ -51,26 +45,26 @@ public class TunerSessionExoV2 extends TisSessionCompat
private final TunerSessionOverlay mTunerSessionOverlay;
private final TunerSessionWorkerExoV2 mSessionWorker;
private final SessionReleasedCallback mReleasedCallback;
- private final SessionRecordingCallback mRecordingCallback;
private boolean mPlayPaused;
private long mTuneStartTimestamp;
public TunerSessionExoV2(
- @Provided @ApplicationContext Context context,
+ Context context,
ChannelDataManager channelDataManager,
SessionReleasedCallback releasedCallback,
- SessionRecordingCallback recordingCallback,
- @Provided TunerSessionWorkerExoV2.Factory tunerSessionWorkerExoV2Factory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
mReleasedCallback = releasedCallback;
- mRecordingCallback = recordingCallback;
mTunerSessionOverlay = new TunerSessionOverlay(context);
mSessionWorker =
- tunerSessionWorkerExoV2Factory.create(
+ new TunerSessionWorkerExoV2(
context,
channelDataManager,
this,
- mTunerSessionOverlay);
+ mTunerSessionOverlay,
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
TunerPreferences.setCommonPreferencesChangedListener(this);
}
@@ -209,8 +203,4 @@ public class TunerSessionExoV2 extends TisSessionCompat
public void onCommonPreferencesChanged() {
mSessionWorker.sendMessage(TunerSessionWorkerExoV2.MSG_TUNER_PREFERENCES_CHANGED);
}
-
- public Uri getRecordingUri(Uri channelUri) {
- return mRecordingCallback.getRecordingUri(channelUri);
- }
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionOverlay.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionOverlay.java
index 53e0bcc2..9f21e16a 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionOverlay.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionOverlay.java
@@ -26,18 +26,17 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
-
+import com.android.tv.common.util.SystemPropertiesProxy;
import com.android.tv.tuner.R;
import com.android.tv.tuner.cc.CaptionLayout;
import com.android.tv.tuner.cc.CaptionTrackRenderer;
import com.android.tv.tuner.data.Cea708Data.CaptionEvent;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.util.GlobalSettingsUtils;
import com.android.tv.tuner.util.StatusTextUtils;
/** Executes {@link Session} overlay changes on the main thread. */
/* package */ final class TunerSessionOverlay implements Handler.Callback {
- private static final boolean DEBUG = false;
/** Displays the given {@link String} message object in the message view. */
public static final int MSG_UI_SHOW_MESSAGE = 1;
@@ -68,6 +67,8 @@ import com.android.tv.tuner.util.StatusTextUtils;
/** Displays a toast signalling that a re-scan is required. Does not expect a message object. */
public static final int MSG_UI_TOAST_RESCAN_NEEDED = 11;
+ private static final String USBTUNER_SHOW_DEBUG = "persist.tv.tuner.show_debug";
+
private final Context mContext;
private final Handler mHandler;
private final View mOverlayView;
@@ -87,12 +88,13 @@ import com.android.tv.tuner.util.StatusTextUtils;
mHandler = new Handler(this);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ boolean showDebug = SystemPropertiesProxy.getBoolean(USBTUNER_SHOW_DEBUG, false);
mOverlayView = inflater.inflate(R.layout.ut_overlay_view, null);
mMessageLayout = mOverlayView.findViewById(R.id.message_layout);
mMessageLayout.setVisibility(View.INVISIBLE);
mMessageView = mOverlayView.findViewById(R.id.message);
mStatusView = mOverlayView.findViewById(R.id.tuner_status);
- mStatusView.setVisibility(DEBUG ? View.VISIBLE : View.INVISIBLE);
+ mStatusView.setVisibility(showDebug ? View.VISIBLE : View.INVISIBLE);
mAudioStatusView = mOverlayView.findViewById(R.id.audio_status);
mAudioStatusView.setVisibility(View.INVISIBLE);
CaptionLayout captionLayout = mOverlayView.findViewById(R.id.caption);
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
index 792dfaab..d3f9409b 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
@@ -44,22 +44,22 @@ import android.util.Pair;
import android.util.SparseArray;
import android.view.Surface;
import android.view.accessibility.CaptioningManager;
-
import com.android.tv.common.CommonPreferences.TrickplaySetting;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.compat.TvInputConstantCompat;
import com.android.tv.common.customization.CustomizationManager;
import com.android.tv.common.customization.CustomizationManager.TRICKPLAY_MODE;
-import com.android.tv.common.dev.DeveloperPreferences;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.util.SystemPropertiesProxy;
import com.android.tv.tuner.data.Cea708Data;
-import com.android.tv.tuner.data.Channel;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.PsipData.TvTracksInterface;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.MpegTsPlayer;
import com.android.tv.tuner.exoplayer.MpegTsRendererBuilder;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
@@ -74,15 +74,10 @@ import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
import com.android.tv.tuner.tvinput.debug.TunerDebug;
import com.android.tv.tuner.util.StatusTextUtils;
-
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
import com.google.common.collect.ImmutableList;
-
-import com.android.tv.common.flags.LegacyFlags;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
@@ -108,6 +103,8 @@ public class TunerSessionWorker
private static final boolean DEBUG = false;
private static final boolean ENABLE_PROFILER = true;
private static final String PLAY_FROM_CHANNEL = "channel";
+ private static final String MAX_BUFFER_SIZE_KEY = "tv.tuner.buffersize_mbytes";
+ private static final int MAX_BUFFER_SIZE_DEF = 2 * 1024; // 2GB
private static final int MIN_BUFFER_SIZE_DEF = 256; // 256MB
// Public messages
@@ -192,8 +189,6 @@ public class TunerSessionWorker
private final int mMaxTrickplayBufferSizeMb;
private final File mTrickplayBufferDir;
private final @TRICKPLAY_MODE int mTrickplayModeCustomization;
- private final LegacyFlags mLegacyFlags;
- private final MpegTsRendererBuilder.Factory mMpegTsRendererBuilderFactory;
private volatile Surface mSurface;
private volatile float mVolume = 1.0f;
private volatile boolean mCaptionEnabled;
@@ -236,44 +231,25 @@ public class TunerSessionWorker
private boolean mIsActiveSession;
private boolean mReleaseRequested; // Guarded by mReleaseLock
private final Object mReleaseLock = new Object();
- private Uri mChannelUri;
- private Uri mRecordingUri;
- private boolean mOnTuneUsesRecording = false;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private int mSignalStrength;
private long mRecordedProgramStartTimeMs;
- /**
- * Factory for {@link TunerSessionWorker}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public TunerSessionWorker create(
- Context context,
- ChannelDataManager channelDataManager,
- TunerSession tunerSession,
- TunerSessionOverlay tunerSessionOverlay);
- }
-
- @AutoFactory(implementing = Factory.class)
public TunerSessionWorker(
Context context,
ChannelDataManager channelDataManager,
TunerSession tunerSession,
TunerSessionOverlay tunerSessionOverlay,
- @Provided LegacyFlags legacyFlags,
- @Provided MpegTsRendererBuilder.Factory mpegTsRendererBuilderFactory,
- @Provided TsDataSourceManager.Factory tsDataSourceManagerFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
this(
context,
channelDataManager,
tunerSession,
tunerSessionOverlay,
null,
- legacyFlags,
- mpegTsRendererBuilderFactory,
+ concurrentDvrPlaybackFlags,
tsDataSourceManagerFactory);
}
@@ -284,10 +260,9 @@ public class TunerSessionWorker
TunerSession tunerSession,
TunerSessionOverlay tunerSessionOverlay,
@Nullable Handler handler,
- LegacyFlags legacyFlags,
- MpegTsRendererBuilder.Factory mpegTsRendererBuilderFactory,
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
TsDataSourceManager.Factory tsDataSourceManagerFactory) {
- mLegacyFlags = legacyFlags;
+ this.mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
if (DEBUG) Log.d(TAG, "TunerSessionWorker created");
mContext = context;
if (handler != null) {
@@ -302,8 +277,6 @@ public class TunerSessionWorker
mSession = tunerSession;
mTunerSessionOverlay = tunerSessionOverlay;
mChannelDataManager = channelDataManager;
- mMpegTsRendererBuilderFactory = mpegTsRendererBuilderFactory;
- mRecordingUri = null;
mChannelDataManager.setListener(this);
mChannelDataManager.checkDataVersion(mContext);
mSourceManager = tsDataSourceManagerFactory.create(false);
@@ -320,7 +293,8 @@ public class TunerSessionWorker
(CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
mCaptionEnabled = captioningManager.isEnabled();
mPlaybackParams.setSpeed(1.0f);
- mMaxTrickplayBufferSizeMb = DeveloperPreferences.MAX_BUFFER_SIZE_MBYTES.get(context);
+ mMaxTrickplayBufferSizeMb =
+ SystemPropertiesProxy.getInt(MAX_BUFFER_SIZE_KEY, MAX_BUFFER_SIZE_DEF);
mTrickplayModeCustomization = CustomizationManager.getTrickplayMode(context);
if (mTrickplayModeCustomization
== CustomizationManager.TRICKPLAY_MODE_USE_EXTERNAL_STORAGE) {
@@ -513,11 +487,6 @@ public class TunerSessionWorker
// Final status
// notification of STATE_ENDED from MpegTsPlayer will be ignored afterwards.
Log.i(TAG, "Player ended: end of stream");
- if (mOnTuneUsesRecording) {
- mRecordingUri = null;
- mSession.notifyChannelRetuned(mChannelUri);
- sendMessage(MSG_TUNE, mChannelUri);
- }
if (mChannel != null) {
sendMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer));
}
@@ -546,10 +515,10 @@ public class TunerSessionWorker
@Override
public void onVideoSizeChanged(int width, int height, float pixelWidthHeight) {
if (mChannel != null && mChannel.hasVideo()) {
- updateVideoTrack(width, height, pixelWidthHeight);
+ updateVideoTrack(width, height);
}
if (mRecordingId != null) {
- updateVideoTrack(width, height, pixelWidthHeight);
+ updateVideoTrack(width, height);
}
}
@@ -563,9 +532,6 @@ public class TunerSessionWorker
} else {
mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
}
- if (mOnTuneUsesRecording) {
- mBufferStartTimeMs = mRecordStartTimeMs = mRecordedProgramStartTimeMs;
- }
notifyVideoAvailable();
mReportedDrawnToSurface = true;
@@ -621,7 +587,7 @@ public class TunerSessionWorker
// ChannelDataManager.ProgramInfoListener
@Override
public void onProgramsArrived(TunerChannel channel, List<EitItem> programs) {
- sendMessage(MSG_SCHEDULE_OF_PROGRAMS, Pair.create(channel, programs));
+ sendMessage(MSG_SCHEDULE_OF_PROGRAMS, new Pair<>(channel, programs));
}
@Override
@@ -636,7 +602,7 @@ public class TunerSessionWorker
@Override
public void onRequestProgramsResponse(TunerChannel channel, List<EitItem> programs) {
- sendMessage(MSG_PROGRAM_DATA_RESULT, Pair.create(channel, programs));
+ sendMessage(MSG_PROGRAM_DATA_RESULT, new Pair<>(channel, programs));
}
// PlaybackBufferListener
@@ -684,7 +650,7 @@ public class TunerSessionWorker
}
private static class RecordedProgram {
- private final long mChannelId;
+ // private final long mChannelId;
private final String mDataUri;
private final long mStartTimeMillis;
@@ -696,13 +662,14 @@ public class TunerSessionWorker
public RecordedProgram(Cursor cursor) {
int index = 0;
- mChannelId = cursor.getLong(index++);
+ // mChannelId = cursor.getLong(index++);
+ index++;
mDataUri = cursor.getString(index++);
mStartTimeMillis = cursor.getLong(index++);
}
public RecordedProgram(long channelId, String dataUri) {
- mChannelId = channelId;
+ // mChannelId = channelId;
mDataUri = dataUri;
mStartTimeMillis = 0;
}
@@ -722,10 +689,6 @@ public class TunerSessionWorker
public long getStartTime() {
return mStartTimeMillis;
}
-
- public long getChannelId() {
- return mChannelId;
- }
}
private RecordedProgram getRecordedProgram(Uri recordedUri) {
@@ -748,13 +711,9 @@ public class TunerSessionWorker
}
}
- private String parseRecording(Uri uri, long channelId) {
+ private String parseRecording(Uri uri) {
RecordedProgram recording = getRecordedProgram(uri);
if (recording != null) {
- if (channelId != -1 && channelId != recording.getChannelId()) {
- // Recorded URI is of some other channel
- return null;
- }
mRecordedProgramStartTimeMs = recording.getStartTime();
return recording.getDataUri();
}
@@ -867,20 +826,10 @@ public class TunerSessionWorker
mIsActiveSession = true;
}
String recording = null;
- mOnTuneUsesRecording = false;
long channelId = parseChannel(channelUri);
TunerChannel channel = (channelId == -1) ? null : mChannelDataManager.getChannel(channelId);
- mRecordingUri = mSession.getRecordingUri(channelUri);
if (channelId == -1) {
- recording = parseRecording(channelUri, channelId);
-
- } else if (mRecordingUri != null) {
- mChannelUri = channelUri;
- recording = parseRecording(mRecordingUri, channelId);
- if (recording != null) {
- mOnTuneUsesRecording = true;
- channel = null;
- }
+ recording = parseRecording(channelUri);
}
if (channel == null && recording == null) {
Log.w(TAG, "onTune() is failed. Can't find channel for " + channelUri);
@@ -1184,15 +1133,8 @@ public class TunerSessionWorker
if (mPlayer == null) {
return true;
}
- long seekPosMs = timeMs;
- if (mRecordingId != null) {
- long systemBufferTime = System.currentTimeMillis() - SEEK_MARGIN_MS;
- if (seekPosMs > systemBufferTime) {
- seekPosMs = systemBufferTime;
- }
- }
setTrickplayEnabledIfNeeded();
- doTimeShiftSeekTo(seekPosMs);
+ doTimeShiftSeekTo(timeMs);
return true;
}
@@ -1490,7 +1432,8 @@ public class TunerSessionWorker
}
MpegTsPlayer player =
new MpegTsPlayer(
- mMpegTsRendererBuilderFactory.create(mContext, bufferManager, this),
+ new MpegTsRendererBuilder(
+ mContext, bufferManager, this, mConcurrentDvrPlaybackFlags),
mHandler,
mSourceManager,
capabilities,
@@ -1501,7 +1444,7 @@ public class TunerSessionWorker
player.setVideoEventListener(this);
player.setCaptionServiceNumber(
mCaptionTrack != null
- ? mCaptionTrack.getServiceNumber()
+ ? mCaptionTrack.serviceNumber
: Cea708Data.EMPTY_SERVICE_NUMBER);
return player;
}
@@ -1511,7 +1454,7 @@ public class TunerSessionWorker
mTunerSessionOverlay.sendUiMessage(
TunerSessionOverlay.MSG_UI_START_CAPTION_TRACK, mCaptionTrack);
if (mPlayer != null) {
- mPlayer.setCaptionServiceNumber(mCaptionTrack.getServiceNumber());
+ mPlayer.setCaptionServiceNumber(mCaptionTrack.serviceNumber);
}
}
}
@@ -1568,13 +1511,12 @@ public class TunerSessionWorker
}
}
- private void updateVideoTrack(int width, int height, float pixelWidthHeight) {
+ private void updateVideoTrack(int width, int height) {
removeTvTracks(TvTrackInfo.TYPE_VIDEO);
mTvTracks.add(
new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, VIDEO_TRACK_ID)
.setVideoWidth(width)
.setVideoHeight(height)
- .setVideoPixelAspectRatio(pixelWidthHeight)
.build());
mSession.notifyTracksChanged(mTvTracks);
mSession.notifyTrackSelected(TvTrackInfo.TYPE_VIDEO, VIDEO_TRACK_ID);
@@ -1588,7 +1530,7 @@ public class TunerSessionWorker
if (audioTracks != null) {
int index = 0;
for (AtscAudioTrack audioTrack : audioTracks) {
- audioTrack = audioTrack.toBuilder().setIndex(index).build();
+ audioTrack.index = index;
mAudioTrackMap.put(index, audioTrack);
++index;
}
@@ -1618,10 +1560,10 @@ public class TunerSessionWorker
String language =
!TextUtils.isEmpty(infoFromPlayer.language)
? infoFromPlayer.language
- : (infoFromEit != null && infoFromEit.hasLanguage())
- ? infoFromEit.getLanguage()
- : (infoFromVct != null && infoFromVct.hasLanguage())
- ? infoFromVct.getLanguage()
+ : (infoFromEit != null && infoFromEit.language != null)
+ ? infoFromEit.language
+ : (infoFromVct != null && infoFromVct.language != null)
+ ? infoFromVct.language
: null;
TvTrackInfo.Builder builder =
new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, AUDIO_TRACK_PREFIX + i);
@@ -1642,20 +1584,20 @@ public class TunerSessionWorker
mCaptionTrackMap.clear();
if (captionTracks != null) {
for (AtscCaptionTrack captionTrack : captionTracks) {
- if (mCaptionTrackMap.indexOfKey(captionTrack.getServiceNumber()) >= 0) {
+ if (mCaptionTrackMap.indexOfKey(captionTrack.serviceNumber) >= 0) {
continue;
}
- String language = captionTrack.getLanguage();
+ String language = captionTrack.language;
// The service number of the caption service is used for track id of a subtitle.
// Later, when a subtitle is chosen, track id will be passed on to TsParser.
TvTrackInfo.Builder builder =
new TvTrackInfo.Builder(
TvTrackInfo.TYPE_SUBTITLE,
- SUBTITLE_TRACK_PREFIX + captionTrack.getServiceNumber());
+ SUBTITLE_TRACK_PREFIX + captionTrack.serviceNumber);
builder.setLanguage(language);
mTvTracks.add(builder.build());
- mCaptionTrackMap.put(captionTrack.getServiceNumber(), captionTrack);
+ mCaptionTrackMap.put(captionTrack.serviceNumber, captionTrack);
}
}
mSession.notifyTracksChanged(mTvTracks);
@@ -1835,9 +1777,6 @@ public class TunerSessionWorker
} else {
mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
}
- if (mOnTuneUsesRecording) {
- mBufferStartTimeMs = mRecordStartTimeMs = mRecordedProgramStartTimeMs;
- }
mLastPositionMs = 0;
mCaptionTrack = null;
mSignalStrength = TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN;
@@ -1845,14 +1784,6 @@ public class TunerSessionWorker
mSession.notifySignalStrength(mSignalStrength);
}
mHandler.sendEmptyMessage(MSG_PARENTAL_CONTROLS);
- if (mOnTuneUsesRecording) {
- mHandler.obtainMessage(
- MSG_TIMESHIFT_SEEK_TO,
- 1,
- 0,
- System.currentTimeMillis() - SEEK_MARGIN_MS)
- .sendToTarget();
- }
}
private void doReschedulePrograms() {
@@ -1874,7 +1805,7 @@ public class TunerSessionWorker
+ " current program: "
+ getCurrentProgram());
}
- mHandler.obtainMessage(MSG_SCHEDULE_OF_PROGRAMS, Pair.create(mChannel, mPrograms))
+ mHandler.obtainMessage(MSG_SCHEDULE_OF_PROGRAMS, new Pair<>(mChannel, mPrograms))
.sendToTarget();
}
mHandler.removeMessages(MSG_RESCHEDULE_PROGRAMS);
@@ -2035,12 +1966,10 @@ public class TunerSessionWorker
private void doDiscoverCaptionServiceNumber(int serviceNumber) {
int index = mCaptionTrackMap.indexOfKey(serviceNumber);
if (index < 0) {
- AtscCaptionTrack captionTrack =
- AtscCaptionTrack.newBuilder()
- .setServiceNumber(serviceNumber)
- .setWideAspectRatio(false)
- .setEasyReader(false)
- .build();
+ AtscCaptionTrack captionTrack = new AtscCaptionTrack();
+ captionTrack.serviceNumber = serviceNumber;
+ captionTrack.wideAspectRatio = false;
+ captionTrack.easyReader = false;
mCaptionTrackMap.put(serviceNumber, captionTrack);
mTvTracks.add(
new TvTrackInfo.Builder(
@@ -2059,7 +1988,7 @@ public class TunerSessionWorker
ImmutableList<TvContentRating> ratings =
mTvContentRatingCache.getRatings(currentProgram.getContentRating());
if ((ratings == null || ratings.isEmpty())) {
- if (mLegacyFlags.enableUnratedContentSettings()) {
+ if (Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get()) {
ratings = ImmutableList.of(TvContentRating.UNRATED);
} else {
ratings = NO_CONTENT_RATINGS;
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
index f56e4879..82afff15 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
@@ -44,22 +44,22 @@ import android.util.Pair;
import android.util.SparseArray;
import android.view.Surface;
import android.view.accessibility.CaptioningManager;
-
import com.android.tv.common.CommonPreferences.TrickplaySetting;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.compat.TvInputConstantCompat;
import com.android.tv.common.customization.CustomizationManager;
import com.android.tv.common.customization.CustomizationManager.TRICKPLAY_MODE;
-import com.android.tv.common.dev.DeveloperPreferences;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.util.SystemPropertiesProxy;
import com.android.tv.tuner.data.Cea708Data;
-import com.android.tv.tuner.data.Channel;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.PsipData.TvTracksInterface;
-import com.android.tv.tuner.data.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.MpegTsPlayer;
import com.android.tv.tuner.exoplayer.MpegTsRendererBuilder;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
@@ -74,15 +74,10 @@ import com.android.tv.tuner.ts.EventDetector.EventListener;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
import com.android.tv.tuner.tvinput.debug.TunerDebug;
import com.android.tv.tuner.util.StatusTextUtils;
-
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
import com.google.common.collect.ImmutableList;
-
-import com.android.tv.common.flags.LegacyFlags;
-
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
@@ -105,6 +100,8 @@ public class TunerSessionWorkerExoV2
private static final boolean DEBUG = false;
private static final boolean ENABLE_PROFILER = true;
private static final String PLAY_FROM_CHANNEL = "channel";
+ private static final String MAX_BUFFER_SIZE_KEY = "tv.tuner.buffersize_mbytes";
+ private static final int MAX_BUFFER_SIZE_DEF = 2 * 1024; // 2GB
private static final int MIN_BUFFER_SIZE_DEF = 256; // 256MB
// Public messages
@@ -191,7 +188,6 @@ public class TunerSessionWorkerExoV2
private final int mMaxTrickplayBufferSizeMb;
private final File mTrickplayBufferDir;
private final @TRICKPLAY_MODE int mTrickplayModeCustomization;
- private final MpegTsRendererBuilder.Factory mMpegTsRendererBuilderFactory;
private volatile Surface mSurface;
private volatile float mVolume = 1.0f;
private volatile boolean mCaptionEnabled;
@@ -234,45 +230,25 @@ public class TunerSessionWorkerExoV2
private boolean mIsActiveSession;
private boolean mReleaseRequested; // Guarded by mReleaseLock
private final Object mReleaseLock = new Object();
- private final LegacyFlags mLegacyFlags;
- private Uri mChannelUri;
- private Uri mRecordingUri;
- private boolean mOnTuneUsesRecording = false;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private int mSignalStrength;
private long mRecordedProgramStartTimeMs;
- /**
- * Factory for {@link TunerSessionWorkerExoV2}.
- *
- * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
- * generated class.
- */
- public interface Factory {
- public TunerSessionWorkerExoV2 create(
- Context context,
- ChannelDataManager channelDataManager,
- TunerSessionExoV2 tunerSession,
- TunerSessionOverlay tunerSessionOverlay);
- }
-
- @AutoFactory(implementing = Factory.class)
public TunerSessionWorkerExoV2(
Context context,
ChannelDataManager channelDataManager,
TunerSessionExoV2 tunerSession,
TunerSessionOverlay tunerSessionOverlay,
- @Provided LegacyFlags legacyFlags,
- @Provided MpegTsRendererBuilder.Factory mpegTsRendererBuilderFactory,
- @Provided TsDataSourceManager.Factory tsDataSourceManagerFactory) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
this(
context,
channelDataManager,
tunerSession,
tunerSessionOverlay,
null,
- legacyFlags,
- mpegTsRendererBuilderFactory,
+ concurrentDvrPlaybackFlags,
tsDataSourceManagerFactory);
}
@@ -283,10 +259,9 @@ public class TunerSessionWorkerExoV2
TunerSessionExoV2 tunerSession,
TunerSessionOverlay tunerSessionOverlay,
@Nullable Handler handler,
- LegacyFlags legacyFlags,
- MpegTsRendererBuilder.Factory mpegTsRendererBuilderFactory,
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
TsDataSourceManager.Factory tsDataSourceManagerFactory) {
- mLegacyFlags = legacyFlags;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
if (DEBUG) {
Log.d(TAG, "TunerSessionWorkerExoV2 created");
}
@@ -303,8 +278,6 @@ public class TunerSessionWorkerExoV2
mSession = tunerSession;
mTunerSessionOverlay = tunerSessionOverlay;
mChannelDataManager = channelDataManager;
- mMpegTsRendererBuilderFactory = mpegTsRendererBuilderFactory;
- mRecordingUri = null;
mChannelDataManager.setListener(this);
mChannelDataManager.checkDataVersion(mContext);
mSourceManager = tsDataSourceManagerFactory.create(false);
@@ -321,7 +294,8 @@ public class TunerSessionWorkerExoV2
(CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
mCaptionEnabled = captioningManager.isEnabled();
mPlaybackParams.setSpeed(1.0f);
- mMaxTrickplayBufferSizeMb = DeveloperPreferences.MAX_BUFFER_SIZE_MBYTES.get(context);
+ mMaxTrickplayBufferSizeMb =
+ SystemPropertiesProxy.getInt(MAX_BUFFER_SIZE_KEY, MAX_BUFFER_SIZE_DEF);
mTrickplayModeCustomization = CustomizationManager.getTrickplayMode(context);
if (mTrickplayModeCustomization
== CustomizationManager.TRICKPLAY_MODE_USE_EXTERNAL_STORAGE) {
@@ -519,11 +493,6 @@ public class TunerSessionWorkerExoV2
// Final status
// notification of STATE_ENDED from MpegTsPlayer will be ignored afterwards.
Log.i(TAG, "Player ended: end of stream");
- if (mOnTuneUsesRecording) {
- mRecordingUri = null;
- mSession.notifyChannelRetuned(mChannelUri);
- sendMessage(MSG_TUNE, mChannelUri);
- }
if (mChannel != null) {
sendMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer));
}
@@ -552,10 +521,10 @@ public class TunerSessionWorkerExoV2
@Override
public void onVideoSizeChanged(int width, int height, float pixelWidthHeight) {
if (mChannel != null && mChannel.hasVideo()) {
- updateVideoTrack(width, height, pixelWidthHeight);
+ updateVideoTrack(width, height);
}
if (mRecordingId != null) {
- updateVideoTrack(width, height, pixelWidthHeight);
+ updateVideoTrack(width, height);
}
}
@@ -571,9 +540,6 @@ public class TunerSessionWorkerExoV2
} else {
mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
}
- if (mOnTuneUsesRecording) {
- mBufferStartTimeMs = mRecordStartTimeMs = mRecordedProgramStartTimeMs;
- }
notifyVideoAvailable();
mReportedDrawnToSurface = true;
@@ -629,7 +595,7 @@ public class TunerSessionWorkerExoV2
// ChannelDataManager.ProgramInfoListener
@Override
public void onProgramsArrived(TunerChannel channel, List<EitItem> programs) {
- sendMessage(MSG_SCHEDULE_OF_PROGRAMS, Pair.create(channel, programs));
+ sendMessage(MSG_SCHEDULE_OF_PROGRAMS, new Pair<>(channel, programs));
}
@Override
@@ -644,7 +610,7 @@ public class TunerSessionWorkerExoV2
@Override
public void onRequestProgramsResponse(TunerChannel channel, List<EitItem> programs) {
- sendMessage(MSG_PROGRAM_DATA_RESULT, Pair.create(channel, programs));
+ sendMessage(MSG_PROGRAM_DATA_RESULT, new Pair<>(channel, programs));
}
// PlaybackBufferListener
@@ -692,7 +658,7 @@ public class TunerSessionWorkerExoV2
}
private static class RecordedProgram {
- private final long mChannelId;
+ // private final long mChannelId;
private final String mDataUri;
private final long mStartTimeMillis;
@@ -704,13 +670,14 @@ public class TunerSessionWorkerExoV2
public RecordedProgram(Cursor cursor) {
int index = 0;
- mChannelId = cursor.getLong(index++);
+ // mChannelId = cursor.getLong(index++);
+ index++;
mDataUri = cursor.getString(index++);
mStartTimeMillis = cursor.getLong(index++);
}
public RecordedProgram(long channelId, String dataUri) {
- mChannelId = channelId;
+ // mChannelId = channelId;
mDataUri = dataUri;
mStartTimeMillis = 0;
}
@@ -730,10 +697,6 @@ public class TunerSessionWorkerExoV2
public long getStartTime() {
return mStartTimeMillis;
}
-
- public long getChannelId() {
- return mChannelId;
- }
}
private RecordedProgram getRecordedProgram(Uri recordedUri) {
@@ -758,13 +721,9 @@ public class TunerSessionWorkerExoV2
}
}
- private String parseRecording(Uri uri, long channelId) {
+ private String parseRecording(Uri uri) {
RecordedProgram recording = getRecordedProgram(uri);
if (recording != null) {
- if (channelId != -1 && channelId != recording.getChannelId()) {
- // Recorded URI is of some other channel
- return null;
- }
mRecordedProgramStartTimeMs = recording.getStartTime();
return recording.getDataUri();
}
@@ -877,19 +836,10 @@ public class TunerSessionWorkerExoV2
mIsActiveSession = true;
}
String recording = null;
- mOnTuneUsesRecording = false;
long channelId = parseChannel(channelUri);
TunerChannel channel = (channelId == -1) ? null : mChannelDataManager.getChannel(channelId);
- mRecordingUri = mSession.getRecordingUri(channelUri);
if (channelId == -1) {
- recording = parseRecording(channelUri, channelId);
- } else if (mRecordingUri != null) {
- mChannelUri = channelUri;
- recording = parseRecording(mRecordingUri, channelId);
- if (recording != null) {
- mOnTuneUsesRecording = true;
- channel = null;
- }
+ recording = parseRecording(channelUri);
}
if (channel == null && recording == null) {
Log.w(TAG, "onTune() is failed. Can't find channel for " + channelUri);
@@ -1492,7 +1442,8 @@ public class TunerSessionWorkerExoV2
}
MpegTsPlayer player =
new MpegTsPlayer(
- mMpegTsRendererBuilderFactory.create(mContext, bufferManager, this),
+ new MpegTsRendererBuilder(
+ mContext, bufferManager, this, mConcurrentDvrPlaybackFlags),
mHandler,
mSourceManager,
capabilities,
@@ -1505,7 +1456,7 @@ public class TunerSessionWorkerExoV2
player.setVideoEventListener(this);
player.setCaptionServiceNumber(
mCaptionTrack != null
- ? mCaptionTrack.getServiceNumber()
+ ? mCaptionTrack.serviceNumber
: Cea708Data.EMPTY_SERVICE_NUMBER);
return player;
}
@@ -1515,7 +1466,7 @@ public class TunerSessionWorkerExoV2
mTunerSessionOverlay.sendUiMessage(
TunerSessionOverlay.MSG_UI_START_CAPTION_TRACK, mCaptionTrack);
if (mPlayer != null) {
- mPlayer.setCaptionServiceNumber(mCaptionTrack.getServiceNumber());
+ mPlayer.setCaptionServiceNumber(mCaptionTrack.serviceNumber);
}
}
}
@@ -1572,13 +1523,12 @@ public class TunerSessionWorkerExoV2
}
}
- private void updateVideoTrack(int width, int height, float pixelWidthHeight) {
+ private void updateVideoTrack(int width, int height) {
removeTvTracks(TvTrackInfo.TYPE_VIDEO);
mTvTracks.add(
new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, VIDEO_TRACK_ID)
.setVideoWidth(width)
.setVideoHeight(height)
- .setVideoPixelAspectRatio(pixelWidthHeight)
.build());
mSession.notifyTracksChanged(mTvTracks);
mSession.notifyTrackSelected(TvTrackInfo.TYPE_VIDEO, VIDEO_TRACK_ID);
@@ -1592,7 +1542,7 @@ public class TunerSessionWorkerExoV2
if (audioTracks != null) {
int index = 0;
for (AtscAudioTrack audioTrack : audioTracks) {
- audioTrack = audioTrack.toBuilder().setIndex(index).build();
+ audioTrack.index = index;
mAudioTrackMap.put(index, audioTrack);
++index;
}
@@ -1622,10 +1572,10 @@ public class TunerSessionWorkerExoV2
String language =
!TextUtils.isEmpty(infoFromPlayer.language)
? infoFromPlayer.language
- : (infoFromEit != null && infoFromEit.hasLanguage())
- ? infoFromEit.getLanguage()
- : (infoFromVct != null && infoFromVct.hasLanguage())
- ? infoFromVct.getLanguage()
+ : (infoFromEit != null && infoFromEit.language != null)
+ ? infoFromEit.language
+ : (infoFromVct != null && infoFromVct.language != null)
+ ? infoFromVct.language
: null;
TvTrackInfo.Builder builder =
new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, AUDIO_TRACK_PREFIX + i);
@@ -1646,20 +1596,20 @@ public class TunerSessionWorkerExoV2
mCaptionTrackMap.clear();
if (captionTracks != null) {
for (AtscCaptionTrack captionTrack : captionTracks) {
- if (mCaptionTrackMap.indexOfKey(captionTrack.getServiceNumber()) >= 0) {
+ if (mCaptionTrackMap.indexOfKey(captionTrack.serviceNumber) >= 0) {
continue;
}
- String language = captionTrack.getLanguage();
+ String language = captionTrack.language;
// The service number of the caption service is used for track id of a subtitle.
// Later, when a subtitle is chosen, track id will be passed on to TsParser.
TvTrackInfo.Builder builder =
new TvTrackInfo.Builder(
TvTrackInfo.TYPE_SUBTITLE,
- SUBTITLE_TRACK_PREFIX + captionTrack.getServiceNumber());
+ SUBTITLE_TRACK_PREFIX + captionTrack.serviceNumber);
builder.setLanguage(language);
mTvTracks.add(builder.build());
- mCaptionTrackMap.put(captionTrack.getServiceNumber(), captionTrack);
+ mCaptionTrackMap.put(captionTrack.serviceNumber, captionTrack);
}
}
mSession.notifyTracksChanged(mTvTracks);
@@ -1841,9 +1791,6 @@ public class TunerSessionWorkerExoV2
} else {
mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
}
- if (mOnTuneUsesRecording) {
- mBufferStartTimeMs = mRecordStartTimeMs = mRecordedProgramStartTimeMs;
- }
mLastPositionMs = 0;
mCaptionTrack = null;
mSignalStrength = TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN;
@@ -1851,14 +1798,6 @@ public class TunerSessionWorkerExoV2
mSession.notifySignalStrength(mSignalStrength);
}
mHandler.sendEmptyMessage(MSG_PARENTAL_CONTROLS);
- if (mOnTuneUsesRecording) {
- mHandler.obtainMessage(
- MSG_TIMESHIFT_SEEK_TO,
- 1,
- 0,
- System.currentTimeMillis() - SEEK_MARGIN_MS)
- .sendToTarget();
- }
}
private void doReschedulePrograms() {
@@ -1880,7 +1819,7 @@ public class TunerSessionWorkerExoV2
+ " current program: "
+ getCurrentProgram());
}
- mHandler.obtainMessage(MSG_SCHEDULE_OF_PROGRAMS, Pair.create(mChannel, mPrograms))
+ mHandler.obtainMessage(MSG_SCHEDULE_OF_PROGRAMS, new Pair<>(mChannel, mPrograms))
.sendToTarget();
}
mHandler.removeMessages(MSG_RESCHEDULE_PROGRAMS);
@@ -2041,13 +1980,10 @@ public class TunerSessionWorkerExoV2
private void doDiscoverCaptionServiceNumber(int serviceNumber) {
int index = mCaptionTrackMap.indexOfKey(serviceNumber);
if (index < 0) {
- AtscCaptionTrack.Builder captionTrackBuilder = AtscCaptionTrack.newBuilder();
- AtscCaptionTrack captionTrack =
- captionTrackBuilder
- .setServiceNumber(serviceNumber)
- .setWideAspectRatio(false)
- .setEasyReader(false)
- .build();
+ AtscCaptionTrack captionTrack = new AtscCaptionTrack();
+ captionTrack.serviceNumber = serviceNumber;
+ captionTrack.wideAspectRatio = false;
+ captionTrack.easyReader = false;
mCaptionTrackMap.put(serviceNumber, captionTrack);
mTvTracks.add(
new TvTrackInfo.Builder(
@@ -2066,7 +2002,7 @@ public class TunerSessionWorkerExoV2
ImmutableList<TvContentRating> ratings =
mTvContentRatingCache.getRatings(currentProgram.getContentRating());
if ((ratings == null || ratings.isEmpty())) {
- if (mLegacyFlags.enableUnratedContentSettings()) {
+ if (Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get()) {
ratings = ImmutableList.of(TvContentRating.UNRATED);
} else {
ratings = NO_CONTENT_RATINGS;
diff --git a/tuner/src/com/android/tv/tuner/tvinput/datamanager/ChannelDataManager.java b/tuner/src/com/android/tv/tuner/tvinput/datamanager/ChannelDataManager.java
index 447618a4..585b28bc 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/datamanager/ChannelDataManager.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/datamanager/ChannelDataManager.java
@@ -29,10 +29,11 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.format.DateUtils;
import android.util.Log;
+import com.android.tv.common.singletons.HasSingletons;
+import com.android.tv.common.singletons.HasTvInputId;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.TunerChannel;
@@ -50,7 +51,7 @@ import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-/** Manages the channel info and EPG data for a specific inputId. */
+/** Manages the channel info and EPG data through {@link TvInputManager}. */
public class ChannelDataManager implements Handler.Callback {
private static final String TAG = "ChannelDataManager";
@@ -145,9 +146,9 @@ public class ChannelDataManager implements Handler.Callback {
void onChannelHandlingDone();
}
- public ChannelDataManager(Context context, String inputId) {
+ public ChannelDataManager(Context context) {
mContext = context;
- mInputId = inputId;
+ mInputId = HasSingletons.get(HasTvInputId.class, context).getEmbeddedTunerInputId();
mChannelsUri = TvContract.buildChannelsUriForInput(mInputId);
mTunerChannelMap = new ConcurrentHashMap<>();
mTunerChannelIdMap = new ConcurrentSkipListMap<>();
@@ -381,12 +382,6 @@ public class ChannelDataManager implements Handler.Callback {
return false;
}
- @NonNull
- @Override
- public String toString() {
- return "ChannelDataManager[" + mInputId + "]";
- }
-
// Private methods
private void handleEvents(TunerChannel channel, List<EitItem> items) {
long channelId = getChannelId(channel);
diff --git a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerRecordingSessionFactory.java b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerRecordingSessionFactory.java
deleted file mode 100644
index c5950756..00000000
--- a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerRecordingSessionFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.tvinput.factory;
-
-import android.media.tv.TvInputService.RecordingSession;
-
-import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-
-/** {@link RecordingSession} factory */
-public interface TunerRecordingSessionFactory {
-
- /** Called when a recording session is released */
- interface RecordingSessionReleasedCallback {
-
- /**
- * Called when the given recording session is released.
- *
- * @param session The recording session that has been released.
- */
- void onReleased(RecordingSession session);
- }
-
- RecordingSession create(
- String inputId,
- RecordingSessionReleasedCallback releasedCallback,
- ChannelDataManager channelDataManager);
-}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java
index e22562ac..a27cb22a 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java
@@ -1,24 +1,7 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package com.android.tv.tuner.tvinput.factory;
+import android.content.Context;
import android.media.tv.TvInputService.Session;
-import android.net.Uri;
-
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
/** {@link android.media.tv.TvInputService.Session} factory */
@@ -35,19 +18,8 @@ public interface TunerSessionFactory {
void onReleased(Session session);
}
- /** Called when recording URI is required for playback */
- interface SessionRecordingCallback {
-
- /**
- * Called when recording URI is required for playback.
- *
- * @param channelUri for which recording URI is requested.
- */
- Uri getRecordingUri(Uri channelUri);
- }
-
Session create(
+ Context context,
ChannelDataManager channelDataManager,
- SessionReleasedCallback releasedCallback,
- SessionRecordingCallback recordingCallback);
+ SessionReleasedCallback releasedCallback);
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java
new file mode 100644
index 00000000..54e959e6
--- /dev/null
+++ b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java
@@ -0,0 +1,49 @@
+package com.android.tv.tuner.tvinput.factory;
+
+import android.content.Context;
+import android.media.tv.TvInputService.Session;
+import com.android.tv.tuner.source.TsDataSourceManager;
+import com.android.tv.tuner.tvinput.TunerSession;
+import com.android.tv.tuner.tvinput.TunerSessionExoV2;
+import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
+import com.android.tv.common.flags.TunerFlags;
+import javax.inject.Inject;
+
+/** Creates a {@link TunerSessionFactory}. */
+public class TunerSessionFactoryImpl implements TunerSessionFactory {
+
+ private final TunerFlags mTunerFlags;
+ private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ private final TsDataSourceManager.Factory mTsDataSourceManagerFactory;
+
+ @Inject
+ public TunerSessionFactoryImpl(
+ TunerFlags tunerFlags,
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
+ mTunerFlags = tunerFlags;
+ mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
+ mTsDataSourceManagerFactory = tsDataSourceManagerFactory;
+ }
+
+ @Override
+ public Session create(
+ Context context,
+ ChannelDataManager channelDataManager,
+ SessionReleasedCallback releasedCallback) {
+ return mTunerFlags.useExoplayerV2()
+ ? new TunerSessionExoV2(
+ context,
+ channelDataManager,
+ releasedCallback,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory)
+ : new TunerSession(
+ context,
+ channelDataManager,
+ releasedCallback,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
+ }
+}
diff --git a/tuner/tests/robotests/Android.mk b/tuner/tests/robotests/Android.mk
deleted file mode 100644
index 16af9e9c..00000000
--- a/tuner/tests/robotests/Android.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-#############################################################
-# Tv Robolectric test target. #
-#############################################################
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := TvTunerRoboTests
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-
-LOCAL_SRC_FILES := $(call all-java-files-under, javatests)
-
-LOCAL_JAVA_LIBRARIES := \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- robolectric_android-all-stub \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- tv-lib-dagger
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- androidx.test.core \
- tv-lib-dagger-android \
- tv-test-common \
- tv-test-common-robo \
- tv-tuner-testing \
-
-LOCAL_ANNOTATION_PROCESSORS := \
- tv-lib-dagger-android-processor \
- tv-lib-dagger-compiler \
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := \
- dagger.internal.codegen.ComponentProcessor,dagger.android.processor.AndroidProcessor
-
-LOCAL_INSTRUMENTATION_FOR := LiveTv
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-#############################################################
-# Tv runner target to run the previous target. #
-#############################################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := RunTvTunerRoboTests
-
-BASE_DIR = com/android/tv/tuner
-EXCLUDE_FILES := \
- $(BASE_DIR)/dvb/DvbTunerHalTest.java \
- $(BASE_DIR)/exoplayer/tests/SampleSourceExtractorTest.java \
-
-LOCAL_ROBOTEST_FILES := $(call find-files-in-subdirs,$(LOCAL_PATH)/javatests,*Test.java,.)
-LOCAL_ROBOTEST_FILES := $(filter-out $(EXCLUDE_FILES),$(LOCAL_ROBOTEST_FILES))
-
-LOCAL_JAVA_LIBRARIES := \
- Robolectric_all-target \
- TvTunerRoboTests \
- mockito-robolectric-prebuilt \
- robolectric_android-all-stub \
- tv-lib-truth \
- tv-test-common \
- tv-test-common-robo \
- tv-tuner-testing \
-
-LOCAL_TEST_PACKAGE := LiveTv
-
-LOCAL_ROBOTEST_TIMEOUT := 36000
-
-include external/robolectric-shadows/run_robotests.mk
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/data/SectionParserTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/data/SectionParserTest.java
deleted file mode 100644
index e40abdc4..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/data/SectionParserTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.data;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.data.PsipData.ContentAdvisoryDescriptor;
-import com.android.tv.tuner.data.PsipData.RatingRegion;
-import com.android.tv.tuner.data.PsipData.RegionalRating;
-import com.android.tv.tuner.data.PsipData.TsDescriptor;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Tests for {@link com.android.tv.tuner.data.SectionParser}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SectionParserTest {
- private static final Map<String, String> US_RATING_MAP = new HashMap<>();
- private static final int RATING_REGION_US = 1;
-
- static {
- // These mappings are from table 3 of ANSI-CEA-766-D
- US_RATING_MAP.put("1 0 0 0 0 0 0 X", ""); // TV-None
- US_RATING_MAP.put("0 0 0 0 0 1 0 X", "com.android.tv/US_TV/US_TV_Y");
- US_RATING_MAP.put("0 0 0 0 0 2 0 X", "com.android.tv/US_TV/US_TV_Y7");
- US_RATING_MAP.put("0 0 0 0 0 2 1 X", "com.android.tv/US_TV/US_TV_Y7/US_TV_FV");
- US_RATING_MAP.put("2 0 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_G");
- US_RATING_MAP.put("3 0 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_PG");
- US_RATING_MAP.put("3 1 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D");
- US_RATING_MAP.put("3 0 1 0 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_L");
- US_RATING_MAP.put("3 0 0 1 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_S");
- US_RATING_MAP.put("3 0 0 0 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_V");
- US_RATING_MAP.put("3 1 1 0 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_L");
- US_RATING_MAP.put("3 1 0 1 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_S");
- US_RATING_MAP.put("3 1 0 0 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_V");
- US_RATING_MAP.put("3 0 1 1 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_L/US_TV_S");
- US_RATING_MAP.put("3 0 1 0 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_L/US_TV_V");
- US_RATING_MAP.put("3 0 0 1 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "3 1 1 1 0 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_L/US_TV_S");
- US_RATING_MAP.put(
- "3 1 1 0 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_L/US_TV_V");
- US_RATING_MAP.put(
- "3 1 0 1 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "3 0 1 1 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_L/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "3 1 1 1 1 0 0 X", "com.android.tv/US_TV/US_TV_PG/US_TV_D/US_TV_L/US_TV_S/US_TV_V");
- US_RATING_MAP.put("4 0 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_14");
- US_RATING_MAP.put("4 1 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D");
- US_RATING_MAP.put("4 0 1 0 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_L");
- US_RATING_MAP.put("4 0 0 1 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_S");
- US_RATING_MAP.put("4 0 0 0 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_V");
- US_RATING_MAP.put("4 1 1 0 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_L");
- US_RATING_MAP.put("4 1 0 1 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_S");
- US_RATING_MAP.put("4 1 0 0 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_V");
- US_RATING_MAP.put("4 0 1 1 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_L/US_TV_S");
- US_RATING_MAP.put("4 0 1 0 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_L/US_TV_V");
- US_RATING_MAP.put("4 0 0 1 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "4 1 1 1 0 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_L/US_TV_S");
- US_RATING_MAP.put(
- "4 1 1 0 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_L/US_TV_V");
- US_RATING_MAP.put(
- "4 1 0 1 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "4 0 1 1 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_L/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "4 1 1 1 1 0 0 X", "com.android.tv/US_TV/US_TV_14/US_TV_D/US_TV_L/US_TV_S/US_TV_V");
- US_RATING_MAP.put("5 0 0 0 0 0 0 X", "com.android.tv/US_TV/US_TV_MA");
- US_RATING_MAP.put("5 0 1 0 0 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_L");
- US_RATING_MAP.put("5 0 0 1 0 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_S");
- US_RATING_MAP.put("5 0 0 0 1 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_V");
- US_RATING_MAP.put("5 0 1 1 0 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_L/US_TV_S");
- US_RATING_MAP.put("5 0 1 0 1 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_L/US_TV_V");
- US_RATING_MAP.put("5 0 0 1 1 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_S/US_TV_V");
- US_RATING_MAP.put(
- "5 0 1 1 1 0 0 X", "com.android.tv/US_TV/US_TV_MA/US_TV_L/US_TV_S/US_TV_V");
- US_RATING_MAP.put("X X X X X X X 1", ""); // MPAA-N/A
- US_RATING_MAP.put("X X X X X X X 2", "com.android.tv/US_MV/US_MV_G");
- US_RATING_MAP.put("X X X X X X X 3", "com.android.tv/US_MV/US_MV_PG");
- US_RATING_MAP.put("X X X X X X X 4", "com.android.tv/US_MV/US_MV_PG13");
- US_RATING_MAP.put("X X X X X X X 5", "com.android.tv/US_MV/US_MV_R");
- US_RATING_MAP.put("X X X X X X X 6", "com.android.tv/US_MV/US_MV_NC17");
- // MPAA-X was replaced by NC17
- US_RATING_MAP.put("X X X X X X X 7", "com.android.tv/US_MV/US_MV_NC17");
- US_RATING_MAP.put("X X X X X X X 8", ""); // MPAA - Not Rated
- }
-
- @Test
- public void testGenerateContentRating_emptyInput() {
- assertThat(SectionParser.generateContentRating(new ArrayList<TsDescriptor>())).isEmpty();
- }
-
- @Test
- public void testGenerateContentRating_validInputs() {
- for (Map.Entry<String, String> entry : US_RATING_MAP.entrySet()) {
- RatingRegion ratingRegion = createRatingRegionForTest(entry.getKey(), RATING_REGION_US);
- ContentAdvisoryDescriptor descriptor = createDescriptorForTest(ratingRegion);
- assertWithMessage("key = " + entry.getKey())
- .that(
- SectionParser.generateContentRating(
- Collections.singletonList((TsDescriptor) descriptor)))
- .isEqualTo(entry.getValue());
- }
- }
-
- @Test
- public void testGenerateContentRating_invalidInput() {
- // Invalid because the value of the first dimension is lost.
- RatingRegion ratingRegion = createRatingRegionForTest("X 1 0 0 0 0 0 X", RATING_REGION_US);
- ContentAdvisoryDescriptor descriptor = createDescriptorForTest(ratingRegion);
- assertThat(
- SectionParser.generateContentRating(
- Collections.singletonList((TsDescriptor) descriptor)))
- .isEmpty();
- }
-
- @Test
- public void testGenerateContentRating_multipleRatings() {
- // TV-MA
- RatingRegion ratingRegionTv =
- createRatingRegionForTest("5 0 0 0 0 0 0 X", RATING_REGION_US);
- // MPAA-R
- RatingRegion ratingRegionMv =
- createRatingRegionForTest("X X X X X X X 5", RATING_REGION_US);
- ContentAdvisoryDescriptor descriptorTv = createDescriptorForTest(ratingRegionTv);
- ContentAdvisoryDescriptor descriptorMv = createDescriptorForTest(ratingRegionMv);
- assertThat(
- SectionParser.generateContentRating(
- Arrays.<TsDescriptor>asList(descriptorTv, descriptorMv)))
- .isEqualTo("com.android.tv/US_MV/US_MV_R,com.android.tv/US_TV/US_TV_MA");
- }
-
- private static RatingRegion createRatingRegionForTest(String values, int region) {
- String[] valueArray = values.split(" ");
- List<RegionalRating> regionalRatings = new ArrayList<>();
- for (int i = 0; i < valueArray.length; i++) {
- try {
- int value = Integer.valueOf(valueArray[i]);
- if (value != 0) {
- // value 0 means the dimension should be omitted from the descriptor
- regionalRatings.add(new RegionalRating(i, value));
- }
- } catch (NumberFormatException e) {
- // do nothing
- }
- }
- return new RatingRegion(region, "", regionalRatings);
- }
-
- private static ContentAdvisoryDescriptor createDescriptorForTest(RatingRegion... regions) {
- return new ContentAdvisoryDescriptor(Arrays.asList(regions));
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/dvb/DvbTunerHalTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/dvb/DvbTunerHalTest.java
deleted file mode 100644
index 13fb06a3..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/dvb/DvbTunerHalTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.dvb;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.common.compat.TvInputConstantCompat;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.tvinput.TunerSessionWorker;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-/** Tests for {@link TunerSessionWorker}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class DvbTunerHalTest {
- private int mSignal = 0;
-
- DvbTunerHal mDvbTunerHal =
- new DvbTunerHal(RuntimeEnvironment.application) {
- @Override
- protected int nativeGetSignalStrength(long deviceId) {
- return mSignal;
- }
- };
-
- @Test
- public void getSignalStrength_notUsed() {
- mSignal = -3;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED);
- }
-
- @Test
- public void getSignalStrength_errorMax() {
- mSignal = Integer.MAX_VALUE;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR);
- }
-
- @Test
- public void getSignalStrength_errorMin() {
- mSignal = Integer.MIN_VALUE;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR);
- }
-
- @Test
- public void getSignalStrength_error() {
- mSignal = -1;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR);
- }
-
- @Test
- public void getSignalStrength_curvedMax() {
- mSignal = 65535;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(100);
- }
-
- @Test
- public void getSignalStrength_curvedHalf() {
- mSignal = 58982;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(50);
- }
-
- @Test
- public void getSignalStrength_curvedMin() {
- mSignal = 0;
- int signal = mDvbTunerHal.getSignalStrength();
- assertThat(signal).isEqualTo(0);
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/AssetDataSource.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/AssetDataSource.java
deleted file mode 100644
index 52faa1d2..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/AssetDataSource.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.exoplayer.tests;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.net.Uri;
-import com.google.android.exoplayer.C;
-import com.google.android.exoplayer2.upstream.DataSource;
-import com.google.android.exoplayer2.upstream.DataSpec;
-import com.google.android.exoplayer2.upstream.TransferListener;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** A local asset. */
-// Copied from com.google.android.exoplayer.upstream.AssetDataSource for test.
-final class AssetDataSource implements DataSource {
- /** Thrown when an {@link IOException} is encountered reading a local asset. */
- private static final class AssetDataSourceException extends IOException {
- private AssetDataSourceException(IOException cause) {
- super(cause);
- }
- }
-
- private final AssetManager mAssetManager;
-
- private InputStream mInputStream;
- private long mBytesRemaining;
- private Uri mUri;
-
- /** Constructs a new {@link DataSource} that retrieves data from a local asset. */
- AssetDataSource(Context context) {
- mAssetManager = context.getAssets();
- }
-
- @Override
- public long open(DataSpec dataSpec) throws AssetDataSourceException {
- try {
- String path = dataSpec.uri.getPath();
- if (path.startsWith("/android_asset/")) {
- path = path.substring(15);
- } else if (path.startsWith("/")) {
- path = path.substring(1);
- }
- mInputStream = mAssetManager.open(path, AssetManager.ACCESS_RANDOM);
- long skipped = mInputStream.skip(dataSpec.position);
- if (skipped < dataSpec.position) {
- // mAssetManager.open() returns an AssetInputStream, whose skip() implementation
- // only skips fewer bytes than requested if the skip is beyond the end of the
- // asset's data.
- throw new EOFException();
- }
- if (dataSpec.length != C.LENGTH_UNBOUNDED) {
- mBytesRemaining = dataSpec.length;
- } else {
- mBytesRemaining = mInputStream.available();
- if (mBytesRemaining == Integer.MAX_VALUE) {
- // mAssetManager.open() returns an AssetInputStream, whose available()
- // implementation returns Integer.MAX_VALUE if the remaining length is greater
- // than (or equal to) Integer.MAX_VALUE. We don't know the true length in this
- // case, so treat as unbounded.
- mBytesRemaining = C.LENGTH_UNBOUNDED;
- }
- }
- } catch (IOException e) {
- throw new AssetDataSourceException(e);
- }
-
- mUri = dataSpec.uri;
- return mBytesRemaining;
- }
-
- @Override
- public int read(byte[] buffer, int offset, int readLength) throws AssetDataSourceException {
- if (mBytesRemaining == 0) {
- return -1;
- } else {
- int bytesRead = 0;
- try {
- int bytesToRead =
- mBytesRemaining == C.LENGTH_UNBOUNDED
- ? readLength
- : (int) Math.min(mBytesRemaining, readLength);
- bytesRead = mInputStream.read(buffer, offset, bytesToRead);
- } catch (IOException e) {
- throw new AssetDataSourceException(e);
- }
-
- if (bytesRead > 0 && mBytesRemaining != C.LENGTH_UNBOUNDED) {
- mBytesRemaining -= bytesRead;
- }
-
- return bytesRead;
- }
- }
-
- @Override
- public void close() throws AssetDataSourceException {
- mUri = null;
- if (mInputStream != null) {
- try {
- mInputStream.close();
- } catch (IOException e) {
- throw new AssetDataSourceException(e);
- } finally {
- mInputStream = null;
- }
- }
- }
-
- @Override
- public void addTransferListener(TransferListener transferListener) {
- // TODO: Implement to support metrics collection.
- }
-
- @Override
- public Uri getUri() {
- return mUri;
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/SampleSourceExtractorTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/SampleSourceExtractorTest.java
deleted file mode 100644
index 5af30b93..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/exoplayer/tests/SampleSourceExtractorTest.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.exoplayer.tests;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static junit.framework.Assert.fail;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.util.Pair;
-
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractor;
-import com.android.tv.tuner.exoplayer.buffer.BufferManager;
-import com.android.tv.tuner.exoplayer.buffer.BufferManager.StorageManager;
-import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
-import com.android.tv.tuner.exoplayer.buffer.SampleChunk;
-import com.android.tv.tuner.testing.buffer.VerySlowSampleChunk;
-
-import com.google.android.exoplayer.MediaFormat;
-import com.google.android.exoplayer.SampleHolder;
-import com.google.android.exoplayer.SampleSource;
-import com.google.android.exoplayer2.upstream.DataSource;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowLooper;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.SortedMap;
-
-/** Tests for {@link ExoPlayerSampleExtractor} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class SampleSourceExtractorTest {
- // 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;
- private static final int CONSUMING_SAMPLES_PERIOD = 100;
- private Uri testStreamUri;
- private HandlerThread handlerThread;
- private DataSource dataSource;
-
- @Before
- public void setUp() {
- testStreamUri = Uri.parse("asset:///capture_stream.ts");
- handlerThread = new HandlerThread("test");
- dataSource = new AssetDataSource(RuntimeEnvironment.application);
- }
-
- @Test
- public void testTrickplayDisabled() throws Throwable {
- DataSource source = new AssetDataSource(RuntimeEnvironment.application);
- MockPlaybackBufferListener listener = new MockPlaybackBufferListener();
- ExoPlayerSampleExtractor extractor =
- new ExoPlayerSampleExtractor(
- testStreamUri,
- source,
- null,
- listener,
- false,
- Looper.getMainLooper(),
- handlerThread,
- (bufferManager, bufferListener, enableTrickplay, bufferReason) -> null);
- assertWithMessage("Trickplay should be disabled").that(listener.getLastState()).isFalse();
- // Prepares the extractor.
- extractor.prepare();
- // Looper is nat available until prepare is called at least once
- Looper handlerLooper = handlerThread.getLooper();
- try {
- while (!extractor.prepare()) {
-
- ShadowLooper.getShadowMainLooper().runOneTask();
- Shadows.shadowOf(handlerLooper).runOneTask();
- }
- } catch (IOException e) {
- fail("Exception occurred while preparing: " + e.getMessage());
- }
- // Selects all tracks.
- List<MediaFormat> trackFormats = extractor.getTrackFormats();
- for (int i = 0; i < trackFormats.size(); ++i) {
- extractor.selectTrack(i);
- }
- // Consumes over some period.
- SampleHolder sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
- sampleHolder.ensureSpaceForWrite(SAMPLE_BUFFER_SIZE);
-
- Shadows.shadowOf(handlerLooper).idle();
- for (int i = 0; i < CONSUMING_SAMPLES_PERIOD; ++i) {
- boolean found = false;
- while (!found) {
- for (int j = 0; j < trackFormats.size(); ++j) {
- int result = extractor.readSample(j, sampleHolder);
- switch (result) {
- case SampleSource.SAMPLE_READ:
- found = true;
- break;
- case SampleSource.END_OF_STREAM:
- fail("Failed to read samples");
- break;
- default:
- }
- if (found) {
- break;
- }
- }
- Shadows.shadowOf(handlerLooper).runOneTask();
- ShadowLooper.getShadowMainLooper().runOneTask();
- }
- }
- extractor.release();
- }
-
- @Ignore("b/70338667")
- @Test
- public void testDiskTooSlowTrickplayDisabled() throws Throwable {
- StorageManager storageManager = new StubStorageManager(RuntimeEnvironment.application);
- BufferManager bufferManager =
- new BufferManager(
- storageManager, new VerySlowSampleChunk.VerySlowSampleChunkCreator());
- bufferManager.setMinimumSampleSizeForSpeedCheck(0);
- MockPlaybackBufferListener listener = new MockPlaybackBufferListener();
- ExoPlayerSampleExtractor extractor =
- new ExoPlayerSampleExtractor(
- testStreamUri,
- dataSource,
- bufferManager,
- listener,
- false,
- Looper.getMainLooper(),
- handlerThread,
- (bufferManager2, bufferListener, enableTrickplay, bufferReason) -> null);
-
- assertWithMessage("Trickplay should be enabled at the first")
- .that(Boolean.TRUE)
- .isEqualTo(listener.getLastState());
- // Prepares the extractor.
- extractor.prepare();
- // Looper is nat available until prepare is called at least once
- Looper handlerLooper = handlerThread.getLooper();
- try {
- while (!extractor.prepare()) {
-
- ShadowLooper.getShadowMainLooper().runOneTask();
- Shadows.shadowOf(handlerLooper).runOneTask();
- }
- } catch (IOException e) {
- fail("Exception occurred while preparing: " + e.getMessage());
- }
- // Selects all tracks.
- List<MediaFormat> trackFormats = extractor.getTrackFormats();
- for (int i = 0; i < trackFormats.size(); ++i) {
- extractor.selectTrack(i);
- }
- // Consumes until once speed check is done.
- SampleHolder sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
- sampleHolder.ensureSpaceForWrite(SAMPLE_BUFFER_SIZE);
- while (!bufferManager.hasSpeedCheckDone()) {
- boolean found = false;
- while (!found) {
- for (int j = 0; j < trackFormats.size(); ++j) {
- int result = extractor.readSample(j, sampleHolder);
- switch (result) {
- case SampleSource.SAMPLE_READ:
- found = true;
- break;
- case SampleSource.END_OF_STREAM:
- fail("Failed to read samples");
- break;
- default:
- }
- if (found) {
- break;
- }
- }
- ShadowLooper.getShadowMainLooper().runOneTask();
- Shadows.shadowOf(handlerLooper).runOneTask();
- }
- }
- extractor.release();
- ShadowLooper.getShadowMainLooper().idle();
- Shadows.shadowOf(handlerLooper).idle();
- assertWithMessage("Disk too slow event should be reported")
- .that(listener.isReportedDiskTooSlow())
- .isTrue();
- }
-
- private static class StubStorageManager implements StorageManager {
- private final Context mContext;
-
- StubStorageManager(Context context) {
- mContext = context;
- }
-
- @Override
- public File getBufferDir() {
- return mContext.getCacheDir();
- }
-
- @Override
- public boolean isPersistent() {
- return false;
- }
-
- @Override
- public boolean reachedStorageMax(long bufferSize, long pendingDelete) {
- return false;
- }
-
- @Override
- public boolean hasEnoughBuffer(long pendingDelete) {
- return true;
- }
-
- @Override
- public List<BufferManager.TrackFormat> readTrackInfoFiles(boolean isAudio) {
- return null;
- }
-
- @Override
- public ArrayList<BufferManager.PositionHolder> readIndexFile(String trackId)
- throws IOException {
- return null;
- }
-
- @Override
- public void writeTrackInfoFiles(List<BufferManager.TrackFormat> formatList, boolean isAudio)
- throws IOException {
- // No-op.
- }
-
- @Override
- public void writeIndexFile(
- String trackName, SortedMap<Long, Pair<SampleChunk, Integer>> index)
- throws IOException {
- // No-op.
- }
-
- @Override
- public void updateIndexFile(
- String trackName, int size, long position, SampleChunk sampleChunk, int offset)
- throws IOException {
- // No-op
- }
- }
-
- public static class MockPlaybackBufferListener implements PlaybackBufferListener {
- private Boolean mLastState;
- private boolean mIsReportedDiskTooSlow;
-
- public Boolean getLastState() {
- return mLastState;
- }
-
- public boolean isReportedDiskTooSlow() {
- return mIsReportedDiskTooSlow;
- }
- // PlaybackBufferListener
- @Override
- public void onBufferStartTimeChanged(long startTimeMs) {
- // No-op.
- }
-
- @Override
- public void onBufferStateChanged(boolean available) {
- mLastState = available;
- }
-
- @Override
- public void onDiskTooSlow() {
- mIsReportedDiskTooSlow = true;
- }
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/testing/TvTunerRobolectricTestRunner.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/testing/TvTunerRobolectricTestRunner.java
deleted file mode 100644
index 31dc25d5..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/testing/TvTunerRobolectricTestRunner.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.tuner.testing;
-
-import org.junit.runners.model.InitializationError;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.manifest.AndroidManifest;
-import org.robolectric.res.Fs;
-import org.robolectric.res.ResourcePath;
-
-import java.util.List;
-
-/**
- * Custom test runner TV tuner. This is needed because the default behavior for robolectric is just
- * to grab the resource directory in the target package. We want to override this to add several
- * spanning different projects.
- *
- * <p><b>Note</b> copied from
- * http://cs/android/packages/apps/Settings/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
- */
-public class TvTunerRobolectricTestRunner extends RobolectricTestRunner {
-
- /** We don't actually want to change this behavior, so we just call super. */
- public TvTunerRobolectricTestRunner(Class<?> testClass) throws InitializationError {
- super(testClass);
- }
-
- /**
- * We are going to create our own custom manifest so that we can add multiple resource paths to
- * it.
- */
- @Override
- protected AndroidManifest getAppManifest(Config config) {
- final String packageName = "com.android.tv.tuner";
-
- // By adding any resources from libraries we need the AndroidManifest, we can access
- // them from within the parallel universe's resource loader.
- return new AndroidManifest(
- Fs.fileFromPath(config.manifest()),
- Fs.fileFromPath(config.resourceDir()),
- Fs.fileFromPath(config.assetDir()),
- packageName) {
- @Override
- public List<ResourcePath> getIncludedResourcePaths() {
- List<ResourcePath> paths = super.getIncludedResourcePaths();
- TvTunerRobolectricTestRunner.getIncludedResourcePaths(paths);
- return paths;
- }
- };
- }
-
- public static void getIncludedResourcePaths(List<ResourcePath> paths) {
- paths.add(
- new ResourcePath(
- null,
- Fs.fileFromPath("./packages/apps/TV/tuner/res"),
- null));
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java
deleted file mode 100644
index 24adbaa9..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.tvinput;
-
-import static com.android.tv.common.customization.CustomizationManager.TRICKPLAY_MODE_ENABLED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Application;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.accessibility.CaptioningManager;
-
-import com.android.tv.common.CommonConstants;
-import com.android.tv.common.CommonPreferences;
-import com.android.tv.common.compat.TvInputConstantCompat;
-import com.android.tv.common.customization.CustomizationManager;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.exoplayer.MpegTsPlayer;
-import com.android.tv.tuner.source.TsDataSourceManager;
-import com.android.tv.tuner.source.TunerTsStreamerManager;
-import com.android.tv.tuner.testing.TvTunerRobolectricTestRunner;
-import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-
-import com.google.android.exoplayer.audio.AudioCapabilities;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mockito;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowContextImpl;
-
-import java.lang.reflect.Field;
-
-import javax.inject.Provider;
-
-/** Tests for {@link TunerSessionWorkerExoV2}. */
-@RunWith(TvTunerRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class TunerSessionWorkerExoV2Test {
-
- private TunerSessionWorkerExoV2 tunerSessionWorker;
- private int mSignalStrength = TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN;
- private MpegTsPlayer mPlayer = Mockito.mock(MpegTsPlayer.class);
- private Handler mHandler;
- private DefaultLegacyFlags mLegacyFlags;
-
- @Before
- public void setUp() throws NoSuchFieldException, IllegalAccessException {
- Application context = RuntimeEnvironment.application;
- mLegacyFlags = DefaultLegacyFlags.DEFAULT;
- CaptioningManager captioningManager = Mockito.mock(CaptioningManager.class);
-
- // TODO (b/65160115)
- Field field = CustomizationManager.class.getDeclaredField("sCustomizationPackage");
- field.setAccessible(true);
- field.set(null, CommonConstants.BASE_PACKAGE + ".tuner");
- field = CustomizationManager.class.getDeclaredField("sTrickplayMode");
- field.setAccessible(true);
- field.set(null, TRICKPLAY_MODE_ENABLED);
-
- ShadowContextImpl shadowContext = Shadow.extract(context.getBaseContext());
- shadowContext.setSystemService(Context.CAPTIONING_SERVICE, captioningManager);
-
- CommonPreferences.initialize(context);
- ChannelDataManager channelDataManager = new ChannelDataManager(context, "testInput");
-
- mHandler = new Handler(Looper.getMainLooper(), null);
-
- Provider<TunerTsStreamerManager> tsStreamerManagerProvider =
- () -> new TunerTsStreamerManager(null);
- TsDataSourceManager.Factory tsDataSourceManagerFactory =
- new TsDataSourceManager.Factory(tsStreamerManagerProvider);
-
- new TunerSessionExoV2(
- context,
- channelDataManager,
- session -> {},
- recordingSession -> Uri.parse("recordingUri"),
- (context1, channelDataManager1, tunerSession1, tunerSessionOverlay) -> {
- tunerSessionWorker =
- new TunerSessionWorkerExoV2(
- context1,
- channelDataManager1,
- tunerSession1,
- tunerSessionOverlay,
- mHandler,
- mLegacyFlags,
- (context2, bufferManager, bufferListener) -> null,
- tsDataSourceManagerFactory) {
- @Override
- protected void notifySignal(int signal) {
- mSignalStrength = signal;
- }
-
- @Override
- protected MpegTsPlayer createPlayer(
- AudioCapabilities capabilities) {
- return mPlayer;
- }
- };
- return tunerSessionWorker;
- });
- }
-
- @Test
- public void doSelectTrack_mPlayerIsNull() {
- Message msg = new Message();
- msg.what = TunerSessionWorker.MSG_SELECT_TRACK;
- assertThat(tunerSessionWorker.handleMessage(msg)).isFalse();
- }
-
- @Test
- public void doCheckSignalStrength_mPlayerIsNull() {
- Message msg = new Message();
- msg.what = TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH;
- assertThat(tunerSessionWorker.handleMessage(msg)).isFalse();
- }
-
- @Test
- public void handleSignal_isNotUsed() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED);
- }
-
- @Test
- public void handleSignal_isError() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR);
- }
-
- @Test
- public void handleSignal_isUnknown() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN);
- }
-
- @Test
- public void handleSignal_isNotifySignal() {
- assertThat(tunerSessionWorker.handleSignal(100)).isTrue();
- assertThat(mSignalStrength).isEqualTo(100);
- }
-
- @Test
- public void preparePlayback_playerIsNotReady() {
- Mockito.when(
- mPlayer.prepare(
- Mockito.eq(RuntimeEnvironment.application),
- ArgumentMatchers.any(),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.any()))
- .thenReturn(false);
- tunerSessionWorker.preparePlayback();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_TUNE)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_RETRY_PLAYBACK)).isTrue();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL)).isFalse();
- }
-
- @Test
- @Ignore
- public void preparePlayback_playerIsReady() {
- Mockito.when(
- mPlayer.prepare(
- RuntimeEnvironment.application,
- ArgumentMatchers.any(),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.any()))
- .thenReturn(true);
- tunerSessionWorker.preparePlayback();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_RETRY_PLAYBACK)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH)).isTrue();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL)).isTrue();
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java
deleted file mode 100644
index 536af60c..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.tuner.tvinput;
-
-import static com.android.tv.common.customization.CustomizationManager.TRICKPLAY_MODE_ENABLED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Application;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.accessibility.CaptioningManager;
-
-import com.android.tv.common.CommonConstants;
-import com.android.tv.common.CommonPreferences;
-import com.android.tv.common.compat.TvInputConstantCompat;
-import com.android.tv.common.customization.CustomizationManager;
-import com.android.tv.common.flags.impl.DefaultLegacyFlags;
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.tuner.exoplayer.MpegTsPlayer;
-import com.android.tv.tuner.source.TsDataSourceManager;
-import com.android.tv.tuner.source.TunerTsStreamerManager;
-import com.android.tv.tuner.testing.TvTunerRobolectricTestRunner;
-import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-
-import com.google.android.exoplayer.audio.AudioCapabilities;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mockito;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowContextImpl;
-
-import java.lang.reflect.Field;
-
-import javax.inject.Provider;
-
-/** Tests for {@link TunerSessionWorker}. */
-@RunWith(TvTunerRobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class TunerSessionWorkerTest {
-
- private TunerSessionWorker tunerSessionWorker;
- private int mSignalStrength = TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN;
- private MpegTsPlayer mPlayer = Mockito.mock(MpegTsPlayer.class);
- private Handler mHandler;
- private DefaultLegacyFlags mLegacyFlags;
-
- @Before
- public void setUp() throws NoSuchFieldException, IllegalAccessException {
- Application context = RuntimeEnvironment.application;
- CaptioningManager captioningManager = Mockito.mock(CaptioningManager.class);
- mLegacyFlags = DefaultLegacyFlags.DEFAULT;
-
- // TODO (b/65160115)
- Field field = CustomizationManager.class.getDeclaredField("sCustomizationPackage");
- field.setAccessible(true);
- field.set(null, CommonConstants.BASE_PACKAGE + ".tuner");
- field = CustomizationManager.class.getDeclaredField("sTrickplayMode");
- field.setAccessible(true);
- field.set(null, TRICKPLAY_MODE_ENABLED);
-
- ShadowContextImpl shadowContext = Shadow.extract(context.getBaseContext());
- shadowContext.setSystemService(Context.CAPTIONING_SERVICE, captioningManager);
-
- CommonPreferences.initialize(context);
- ChannelDataManager channelDataManager = new ChannelDataManager(context, "testInput");
-
- mHandler = new Handler(Looper.getMainLooper(), null);
- Provider<TunerTsStreamerManager> tsStreamerManagerProvider =
- () -> new TunerTsStreamerManager(null);
- TsDataSourceManager.Factory tsdm =
- new TsDataSourceManager.Factory(tsStreamerManagerProvider);
-
- new TunerSession(
- context,
- channelDataManager,
- session -> {},
- recordingSession -> Uri.parse("recordingUri"),
- (context1, channelDataManager1, tunerSession1, tunerSessionOverlay) -> {
- tunerSessionWorker =
- new TunerSessionWorker(
- context1,
- channelDataManager1,
- tunerSession1,
- new TunerSessionOverlay(context1),
- mHandler,
- mLegacyFlags,
- (context2, bufferManager, bufferListener) -> null,
- tsdm) {
- @Override
- protected void notifySignal(int signal) {
- mSignalStrength = signal;
- }
-
- @Override
- protected MpegTsPlayer createPlayer(
- AudioCapabilities capabilities) {
- return mPlayer;
- }
- };
- return tunerSessionWorker;
- });
- }
-
- @Test
- public void doSelectTrack_mPlayerIsNull() {
- Message msg = new Message();
- msg.what = TunerSessionWorker.MSG_SELECT_TRACK;
- assertThat(tunerSessionWorker.handleMessage(msg)).isFalse();
- }
-
- @Test
- public void doCheckSignalStrength_mPlayerIsNull() {
- Message msg = new Message();
- msg.what = TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH;
- assertThat(tunerSessionWorker.handleMessage(msg)).isFalse();
- }
-
- @Test
- public void handleSignal_isNotUsed() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_NOT_USED);
- }
-
- @Test
- public void handleSignal_isError() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_ERROR);
- }
-
- @Test
- public void handleSignal_isUnknown() {
- assertThat(tunerSessionWorker.handleSignal(TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN))
- .isTrue();
- assertThat(mSignalStrength).isEqualTo(TvInputConstantCompat.SIGNAL_STRENGTH_UNKNOWN);
- }
-
- @Test
- public void handleSignal_isNotifySignal() {
- assertThat(tunerSessionWorker.handleSignal(100)).isTrue();
- assertThat(mSignalStrength).isEqualTo(100);
- }
-
- @Test
- public void preparePlayback_playerIsNotReady() {
- Mockito.when(
- mPlayer.prepare(
- Mockito.eq(RuntimeEnvironment.application),
- ArgumentMatchers.any(),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.any()))
- .thenReturn(false);
- tunerSessionWorker.preparePlayback();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_TUNE)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_RETRY_PLAYBACK)).isTrue();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL)).isFalse();
- }
-
- @Test
- @Ignore
- public void preparePlayback_playerIsReady() {
- Mockito.when(
- mPlayer.prepare(
- RuntimeEnvironment.application,
- ArgumentMatchers.any(),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.any()))
- .thenReturn(true);
- tunerSessionWorker.preparePlayback();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_RETRY_PLAYBACK)).isFalse();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL_STRENGTH)).isTrue();
- assertThat(mHandler.hasMessages(TunerSessionWorker.MSG_CHECK_SIGNAL)).isTrue();
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/datamanager/ChannelDataManagerTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/datamanager/ChannelDataManagerTest.java
deleted file mode 100644
index 0da76ef8..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/datamanager/ChannelDataManagerTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.tvinput.datamanager;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentValues;
-import android.content.pm.ProviderInfo;
-import android.media.tv.TvContract;
-
-import com.android.tv.testing.TestSingletonApp;
-import com.android.tv.testing.constants.ConfigConstants;
-import com.android.tv.testing.fakes.FakeTvProvider;
-import com.android.tv.tuner.data.Channel;
-import com.android.tv.tuner.data.TunerChannel;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowContentResolver;
-import org.robolectric.shadows.ShadowContextWrapper;
-
-/** Tests for {@link com.android.tv.tuner.tvinput.datamanager.ChannelDataManager}. */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK, application = TestSingletonApp.class)
-public class ChannelDataManagerTest {
-
- private ChannelDataManager mChannelDataManager;
-
- @Before
- public void setup() {
- ProviderInfo info = new ProviderInfo();
- info.authority = TvContract.AUTHORITY;
- FakeTvProvider provider =
- Robolectric.buildContentProvider(FakeTvProvider.class).create(info).get();
- provider.setCallingPackage("com.android.tv");
- provider.onCreate();
- ShadowContextWrapper shadowContextWrapper = new ShadowContextWrapper();
- shadowContextWrapper.grantPermissions(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS);
- ShadowContentResolver.registerProviderInternal(TvContract.AUTHORITY, provider);
- provider.delete(TvContract.Channels.CONTENT_URI, null, null);
- ContentValues contentValues = new ContentValues();
- contentValues.put(TvContract.Channels.COLUMN_INPUT_ID, "com.android.tv");
- contentValues.put(
- TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA,
- Channel.TunerChannelProto.getDefaultInstance().toByteArray());
- contentValues.put(TvContract.Channels.COLUMN_LOCKED, 0);
- provider.insert(TvContract.Channels.CONTENT_URI, contentValues);
- contentValues.put(TvContract.Channels.COLUMN_LOCKED, 1);
- provider.insert(TvContract.Channels.CONTENT_URI, contentValues);
-
- mChannelDataManager = new ChannelDataManager(RuntimeEnvironment.application, "testInput");
- }
-
- @After
- public void tearDown() {
- mChannelDataManager.releaseSafely();
- }
-
- @Test
- public void getChannel_locked() {
- TunerChannel tunerChannel = mChannelDataManager.getChannel(2L);
- assertThat(tunerChannel.isLocked()).isTrue();
- }
-
- @Test
- public void getChannel_unlocked() {
- TunerChannel tunerChannel = mChannelDataManager.getChannel(1L);
- assertThat(tunerChannel.isLocked()).isFalse();
- }
-}
diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/util/PostalCodeUtilsTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/util/PostalCodeUtilsTest.java
deleted file mode 100644
index 5a49904e..00000000
--- a/tuner/tests/robotests/javatests/com/android/tv/tuner/util/PostalCodeUtilsTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.tuner.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.tv.common.util.PostalCodeUtils;
-import com.android.tv.testing.constants.ConfigConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.Locale;
-
-/** Tests for {@link PostalCodeUtils} */
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = ConfigConstants.SDK)
-public class PostalCodeUtilsTest {
-
- private static final String[] VALID_POSTCODES_US = {"94043", "94063", "90007"};
- private static final String[] INVALID_POSTCODES_US = {
- "", "9404", "ABC", "BCD8", "G777", "BT777", "OXX33", "E1WW", "SW1XX", "E11W", "SW10X",
- "GIR", "B8", "G77", "BT7", "OX33", "E1W", "SW1X"
- };
- private static final String[] VALID_POSTCODES_GB = {
- "GIR", "B8", "G77", "BT7", "OX33", "E1W", "SW1X", "GIR 0AA", "GIR0AA", "B8 2NE", "PR10BJ"
- };
- private static final String[] INVALID_POSTCODES_GB = {
- "", "9404", "ABC", "BCD8", "G777", "BT777", "OXX33", "E1WW", "SW1XX", "E11W", "SW10X",
- "94043", "94063", "90007", "B8 ", "OX331D"
- };
-
- @Test
- public void validPostcodesUs() {
- for (String postcode : VALID_POSTCODES_US) {
- assertThat(PostalCodeUtils.matches(postcode, Locale.US.getCountry())).isTrue();
- }
- }
-
- @Test
- public void validPostcodesGb() {
- for (String postcode : VALID_POSTCODES_GB) {
- assertThat(PostalCodeUtils.matches(postcode, Locale.UK.getCountry())).isTrue();
- }
- }
-
- @Test
- public void invalidPostcodesUs() {
- for (String postcode : INVALID_POSTCODES_US) {
- assertThat(PostalCodeUtils.matches(postcode, Locale.US.getCountry())).isFalse();
- }
- }
-
- @Test
- public void invalidPostcodesGb() {
- for (String postcode : INVALID_POSTCODES_GB) {
- assertThat(PostalCodeUtils.matches(postcode, Locale.UK.getCountry())).isFalse();
- }
- }
-
- @Test
- public void unsupportedRegion() {
- for (String postcode : INVALID_POSTCODES_US) {
- // {@link Locale.ROOT} is an empty Locale
- assertThat(PostalCodeUtils.matches(postcode, Locale.ROOT.getCountry())).isTrue();
- }
- }
-}
diff --git a/tuner/tests/testing/Android.mk b/tuner/tests/testing/Android.mk
index 864f5f3e..79e35e5a 100644
--- a/tuner/tests/testing/Android.mk
+++ b/tuner/tests/testing/Android.mk
@@ -10,7 +10,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-annotations \
androidx.test.runner \
tv-guava-android-jar \
- mockito-robolectric-prebuilt \
+ mockito-target \
tv-lib-truth \
ub-uiautomator \
diff --git a/tuner/tests/testing/AndroidManifest.xml b/tuner/tests/testing/AndroidManifest.xml
index 9fcecf9c..7e07a52a 100644
--- a/tuner/tests/testing/AndroidManifest.xml
+++ b/tuner/tests/testing/AndroidManifest.xml
@@ -18,6 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tuner.testing"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application />
</manifest>
diff --git a/tuner/tests/unittests/javatests/AndroidManifest.xml b/tuner/tests/unittests/javatests/AndroidManifest.xml
index ddbddd0b..62caefa1 100644
--- a/tuner/tests/unittests/javatests/AndroidManifest.xml
+++ b/tuner/tests/unittests/javatests/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tuner.layout.tests" >
- <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28"/>
+ <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="27"/>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
diff --git a/tuner/tests/unittests/javatests/com/android/tv/tuner/AndroidManifest.xml b/tuner/tests/unittests/javatests/com/android/tv/tuner/AndroidManifest.xml
index 6956426d..6fe0b85a 100644
--- a/tuner/tests/unittests/javatests/com/android/tv/tuner/AndroidManifest.xml
+++ b/tuner/tests/unittests/javatests/com/android/tv/tuner/AndroidManifest.xml
@@ -18,11 +18,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tuner.tests" >
- <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28" />
+ <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="27" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.tv.tuner.sample.dvb" />
+ android:targetPackage="com.android.tv" />
<application android:label="TunerTvInputTests" >
<uses-library android:name="android.test.runner" />
diff --git a/tuner/tests/unittests/javatests/com/android/tv/tuner/ZappingTimeTest.java b/tuner/tests/unittests/javatests/com/android/tv/tuner/ZappingTimeTest.java
index 031cec51..ef653f86 100644
--- a/tuner/tests/unittests/javatests/com/android/tv/tuner/ZappingTimeTest.java
+++ b/tuner/tests/unittests/javatests/com/android/tv/tuner/ZappingTimeTest.java
@@ -21,34 +21,24 @@ import android.graphics.SurfaceTexture;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
-import android.support.annotation.Nullable;
import android.test.InstrumentationTestCase;
import android.util.Log;
import android.view.Surface;
-
import androidx.test.filters.LargeTest;
-
+import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
import com.android.tv.tuner.data.Cea708Data;
-import com.android.tv.tuner.data.Channel.AudioStreamType;
-import com.android.tv.tuner.data.Channel.VideoStreamType;
import com.android.tv.tuner.data.PsiData;
import com.android.tv.tuner.data.PsipData;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.exoplayer.MpegTsPlayer;
import com.android.tv.tuner.exoplayer.MpegTsRendererBuilder;
-import com.android.tv.tuner.exoplayer.MpegTsSampleExtractor;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.PlaybackBufferListener;
import com.android.tv.tuner.exoplayer.buffer.TrickplayStorageManager;
import com.android.tv.tuner.source.TsDataSourceManager;
-import com.android.tv.tuner.source.TsDataSourceManager.Factory;
import com.android.tv.tuner.ts.EventDetector.EventListener;
-
import com.google.android.exoplayer.ExoPlayer;
-import com.google.android.exoplayer2.upstream.DataSource;
-
-import org.junit.Ignore;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -59,6 +49,7 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import org.junit.Ignore;
/** This class use {@link FileTunerHal} to simulate tunerhal's actions to test zapping time. */
@LargeTest
@@ -97,6 +88,8 @@ public class ZappingTimeTest extends InstrumentationTestCase {
private MockMpegTsPlayerListener mMpegTsPlayerListener = new MockMpegTsPlayerListener();
private MockPlaybackBufferListener mPlaybackBufferListener = new MockPlaybackBufferListener();
private MockChannelScanListener mEventListener = new MockChannelScanListener();
+ private DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
+ new DefaultConcurrentDvrPlaybackFlags();
@Override
protected void setUp() throws Exception {
@@ -106,10 +99,10 @@ public class ZappingTimeTest extends InstrumentationTestCase {
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
List<PsiData.PmtItem> pmtItems = new ArrayList<>();
- pmtItems.add(new PsiData.PmtItem(VideoStreamType.MPEG2_VALUE, VIDEO_PID, null, null));
+ pmtItems.add(new PsiData.PmtItem(Channel.VideoStreamType.MPEG2, VIDEO_PID, null, null));
for (int audioPid : AUDIO_PIDS) {
pmtItems.add(
- new PsiData.PmtItem(AudioStreamType.A52AC3AUDIO_VALUE, audioPid, null, null));
+ new PsiData.PmtItem(Channel.AudioStreamType.A52AC3AUDIO, audioPid, null, null));
}
Context context = getInstrumentation().getContext();
@@ -124,25 +117,8 @@ public class ZappingTimeTest extends InstrumentationTestCase {
mChannel.setModulation(MODULATION);
mTunerHal = new FileTunerHal(context, tsCacheFile);
mTunerHal.openFirstAvailable();
- TsDataSourceManager.Factory tsFactory = new Factory(null);
- mSourceManager = tsFactory.create(false);
+ mSourceManager = TsDataSourceManager.createSourceManager(false);
mSourceManager.addTunerHalForTest(mTunerHal);
- MpegTsSampleExtractor.Factory mpegTsSampleExtractorFactory =
- new MpegTsSampleExtractor.Factory() {
- @Override
- public MpegTsSampleExtractor create(
- BufferManager bufferManager, PlaybackBufferListener bufferListener) {
- return null;
- }
-
- @Override
- public MpegTsSampleExtractor create(
- DataSource source,
- @Nullable BufferManager bufferManager,
- PlaybackBufferListener bufferListener) {
- return null;
- }
- };
mHandler =
new Handler(
handlerThread.getLooper(),
@@ -174,14 +150,13 @@ public class ZappingTimeTest extends InstrumentationTestCase {
}
mChannel.setFrequency(frequency);
mSourceManager.setKeepTuneStatus(true);
-
mPlayer =
new MpegTsPlayer(
new MpegTsRendererBuilder(
mTargetContext,
bufferManager,
mPlaybackBufferListener,
- mpegTsSampleExtractorFactory),
+ mConcurrentDvrPlaybackFlags),
mHandler,
mSourceManager,
null,
diff --git a/tuner/tests/unittests/javatests/com/android/tv/tuner/layout/tests/AndroidManifest.xml b/tuner/tests/unittests/javatests/com/android/tv/tuner/layout/tests/AndroidManifest.xml
index 79b09872..77c7f40a 100644
--- a/tuner/tests/unittests/javatests/com/android/tv/tuner/layout/tests/AndroidManifest.xml
+++ b/tuner/tests/unittests/javatests/com/android/tv/tuner/layout/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tuner"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="27" android:minSdkVersion="23"/>
<application android:label="TunerTvInputLayoutTests" >
<activity android:name="com.android.tv.tuner.layout.tests.ScaledLayoutActivity"
android:label="ScaledLayout Test" />
diff --git a/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/AndroidManifest.xml b/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/AndroidManifest.xml
deleted file mode 100644
index 19cc0e5d..00000000
--- a/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.tv.tuner.setup.tests" >
-
- <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28" />
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.tv.tuner.sample.dvb" />
-
- <application android:label="TunerTvInputTests" >
- <uses-library android:name="android.test.runner" />
- </application>
-
-</manifest>
diff --git a/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/TunerHalCreatorTest.java b/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/TunerHalCreatorTest.java
index cc5e5c59..a3a32084 100644
--- a/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/TunerHalCreatorTest.java
+++ b/tuner/tests/unittests/javatests/com/android/tv/tuner/setup/TunerHalCreatorTest.java
@@ -21,18 +21,14 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import android.os.AsyncTask;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-
import com.android.tv.tuner.api.Tuner;
import com.android.tv.tuner.setup.BaseTunerSetupActivity.TunerHalCreator;
-
+import java.util.concurrent.Executor;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.concurrent.Executor;
-
/** Tests for {@link TunerHalCreator}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -41,7 +37,7 @@ public class TunerHalCreatorTest {
private static class TestTunerHalCreator extends TunerHalCreator {
private TestTunerHalCreator(Executor executor) {
- super(null, executor, null);
+ super(null, executor);
}
@Override