Snap for 5316819 from c31edd529663ceeab53cbfc10a8ad7a53b3be30a to qt-release
Change-Id: Icd9d7c802479322ccc52dce08082371ef400f268
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..4268636
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,96 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+version_name = "1.20-asop"
+version_code = "417000328"
+
+android_app {
+ name: "LiveTv",
+
+ srcs: ["src/**/*.java"],
+
+ // TODO(b/122608868) turn proguard back on
+ optimize: {
+ enabled: false,
+ },
+
+ // It is required for com.android.providers.tv.permission.ALL_EPG_DATA
+ privileged: true,
+
+ sdk_version: "system_current",
+ min_sdk_version: "23", // M
+
+ resource_dirs: [
+ "res",
+ "material_res",
+
+ ],
+
+ libs: ["tv-guava-android-jar"],
+
+ static_libs: [
+ "android-support-annotations",
+ "android-support-compat",
+ "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",
+ "live-tv-tuner",
+ "tv-auto-value-jar",
+ "tv-auto-factory-jar",
+ "tv-common",
+ "tv-error-prone-annotations-jar",
+ "tv-lib-dagger",
+ "tv-lib-exoplayer",
+ "tv-lib-exoplayer-v2-core",
+ "tv-lib-dagger-android",
+ ],
+
+ plugins: [
+ "tv-auto-value",
+ "tv-auto-factory",
+ "tv-lib-dagger-android-processor",
+ "tv-lib-dagger-compiler",
+ ],
+
+ javacflags: [
+ "-Xlint:deprecation",
+ "-Xlint:unchecked",
+ ],
+
+ aaptflags: [
+ "--version-name",
+ version_name,
+
+ "--version-code",
+ version_code,
+
+ "--extra-packages",
+ "com.android.tv.tuner",
+
+ "--extra-packages",
+ "com.android.tv.common",
+ ],
+}
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 52e9742..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-include $(LOCAL_PATH)/version.mk
-
-LOCAL_SRC_FILES += $(call all-java-files-under, src)
-
-# TODO(b/77284273): Stop compiling everything at once dagger properly supported in libraries
-LOCAL_SRC_FILES += $(call all-java-files-under, common/src)
-LOCAL_SRC_FILES += $(call all-proto-files-under, common/src)
-
-LOCAL_SRC_FILES += $(call all-java-files-under, tuner/src)
-
-
-
-LOCAL_PACKAGE_NAME := LiveTv
-
-# TODO(b/122608868) turn proguard back on
-LOCAL_PROGUARD_ENABLED := disabled
-
-# It is required for com.android.providers.tv.permission.ALL_EPG_DATA
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_SDK_VERSION := system_current
-LOCAL_MIN_SDK_VERSION := 23 # M
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res \
- $(LOCAL_PATH)/material_res \
- $(LOCAL_PATH)/common/res \
- $(LOCAL_PATH)/tuner/res \
-
-LOCAL_JAVA_LIBRARIES := \
- tv-guava-android-jar \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- tv-auto-value-jar \
- tv-auto-factory-jar \
- android-support-annotations \
- tv-error-prone-annotations-jar \
- jsr330 \
- tv-lib-dagger \
- tv-lib-exoplayer \
- tv-lib-exoplayer-v2-core \
- live-tv-tuner-proto \
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-compat \
- 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 \
- tv-lib-dagger-android \
- live-channels-partner-support \
-
-LOCAL_ANNOTATION_PROCESSORS := \
- tv-auto-value-jar \
- tv-auto-factory-jar \
- tv-guava-jre-jar \
- tv-lib-dagger-android-processor \
- tv-lib-dagger-compiler \
-
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := \
- com.google.auto.factory.processor.AutoFactoryProcessor,com.google.auto.value.processor.AutoValueProcessor,dagger.internal.codegen.ComponentProcessor,dagger.android.processor.AndroidProcessor
-
-
-LOCAL_JAVACFLAGS := -Xlint:deprecation -Xlint:unchecked
-
-LOCAL_AAPT_FLAGS += \
- --version-name "$(version_name_package)" \
- --version-code $(version_code_package) \
-
-LOCAL_JNI_SHARED_LIBRARIES := libtunertvinput_jni
-LOCAL_AAPT_FLAGS += --extra-packages com.android.tv.tuner
-LOCAL_AAPT_FLAGS += --extra-packages com.android.tv.common
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 43c2a3e..a398823 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,10 +16,9 @@
-->
<!-- 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="27" />
@@ -81,17 +80,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.TV"
tools:replace="android:appComponentFactory">
- <activity
- android:name="com.android.tv.tuner.setup.LiveTvTunerSetupActivity"
- android:configChanges="keyboard|keyboardHidden"
- android:label="@string/bt_app_name"
- android:launchMode="singleInstance"
- android:process="com.android.tv.tuner"
- android:theme="@style/Theme.Setup.GuidedStep" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
+ >
<!-- providers are listed here to keep them separate from the internal versions -->
<provider
@@ -288,7 +277,7 @@
android:name="com.android.tv.setup.SystemSetupActivity"
android:configChanges="keyboard|keyboardHidden"
android:exported="true"
- android:label="@string/bt_app_name"
+ android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@style/Theme.Setup.GuidedStep" >
<intent-filter>
@@ -304,27 +293,8 @@
<receiver android:name="com.android.tv.dvr.recorder.DvrStartRecordingReceiver" />
<service
- android:name="com.android.tv.tuner.tvinput.TunerStorageCleanUpService"
- android:exported="false"
- android:permission="android.permission.BIND_JOB_SERVICE"
- android:process="com.android.tv.tuner" />
- <service
android:name="com.android.tv.data.epg.EpgFetchService"
android:permission="android.permission.BIND_JOB_SERVICE" />
- <service
- android:name="com.android.tv.tuner.livetuner.LiveTvTunerTvInputService"
- android:enabled="false"
- android:label="@string/bt_app_name"
- android:permission="android.permission.BIND_TV_INPUT"
- android:process="com.android.tv.tuner" >
- <intent-filter>
- <action android:name="android.media.tv.TvInputService" />
- </intent-filter>
-
- <meta-data
- android:name="android.media.tv.input"
- android:resource="@xml/ut_tvinputservice" />
- </service>
</application>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/build.gradle b/build.gradle
index 9a29367..23e3dbd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,18 +26,13 @@
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
- classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'
}
}
apply plugin: 'com.android.application'
android {
- compileSdkVersion 26
- buildToolsVersion '28.0.2'
- lintOptions {
- // check for lint errors in release builds,
- // but continue the build even when errors are found:
- abortOnError false
- }
+ compileSdkVersion 28
+ buildToolsVersion '28.0.3'
dexOptions {
preDexLibraries = false
additionalParameters=['--core-library']
@@ -50,7 +45,7 @@
}
defaultConfig {
minSdkVersion 23
- targetSdkVersion 26
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
}
@@ -81,16 +76,24 @@
google()
}
-final String SUPPORT_LIBS_VERSION = '26.1.0'
dependencies {
- 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)*/
+ 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.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'
+
+ /*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')
- implementation project(':tuner')
}
\ No newline at end of file
diff --git a/common/Android.bp b/common/Android.bp
index bc40838..63759d4 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -48,6 +48,8 @@
plugins: [
"tv-auto-value",
"tv-auto-factory",
+ "tv-lib-dagger-android-processor",
+ "tv-lib-dagger-compiler",
],
diff --git a/common/build.gradle b/common/build.gradle
index 66f3b6e..f371475 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -28,11 +28,12 @@
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'
}
}
android {
- compileSdkVersion 26
- buildToolsVersion '28.0.2'
+ compileSdkVersion 28
+ buildToolsVersion '28.0.3'
dexOptions {
preDexLibraries = false
additionalParameters = ['--core-library']
@@ -47,18 +48,20 @@
defaultConfig {
minSdkVersion 23
- targetSdkVersion 26
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
debug {
minifyEnabled false
+ buildConfigField "boolean", "AOSP", "true"
buildConfigField "boolean", "ENG", "true"
buildConfigField "boolean", "NO_JNI_TEST", "false"
}
release {
minifyEnabled true
+ buildConfigField "boolean", "AOSP", "true"
buildConfigField "boolean", "ENG", "false"
buildConfigField "boolean", "NO_JNI_TEST", "false"
}
@@ -85,17 +88,25 @@
google()
}
-final String SUPPORT_LIBS_VERSION = '26.1.0'
dependencies {
- implementation "com.android.support:appcompat-v7:${SUPPORT_LIBS_VERSION}"
- implementation "com.android.support:leanback-v17:${SUPPORT_LIBS_VERSION}"
+ 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.6.1'
+ 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
protoc {
- artifact = 'com.google.protobuf:protoc:3.6.1'
+ artifact = 'com.google.protobuf:protoc:3.0.0'
plugins {
javalite {
diff --git a/common/src/com/android/tv/common/BaseApplication.java b/common/src/com/android/tv/common/BaseApplication.java
index 871e461..45c3256 100644
--- a/common/src/com/android/tv/common/BaseApplication.java
+++ b/common/src/com/android/tv/common/BaseApplication.java
@@ -18,7 +18,6 @@
import android.annotation.TargetApi;
import android.content.Context;
-import android.content.Intent;
import android.os.Build;
import android.os.StrictMode;
import android.support.annotation.VisibleForTesting;
@@ -105,7 +104,4 @@
}
return mRecordingStorageStatusManager;
}
-
- @Override
- public abstract Intent getTunerSetupIntent(Context context);
}
diff --git a/common/src/com/android/tv/common/BaseSingletons.java b/common/src/com/android/tv/common/BaseSingletons.java
index f5ab636..1053061 100644
--- a/common/src/com/android/tv/common/BaseSingletons.java
+++ b/common/src/com/android/tv/common/BaseSingletons.java
@@ -16,8 +16,6 @@
package com.android.tv.common;
-import android.content.Context;
-import android.content.Intent;
import com.android.tv.common.buildtype.HasBuildType;
import com.android.tv.common.flags.has.HasCloudEpgFlags;
import com.android.tv.common.flags.has.HasConcurrentDvrPlaybackFlags;
@@ -31,6 +29,4 @@
Clock getClock();
RecordingStorageStatusManager getRecordingStorageStatusManager();
-
- Intent getTunerSetupIntent(Context context);
}
diff --git a/common/src/com/android/tv/common/dagger/ApplicationModule.java b/common/src/com/android/tv/common/dagger/ApplicationModule.java
index 592717b..4655f77 100644
--- a/common/src/com/android/tv/common/dagger/ApplicationModule.java
+++ b/common/src/com/android/tv/common/dagger/ApplicationModule.java
@@ -16,6 +16,7 @@
package com.android.tv.common.dagger;
import android.app.Application;
+import android.content.ContentResolver;
import android.content.Context;
import android.os.Looper;
import com.android.tv.common.dagger.annotations.ApplicationContext;
@@ -29,21 +30,21 @@
*/
@Module
public final class ApplicationModule {
- private final Application application;
+ private final Application mApplication;
public ApplicationModule(Application application) {
- this.application = application;
+ mApplication = application;
}
@Provides
Application provideApplication() {
- return application;
+ return mApplication;
}
@Provides
@ApplicationContext
Context provideContext() {
- return application.getApplicationContext();
+ return mApplication.getApplicationContext();
}
@Provides
@@ -51,4 +52,9 @@
static Looper provideMainLooper() {
return Looper.getMainLooper();
}
+
+ @Provides
+ ContentResolver provideContentResolver() {
+ return mApplication.getContentResolver();
+ }
}
diff --git a/common/src/com/android/tv/common/experiments/Experiments.java b/common/src/com/android/tv/common/experiments/Experiments.java
index 6dfa46b..9bfdb54 100644
--- a/common/src/com/android/tv/common/experiments/Experiments.java
+++ b/common/src/com/android/tv/common/experiments/Experiments.java
@@ -27,11 +27,6 @@
* <p>This file is maintained by hand.
*/
public final class Experiments {
- public static final ExperimentFlag<Boolean> CLOUD_EPG =
- ExperimentFlag.createFlag(
-// AOSP_Comment_Out LiveChannels::enableCloudEpg,
- true);
-
public static final ExperimentFlag<Boolean> ENABLE_UNRATED_CONTENT_SETTINGS =
ExperimentFlag.createFlag(
// AOSP_Comment_Out LiveChannels::enableUnratedContentSettings,
diff --git a/common/src/com/android/tv/common/feature/EngOnlyFeature.java b/common/src/com/android/tv/common/feature/BuildTypeFeature.java
similarity index 66%
rename from common/src/com/android/tv/common/feature/EngOnlyFeature.java
rename to common/src/com/android/tv/common/feature/BuildTypeFeature.java
index 5feb548..9e1704e 100644
--- a/common/src/com/android/tv/common/feature/EngOnlyFeature.java
+++ b/common/src/com/android/tv/common/feature/BuildTypeFeature.java
@@ -20,18 +20,23 @@
import com.android.tv.common.BuildConfig;
/** A feature that is only available on {@link BuildConfig#ENG} builds. */
-public final class EngOnlyFeature implements Feature {
- public static final Feature ENG_ONLY_FEATURE = new EngOnlyFeature();
+public final class BuildTypeFeature implements Feature {
+ public static final Feature ENG_ONLY_FEATURE = new BuildTypeFeature(BuildConfig.ENG);
+ public static final Feature ASOP_FEATURE = new BuildTypeFeature(BuildConfig.AOSP);
- private EngOnlyFeature() {}
+ private final boolean mIsBuildType;
+
+ private BuildTypeFeature(boolean isBuildType) {
+ mIsBuildType = isBuildType;
+ }
@Override
public boolean isEnabled(Context context) {
- return BuildConfig.ENG;
+ return mIsBuildType;
}
@Override
public String toString() {
- return "EngOnlyFeature(" + BuildConfig.ENG + ")";
+ return getClass().getSimpleName() + "(" + mIsBuildType + ")";
}
}
diff --git a/common/src/com/android/tv/common/feature/CommonFeatures.java b/common/src/com/android/tv/common/feature/CommonFeatures.java
index 62986f3..04052a7 100644
--- a/common/src/com/android/tv/common/feature/CommonFeatures.java
+++ b/common/src/com/android/tv/common/feature/CommonFeatures.java
@@ -16,14 +16,13 @@
package com.android.tv.common.feature;
-import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
+import static com.android.tv.common.feature.BuildTypeFeature.ENG_ONLY_FEATURE;
import static com.android.tv.common.feature.FeatureUtils.and;
import static com.android.tv.common.feature.FeatureUtils.or;
import static com.android.tv.common.feature.TestableFeature.createTestableFeature;
import android.content.Context;
import android.util.Log;
-import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.flags.has.HasCloudEpgFlags;
import com.android.tv.common.util.LocationUtils;
import com.android.tv.common.flags.CloudEpgFlags;
@@ -57,28 +56,25 @@
/** Show postal code fragment before channel scan. */
public static final Feature ENABLE_CLOUD_EPG_REGION =
- and(
- ExperimentFeature.from(Experiments.CLOUD_EPG),
- or(
- FlagFeature.from(
- HasCloudEpgFlags::fromContext, CloudEpgFlags::supportedRegion),
- new Feature() {
- private final String[] supportedRegions = {
-// AOSP_Comment_Out "US", "GB"
- };
+ or(
+ FlagFeature.from(HasCloudEpgFlags::fromContext, CloudEpgFlags::supportedRegion),
+ new Feature() {
+ private final String[] supportedRegions = {
+// AOSP_Comment_Out "US", "GB"
+ };
- @Override
- public boolean isEnabled(Context context) {
- String country = LocationUtils.getCurrentCountry(context);
- for (int i = 0; i < supportedRegions.length; i++) {
- if (supportedRegions[i].equalsIgnoreCase(country)) {
- return true;
- }
- }
- if (DEBUG) Log.d(TAG, "EPG flag false after country check");
- return false;
+ @Override
+ public boolean isEnabled(Context context) {
+ String country = LocationUtils.getCurrentCountry(context);
+ for (int i = 0; i < supportedRegions.length; i++) {
+ if (supportedRegions[i].equalsIgnoreCase(country)) {
+ return true;
}
- }));
+ }
+ if (DEBUG) Log.d(TAG, "EPG flag false after country check");
+ return false;
+ }
+ });
// TODO(b/74197177): remove when UI and API finalized.
/** Show channel signal strength. */
diff --git a/common/src/com/android/tv/common/flags/BackendKnobsFlags.java b/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
index 553c227..2f9d451 100644
--- a/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
+++ b/common/src/com/android/tv/common/flags/BackendKnobsFlags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -21,15 +21,14 @@
/**
* Whether or not this feature is compiled into this build.
*
- * <p>If the macro which generated this code does not have condtional_compilation_enabled as
- * true, then this always returns true.
- *
- * <p>If the macro which generated this code does have conditional_compilation_enabled as true,
- * this will return true or false depending on the value of the corresponding
- * config_feature_flag controlling this feature. See go/phenotype-compile-time-features.
+ * <p>This returns true by default, unless the is_compiled_selector parameter was set during
+ * code generation.
*/
boolean compiled();
+ /** Enable fetching only part of the program data. */
+ boolean enablePartialProgramFetch();
+
/** EPG fetcher interval in hours */
long epgFetcherIntervalHour();
diff --git a/common/src/com/android/tv/common/flags/CloudEpgFlags.java b/common/src/com/android/tv/common/flags/CloudEpgFlags.java
index 824ec71..ab4c6a1 100755
--- a/common/src/com/android/tv/common/flags/CloudEpgFlags.java
+++ b/common/src/com/android/tv/common/flags/CloudEpgFlags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -21,12 +21,8 @@
/**
* Whether or not this feature is compiled into this build.
*
- * <p>If the macro which generated this code does not have condtional_compilation_enabled as
- * true, then this always returns true.
- *
- * <p>If the macro which generated this code does have conditional_compilation_enabled as true,
- * this will return true or false depending on the value of the corresponding
- * config_feature_flag controlling this feature. See go/phenotype-compile-time-features.
+ * <p>This returns true by default, unless the is_compiled_selector parameter was set during
+ * code generation.
*/
boolean compiled();
diff --git a/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java b/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java
index 7ea74cc..76e1788 100755
--- a/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java
+++ b/common/src/com/android/tv/common/flags/ConcurrentDvrPlaybackFlags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -21,12 +21,8 @@
/**
* Whether or not this feature is compiled into this build.
*
- * <p>If the macro which generated this code does not have condtional_compilation_enabled as
- * true, then this always returns true.
- *
- * <p>If the macro which generated this code does have conditional_compilation_enabled as true,
- * this will return true or false depending on the value of the corresponding
- * config_feature_flag controlling this feature. See go/phenotype-compile-time-features.
+ * <p>This returns true by default, unless the is_compiled_selector parameter was set during
+ * code generation.
*/
boolean compiled();
diff --git a/common/src/com/android/tv/common/flags/Exoplayer2Flags.java b/common/src/com/android/tv/common/flags/Exoplayer2Flags.java
index 03175cf..4a3956f 100755
--- a/common/src/com/android/tv/common/flags/Exoplayer2Flags.java
+++ b/common/src/com/android/tv/common/flags/Exoplayer2Flags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -21,12 +21,8 @@
/**
* Whether or not this feature is compiled into this build.
*
- * <p>If the macro which generated this code does not have condtional_compilation_enabled as
- * true, then this always returns true.
- *
- * <p>If the macro which generated this code does have conditional_compilation_enabled as true,
- * this will return true or false depending on the value of the corresponding
- * config_feature_flag controlling this feature. See go/phenotype-compile-time-features.
+ * <p>This returns true by default, unless the is_compiled_selector parameter was set during
+ * code generation.
*/
boolean compiled();
diff --git a/common/src/com/android/tv/common/flags/TunerFlags.java b/common/src/com/android/tv/common/flags/TunerFlags.java
new file mode 100755
index 0000000..f1d9111
--- /dev/null
+++ b/common/src/com/android/tv/common/flags/TunerFlags.java
@@ -0,0 +1,31 @@
+/*
+ * 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 tuner */
+public interface TunerFlags {
+
+ /**
+ * 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();
+
+ /** Tune using current recording if available. */
+ boolean tuneUsingRecording();
+}
diff --git a/common/src/com/android/tv/common/flags/UiFlags.java b/common/src/com/android/tv/common/flags/UiFlags.java
index b69411f..55767aa 100755
--- a/common/src/com/android/tv/common/flags/UiFlags.java
+++ b/common/src/com/android/tv/common/flags/UiFlags.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -21,15 +21,14 @@
/**
* Whether or not this feature is compiled into this build.
*
- * <p>If the macro which generated this code does not have condtional_compilation_enabled as
- * true, then this always returns true.
- *
- * <p>If the macro which generated this code does have conditional_compilation_enabled as true,
- * this will return true or false depending on the value of the corresponding
- * config_feature_flag controlling this feature. See go/phenotype-compile-time-features.
+ * <p>This returns true by default, unless the is_compiled_selector parameter was set during
+ * code generation.
*/
boolean compiled();
/** Unhide the launcher all the time */
boolean uhideLauncher();
+
+ /** Use the Leanback Pin Picker */
+ boolean useLeanbackPinPicker();
}
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 2805581..53688af 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultBackendKnobsFlags.java
@@ -25,6 +25,11 @@
}
@Override
+ public boolean enablePartialProgramFetch() {
+ return false;
+ }
+
+ @Override
public long epgFetcherIntervalHour() {
return 25;
}
@@ -36,7 +41,7 @@
@Override
public long programGuideMaxHours() {
- return 168;
+ return 336;
}
@Override
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java b/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java
new file mode 100644
index 0000000..3ff6ddf
--- /dev/null
+++ b/common/src/com/android/tv/common/flags/impl/DefaultFlagsModule.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ConcurrentDvrPlaybackFlags;
+import com.android.tv.common.flags.Exoplayer2Flags;
+import com.android.tv.common.flags.TunerFlags;
+import com.android.tv.common.flags.UiFlags;
+
+/** Provides default flags. */
+@Module
+public class DefaultFlagsModule {
+
+ @Provides
+ @Reusable
+ BackendKnobsFlags provideBackendKnobsFlags() {
+ return new DefaultBackendKnobsFlags();
+ }
+
+ @Provides
+ @Reusable
+ CloudEpgFlags provideCloudEpgFlags() {
+ return new DefaultCloudEpgFlags();
+ }
+
+ @Provides
+ @Reusable
+ ConcurrentDvrPlaybackFlags provideConcurrentDvrPlaybackFlags() {
+ return new DefaultConcurrentDvrPlaybackFlags();
+ }
+
+ @Provides
+ @Reusable
+ Exoplayer2Flags provideExoplayer2Flags() {
+ return new DefaultExoplayer2Flags();
+ }
+
+ @Provides
+ @Reusable
+ TunerFlags provideTunerFlags() {
+ return new DefaultTunerFlags();
+ }
+
+ @Provides
+ @Reusable
+ UiFlags provideUiFlags() {
+ return new DefaultUiFlags();
+ }
+}
diff --git a/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java b/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java
new file mode 100644
index 0000000..2494100
--- /dev/null
+++ b/common/src/com/android/tv/common/flags/impl/DefaultTunerFlags.java
@@ -0,0 +1,32 @@
+/*
+ * 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.flags.impl;
+
+import com.android.tv.common.flags.TunerFlags;
+
+/** Default Flags for Tuner */
+public class DefaultTunerFlags implements TunerFlags {
+
+ @Override
+ public boolean compiled() {
+ return true;
+ }
+
+ @Override
+ public boolean tuneUsingRecording() {
+ 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 2eb3d2f..bc7a418 100644
--- a/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java
+++ b/common/src/com/android/tv/common/flags/impl/DefaultUiFlags.java
@@ -29,4 +29,9 @@
public boolean uhideLauncher() {
return false;
}
+
+ @Override
+ public boolean useLeanbackPinPicker() {
+ return false;
+ }
}
diff --git a/partner_support/src/com/google/android/tv/partner/support/EpgInputs.java b/partner_support/src/com/google/android/tv/partner/support/EpgInputs.java
index 53485ec..dddcd08 100644
--- a/partner_support/src/com/google/android/tv/partner/support/EpgInputs.java
+++ b/partner_support/src/com/google/android/tv/partner/support/EpgInputs.java
@@ -59,6 +59,8 @@
result.add(EpgInput.createEpgChannel(contentValues));
}
return result;
+ } catch (Exception e) {
+ return Collections.emptySet();
}
}
diff --git a/res/values/strings-custom.xml b/res/values/strings-custom.xml
new file mode 100644
index 0000000..22f7331
--- /dev/null
+++ b/res/values/strings-custom.xml
@@ -0,0 +1,22 @@
+<?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.
+ -->
+<resources>
+
+ <!-- Name of application [CHAR LIMIT=NONE] -->
+ <string name="app_name" translatable="false">Live TV</string>
+
+</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f7d9312..3682475 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -26,9 +26,6 @@
<string name="option_item_divider_font" translatable="false">@string/condensed_font</string>
- <!-- Name of application [CHAR LIMIT=NONE] -->
- <string name="app_name" translatable="false">Live TV</string>
-
<!-- Title of an application permission, listed so the user can choose
whether they want to allow the application to do this. -->
<string name="permlab_receiveInputEvent" translatable="false">receive input events from <xliff:g id="app_name">Live TV</xliff:g> app</string>
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index 12b1634..3da1523 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -136,6 +136,7 @@
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment;
import com.android.tv.util.AsyncDbTask;
+import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.CaptionSettings;
import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.RecurringRunner;
@@ -151,6 +152,7 @@
import com.google.common.base.Optional;
import dagger.android.AndroidInjection;
import dagger.android.ContributesAndroidInjector;
+import com.android.tv.common.flags.BackendKnobsFlags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
@@ -260,6 +262,7 @@
}
private final MySingletonsImpl mMySingletons = new MySingletonsImpl();
+ @Inject @DbExecutor Executor mDbExecutor;
private AccessibilityManager mAccessibilityManager;
@Inject ChannelDataManager mChannelDataManager;
@@ -274,6 +277,7 @@
private final DurationTimer mTuneDurationTimer = new DurationTimer();
private DvrManager mDvrManager;
private ConflictChecker mDvrConflictChecker;
+ private BackendKnobsFlags mBackendKnobs;
@Inject SetupUtils mSetupUtils;
@Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
@@ -438,12 +442,14 @@
public void onInputAdded(String inputId) {
if (mOptionalBuiltInTunerManager.isPresent()
&& CommonPreferences.shouldShowSetupActivity(MainActivity.this)) {
- String tunerInputId =
- mOptionalBuiltInTunerManager.get().getEmbeddedTunerInputId();
+ BuiltInTunerManager builtInTunerManager =
+ mOptionalBuiltInTunerManager.get();
+ String tunerInputId = builtInTunerManager.getEmbeddedTunerInputId();
if (tunerInputId.equals(inputId)) {
Intent intent =
- TvSingletons.getSingletons(MainActivity.this)
- .getTunerSetupIntent(MainActivity.this);
+ builtInTunerManager
+ .getTunerInputController()
+ .createSetupIntent(MainActivity.this);
startActivity(intent);
CommonPreferences.setShouldShowSetupActivity(MainActivity.this, false);
mSetupUtils.markAsKnownInput(tunerInputId);
@@ -490,6 +496,7 @@
finishAndRemoveTask();
return;
}
+ mBackendKnobs = tvSingletons.getBackendKnobs();
TvSingletons tvApplication = (TvSingletons) getApplication();
// In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
@@ -1495,7 +1502,7 @@
long channelIdFromIntent = ContentUriUtils.safeParseId(mInitChannelUri);
if (programUriFromIntent != null && channelIdFromIntent != Channel.INVALID_ID) {
new AsyncQueryProgramTask(
- TvSingletons.getSingletons(this).getDbExecutor(),
+ mDbExecutor,
programUriFromIntent,
Program.PROJECTION,
null,
@@ -2817,6 +2824,11 @@
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.MyOnTuneListener.onTune");
mChannel = channel;
mWasUnderShrunkenTvView = wasUnderShrunkenTvView;
+
+ if (mBackendKnobs.enablePartialProgramFetch()) {
+ // Fetch complete projection of tuned channel.
+ mProgramDataManager.prefetchChannel(channel.getId());
+ }
}
@Override
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 9ff6471..5185b12 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -28,7 +28,6 @@
import android.util.Log;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.actions.InputSetupActionUtils;
-import com.android.tv.common.experiments.Experiments;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelDataManager.Listener;
import com.android.tv.data.epg.EpgFetcher;
@@ -70,9 +69,7 @@
mEpgInputWhiteList = new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
mActivityAfterCompletion = InputSetupActionUtils.getExtraActivityAfter(intent);
boolean needToFetchEpg =
- mTvInputInfo != null
- && Utils.isInternalTvInput(this, mTvInputInfo.getId())
- && Experiments.CLOUD_EPG.get();
+ mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId());
if (needToFetchEpg) {
// In case when the activity is restored, this flag should be restored as well.
mEpgFetcherDuringScan = true;
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index 2eb94a8..5f25a24 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -36,10 +36,8 @@
import android.view.KeyEvent;
import android.widget.Toast;
import com.android.tv.common.BaseApplication;
-import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.recording.RecordingStorageStatusManager;
-import com.android.tv.common.singletons.HasTvInputId;
import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
import com.android.tv.common.util.Clock;
import com.android.tv.common.util.Debug;
@@ -64,14 +62,14 @@
import com.android.tv.recommendation.RecordedProgramPreviewUpdater;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.android.tv.tunerinputcontroller.TunerInputController;
+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 java.util.List;
import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import javax.inject.Inject;
/**
@@ -99,10 +97,6 @@
private static final String PREFERENCE_IS_FIRST_LAUNCH = "is_first_launch";
- private static final NamedThreadFactory THREAD_FACTORY = new NamedThreadFactory("tv-app-db");
- private static final ExecutorService DB_EXECUTOR =
- Executors.newSingleThreadExecutor(THREAD_FACTORY);
-
private String mVersionName = "";
private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
@@ -121,12 +115,13 @@
// STOP-SHIP: Remove this variable when Tuner Process is split to another application.
// When this variable is null, we don't know in which process TvApplication runs.
private Boolean mRunningInMainProcess;
- private TvInputManagerHelper mTvInputManagerHelper;
+ @Inject Lazy<TvInputManagerHelper> mLazyTvInputManagerHelper;
private boolean mStarted;
private EpgFetcher mEpgFetcher;
- @Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
+ @Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
@Inject SetupUtils mSetupUtils;
+ @Inject @DbExecutor Executor mDbExecutor;
@Override
public void onCreate() {
@@ -365,11 +360,7 @@
/** Returns {@link TvInputManagerHelper}. */
@Override
public TvInputManagerHelper getTvInputManagerHelper() {
- if (mTvInputManagerHelper == null) {
- mTvInputManagerHelper = new TvInputManagerHelper(this);
- mTvInputManagerHelper.start();
- }
- return mTvInputManagerHelper;
+ return mLazyTvInputManagerHelper.get();
}
@Override
@@ -495,8 +486,9 @@
if (!enable) {
List<TvInputInfo> inputs = inputManager.getTvInputList();
boolean skipTunerInputCheck = false;
- Optional<String> optionalEmbeddedTunerInputId = getBuiltInTunerManager()
- .transform(HasTvInputId::getEmbeddedTunerInputId);
+ Optional<String> optionalEmbeddedTunerInputId =
+ mOptionalBuiltInTunerManager.transform(
+ BuiltInTunerManager::getEmbeddedTunerInputId);
// Enable the TvActivity only if there is at least one tuner type input.
if (!skipTunerInputCheck) {
for (TvInputInfo input : inputs) {
@@ -530,6 +522,6 @@
@Override
public Executor getDbExecutor() {
- return DB_EXECUTOR;
+ return mDbExecutor;
}
}
diff --git a/src/com/android/tv/TvSingletons.java b/src/com/android/tv/TvSingletons.java
index ae2ff0d..20edf3d 100644
--- a/src/com/android/tv/TvSingletons.java
+++ b/src/com/android/tv/TvSingletons.java
@@ -116,6 +116,8 @@
ExperimentLoader getExperimentLoader();
+ /** @deprecated use injection instead. */
+ @Deprecated
Executor getDbExecutor();
BackendKnobsFlags getBackendKnobs();
diff --git a/src/com/android/tv/app/LiveTvApplication.java b/src/com/android/tv/app/LiveTvApplication.java
index c65d45e..38e85e4 100644
--- a/src/com/android/tv/app/LiveTvApplication.java
+++ b/src/com/android/tv/app/LiveTvApplication.java
@@ -16,15 +16,11 @@
package com.android.tv.app;
-import android.content.Context;
-import android.content.Intent;
-import com.android.tv.TvActivity;
import com.android.tv.TvApplication;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.StubAnalytics;
import com.android.tv.analytics.Tracker;
-import com.android.tv.common.actions.InputSetupActionUtils;
import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
@@ -32,13 +28,11 @@
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.common.util.CommonUtils;
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.tuner.setup.LiveTvTunerSetupActivity;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.android.tv.util.account.AccountHelper;
import com.android.tv.util.account.AccountHelperImpl;
@@ -70,15 +64,14 @@
private AccountHelper mAccountHelper;
private Analytics mAnalytics;
private Tracker mTracker;
- private String mEmbeddedInputId;
private ExperimentLoader mExperimentLoader;
private PerformanceMonitor mPerformanceMonitor;
@Override
protected AndroidInjector<LiveTvApplication> applicationInjector() {
return DaggerLiveTvApplicationComponent.builder()
- .tvSingletonsModule(new TvSingletonsModule(this))
.applicationModule(new ApplicationModule(this))
+ .tvSingletonsModule(new TvSingletonsModule(this))
.build();
}
@@ -140,19 +133,6 @@
}
@Override
- public Intent getTunerSetupIntent(Context context) {
- // Make an intent to launch the setup activity of TV tuner input.
- Intent intent =
- CommonUtils.createSetupIntent(
- new Intent(context, LiveTvTunerSetupActivity.class), mEmbeddedInputId);
- intent.putExtra(InputSetupActionUtils.EXTRA_INPUT_ID, mEmbeddedInputId);
- Intent tvActivityIntent = new Intent(context, TvActivity.class);
-
- intent.putExtra(InputSetupActionUtils.EXTRA_ACTIVITY_AFTER_COMPLETION, tvActivityIntent);
- return intent;
- }
-
- @Override
public DefaultCloudEpgFlags getCloudEpgFlags() {
return mCloudEpgFlags;
}
diff --git a/src/com/android/tv/app/LiveTvModule.java b/src/com/android/tv/app/LiveTvModule.java
index b821379..a28749b 100644
--- a/src/com/android/tv/app/LiveTvModule.java
+++ b/src/com/android/tv/app/LiveTvModule.java
@@ -15,15 +15,15 @@
*/
package com.android.tv.app;
+import com.android.tv.common.flags.impl.DefaultFlagsModule;
import com.android.tv.modules.TvApplicationModule;
-import com.android.tv.tuner.setup.LiveTvTunerSetupActivity;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.google.common.base.Optional;
import dagger.Module;
import dagger.Provides;
/** Dagger module for {@link LiveTvApplication}. */
-@Module(includes = {TvApplicationModule.class, LiveTvTunerSetupActivity.Module.class})
+@Module(includes = {DefaultFlagsModule.class, TvApplicationModule.class})
class LiveTvModule {
@Provides
diff --git a/src/com/android/tv/data/Program.java b/src/com/android/tv/data/Program.java
index 0119db2..b688927 100644
--- a/src/com/android/tv/data/Program.java
+++ b/src/com/android/tv/data/Program.java
@@ -89,6 +89,16 @@
public static final String[] PROJECTION = createProjection();
+ public static final String[] PARTIAL_PROJECTION = {
+ TvContract.Programs._ID,
+ TvContract.Programs.COLUMN_CHANNEL_ID,
+ TvContract.Programs.COLUMN_TITLE,
+ TvContract.Programs.COLUMN_EPISODE_TITLE,
+ TvContract.Programs.COLUMN_CANONICAL_GENRE,
+ TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
+ TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS,
+ };
+
private static String[] createProjection() {
return CollectionUtils.concatAll(
PROJECTION_BASE,
@@ -154,6 +164,21 @@
return builder.build();
}
+ /** Creates {@code Program} object from cursor. */
+ public static Program fromCursorPartialProjection(Cursor cursor) {
+ // Columns read must match the order of match {@link #PARTIAL_PROJECTION}
+ Builder builder = new Builder();
+ int index = 0;
+ builder.setId(cursor.getLong(index++));
+ builder.setChannelId(cursor.getLong(index++));
+ builder.setTitle(cursor.getString(index++));
+ builder.setEpisodeTitle(cursor.getString(index++));
+ builder.setCanonicalGenres(cursor.getString(index++));
+ builder.setStartTimeUtcMillis(cursor.getLong(index++));
+ builder.setEndTimeUtcMillis(cursor.getLong(index++));
+ return builder.build();
+ }
+
public static Program fromParcel(Parcel in) {
Program program = new Program();
program.mId = in.readLong();
diff --git a/src/com/android/tv/data/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index aa4948e..2f20c89 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -108,14 +108,15 @@
private final MultiLongSparseArray<OnCurrentProgramUpdatedListener>
mChannelId2ProgramUpdatedListeners = new MultiLongSparseArray<>();
private final Handler mHandler;
- private final Set<Listener> mListeners = new ArraySet<>();
+ private final Set<Callback> mCallbacks = new ArraySet<>();
+ private Map<Long, ArrayList<Program>> mChannelIdProgramCache = new ConcurrentHashMap<>();
+ private final Set<Long> mCompleteInfoChannelIds = new HashSet<>();
private final ContentObserver mProgramObserver;
private boolean mPrefetchEnabled;
private long mProgramPrefetchUpdateWaitMs;
private long mLastPrefetchTaskRunMs;
private ProgramsPrefetchTask mProgramsPrefetchTask;
- private Map<Long, ArrayList<Program>> mChannelIdProgramCache = new HashMap<>();
// Any program that ends prior to this time will be removed from the cache
// when a channel's current program is updated.
@@ -258,24 +259,43 @@
}
}
- /** A listener interface to receive notification on program data retrieval from DB. */
- public interface Listener {
+ public void prefetchChannel(long channelId) {
+ 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();
+ }
+ }
+
+ /** A Callback interface to receive notification on program data retrieval from DB. */
+ public interface Callback {
/**
* Called when a Program data is now available through getProgram() after the DB operation
* is done which wasn't before. This would be called only if fetched data is around the
* selected program.
*/
void onProgramUpdated();
+
+ /**
+ * Called when we update complete program data of specific channel during scrolling. Data is
+ * loaded from DB on request basis.
+ *
+ * @param channelId
+ */
+ void onSingleChannelUpdated(long channelId);
}
- /** Adds the {@link Listener}. */
- public void addListener(Listener listener) {
- mListeners.add(listener);
+ /** Adds the {@link Callback}. */
+ public void addCallback(Callback callback) {
+ mCallbacks.add(callback);
}
- /** Removes the {@link Listener}. */
- public void removeListener(Listener listener) {
- mListeners.remove(listener);
+ /** Removes the {@link Callback}. */
+ public void removeCallback(Callback callback) {
+ mCallbacks.remove(callback);
}
/** Enables or Disables program prefetch. */
@@ -480,26 +500,7 @@
long time = mClock.currentTimeMillis();
mStartTimeMs =
Utils.floorTime(time - PROGRAM_GUIDE_SNAP_TIME_MS, PROGRAM_GUIDE_SNAP_TIME_MS);
- long durationHours;
- if (mChannelIdProgramCache.isEmpty()) {
- durationHours = Math.max(1L, mBackendKnobsFlags.programGuideInitialFetchHours());
- } else {
- int channelCount = mChannelDataManager.getChannelCount();
- long knobsMaxHours = mBackendKnobsFlags.programGuideMaxHours();
- long targetChannelCount = mBackendKnobsFlags.epgTargetChannelCount();
- if (channelCount <= targetChannelCount) {
- durationHours = Math.max(48L, knobsMaxHours);
- } else {
- // 2 days <= duration <= 14 days (336 hours)
- durationHours = knobsMaxHours * targetChannelCount / channelCount;
- if (durationHours < 48L) {
- durationHours = 48L;
- } else if (durationHours > 336L) {
- durationHours = 336L;
- }
- }
- }
- mEndTimeMs = mStartTimeMs + TimeUnit.HOURS.toMillis(durationHours);
+ mEndTimeMs = mStartTimeMs + TimeUnit.HOURS.toMillis(getFetchDuration());
mSuccess = false;
}
@@ -538,10 +539,15 @@
}
programMap.clear();
- String[] projection = Program.PROJECTION;
+ String[] projection =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.PARTIAL_PROJECTION
+ : Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(mContext, Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
- projection = TvProviderUtils.addExtraColumnsToProjection(projection);
+ projection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ projection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
}
}
try (Cursor c = mContentResolver.query(uri, projection, null, null, SORT_BY_TIME)) {
@@ -556,7 +562,10 @@
}
return null;
}
- Program program = Program.fromCursor(c);
+ Program program =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.fromCursorPartialProjection(c)
+ : Program.fromCursor(c);
if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
@@ -566,6 +575,15 @@
ArrayList<Program> programs = programMap.get(program.getChannelId());
if (programs == null) {
programs = new ArrayList<>();
+ 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);
@@ -615,6 +633,10 @@
nextMessageDelayedTime = 0;
}
mChannelIdProgramCache = programs;
+ 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(
@@ -632,9 +654,70 @@
}
}
+ private long getFetchDuration() {
+ if (mChannelIdProgramCache.isEmpty()) {
+ return Math.max(1L, mBackendKnobsFlags.programGuideInitialFetchHours());
+ } else {
+ long durationHours;
+ int channelCount = mChannelDataManager.getChannelCount();
+ long knobsMaxHours = mBackendKnobsFlags.programGuideMaxHours();
+ long targetChannelCount = mBackendKnobsFlags.epgTargetChannelCount();
+ if (channelCount <= targetChannelCount) {
+ durationHours = Math.max(48L, knobsMaxHours);
+ } else {
+ // 2 days <= duration <= 14 days (336 hours)
+ durationHours = knobsMaxHours * targetChannelCount / channelCount;
+ if (durationHours < 48L) {
+ durationHours = 48L;
+ } else if (durationHours > 336L) {
+ durationHours = 336L;
+ }
+ }
+ return durationHours;
+ }
+ }
+
+ private class SingleChannelPrefetchTask extends AsyncDbTask.AsyncQueryTask<ArrayList<Program>> {
+ long mChannelId;
+
+ public SingleChannelPrefetchTask(long channelId, long startTimeMs, long endTimeMs) {
+ super(
+ mDbExecutor,
+ mContext,
+ TvContract.buildProgramsUriForChannel(channelId, startTimeMs, endTimeMs),
+ Program.PROJECTION,
+ null,
+ null,
+ SORT_BY_TIME);
+ mChannelId = channelId;
+ }
+
+ @Override
+ protected ArrayList<Program> onQuery(Cursor c) {
+ ArrayList<Program> programMap = new ArrayList<>();
+ while (c.moveToNext()) {
+ Program program = Program.fromCursor(c);
+ programMap.add(program);
+ }
+ return programMap;
+ }
+
+ @Override
+ protected void onPostExecute(ArrayList<Program> programs) {
+ mChannelIdProgramCache.put(mChannelId, programs);
+ notifySingleChannelUpdated(mChannelId);
+ }
+ }
+
private void notifyProgramUpdated() {
- for (Listener listener : mListeners) {
- listener.onProgramUpdated();
+ for (Callback callback : mCallbacks) {
+ callback.onProgramUpdated();
+ }
+ }
+
+ private void notifySingleChannelUpdated(long channelId) {
+ for (Callback callback : mCallbacks) {
+ callback.onSingleChannelUpdated(channelId);
}
}
@@ -694,6 +777,9 @@
for (Long channelId : removedChannelIds) {
if (mPrefetchEnabled) {
mChannelIdProgramCache.remove(channelId);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mCompleteInfoChannelIds.remove(channelId);
+ }
}
mChannelIdCurrentProgramMap.remove(channelId);
notifyCurrentProgramUpdate(channelId, null);
diff --git a/src/com/android/tv/data/epg/EpgFetchHelper.java b/src/com/android/tv/data/epg/EpgFetchHelper.java
index e56185d..3843ca9 100644
--- a/src/com/android/tv/data/epg/EpgFetchHelper.java
+++ b/src/com/android/tv/data/epg/EpgFetchHelper.java
@@ -201,7 +201,9 @@
Context context, long channelId, long startTimeMs, long endTimeMs) {
String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
- projection = TvProviderUtils.addExtraColumnsToProjection(projection);
+ projection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ projection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
}
try (Cursor c =
context.getContentResolver()
diff --git a/src/com/android/tv/data/epg/EpgFetcherImpl.java b/src/com/android/tv/data/epg/EpgFetcherImpl.java
index 0251e66..b191421 100644
--- a/src/com/android/tv/data/epg/EpgFetcherImpl.java
+++ b/src/com/android/tv/data/epg/EpgFetcherImpl.java
@@ -41,6 +41,7 @@
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.util.Clock;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.LocationUtils;
@@ -60,6 +61,7 @@
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.android.tv.common.flags.BackendKnobsFlags;
import java.io.IOException;
import java.util.ArrayList;
@@ -114,7 +116,9 @@
private final ChannelDataManager mChannelDataManager;
private final EpgReader mEpgReader;
private final PerformanceMonitor mPerformanceMonitor;
+ private final EpgInputWhiteList mEpgInputWhiteList;
private final BackendKnobsFlags mBackendKnobsFlags;
+ private final HasBuildType.BuildType mBuildType;
private FetchAsyncTask mFetchTask;
private FetchDuringScanHandler mFetchDuringScanHandler;
private long mEpgTimeStamp;
@@ -133,30 +137,39 @@
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);
+ backendKnobsFlags,
+ buildType);
}
@VisibleForTesting
EpgFetcherImpl(
Context context,
+ EpgInputWhiteList epgInputWhiteList,
ChannelDataManager channelDataManager,
EpgReader epgReader,
PerformanceMonitor performanceMonitor,
Clock clock,
- BackendKnobsFlags backendKnobsFlags) {
+ BackendKnobsFlags backendKnobsFlags,
+ HasBuildType.BuildType buildType) {
mContext = context;
mChannelDataManager = channelDataManager;
mEpgReader = epgReader;
mPerformanceMonitor = performanceMonitor;
mClock = clock;
+ mEpgInputWhiteList = epgInputWhiteList;
mBackendKnobsFlags = backendKnobsFlags;
+ mBuildType = buildType;
}
private long getFastFetchDurationSec() {
@@ -352,6 +365,19 @@
if (DEBUG) Log.d(TAG, "Cannot start routine service: scanning channels.");
return false;
}
+ if (!TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.isEnabled(mContext)
+ && mBuildType != HasBuildType.BuildType.AOSP) {
+ if (getTunerChannelCount() == 0) {
+ if (DEBUG) Log.d(TAG, "Cannot start routine service: no internal tuner channels.");
+ return false;
+ }
+ if (!TextUtils.isEmpty(EpgFetchHelper.getLastLineupId(mContext))) {
+ return true;
+ }
+ if (!TextUtils.isEmpty(PostalCodeUtils.getLastPostalCode(mContext))) {
+ return true;
+ }
+ }
return true;
}
@@ -511,6 +537,17 @@
return numbers.size();
}
+ private boolean isInputInWhiteList(EpgInput epgInput) {
+ if (mBuildType == HasBuildType.BuildType.AOSP) {
+ return false;
+ }
+ return (BuildConfig.ENG
+ && epgInput.getInputId()
+ .equals(
+ "com.example.partnersupportsampletvinput/.SampleTvInputService"))
+ || mEpgInputWhiteList.isInputWhiteListed(epgInput.getInputId());
+ }
+
@VisibleForTesting
class FetchAsyncTask extends AsyncTask<Void, Void, Integer> {
private final JobService mService;
@@ -538,12 +575,45 @@
Integer builtInResult = fetchEpgForBuiltInTuner();
boolean anyCloudEpgFailure = false;
boolean anyCloudEpgSuccess = false;
+ if (TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.isEnabled(mContext)
+ && mBuildType != HasBuildType.BuildType.AOSP) {
+ for (EpgInput epgInput : getEpgInputs()) {
+ if (DEBUG) Log.d(TAG, "Start EPG fetch for " + epgInput);
+ if (isCancelled()) {
+ break;
+ }
+ if (isInputInWhiteList(epgInput)) {
+ // TODO(b/66191312) check timestamp and result code and decide if update
+ // is needed.
+ Set<Channel> channels = getExistingChannelsFor(epgInput.getInputId());
+ Integer result = fetchEpgFor(epgInput.getLineupId(), channels);
+ anyCloudEpgFailure = anyCloudEpgFailure || result != null;
+ anyCloudEpgSuccess = anyCloudEpgSuccess || result == null;
+ updateCloudEpgInput(epgInput, result);
+ } else {
+ Log.w(
+ TAG,
+ "Fetching the EPG for "
+ + epgInput.getInputId()
+ + " is not supported.");
+ }
+ }
+ }
+ if (builtInResult == null || builtInResult == REASON_NO_BUILT_IN_CHANNELS) {
+ return anyCloudEpgFailure
+ ? ((Integer) REASON_CLOUD_EPG_FAILURE)
+ : anyCloudEpgSuccess ? null : builtInResult;
+ }
return builtInResult;
} finally {
TrafficStats.setThreadStatsTag(oldTag);
}
}
+ private void updateCloudEpgInput(EpgInput unusedEpgInput, Integer unusedResult) {
+ // TODO(b/66191312) write the result and timestamp to the input table
+ }
+
private Set<Channel> getExistingChannelsFor(String inputId) {
Set<Channel> result = new HashSet<>();
try (Cursor cursor =
@@ -563,6 +633,15 @@
}
}
+ private Set<EpgInput> getEpgInputs() {
+ if (mBuildType == HasBuildType.BuildType.AOSP) {
+ return ImmutableSet.of();
+ }
+ Set<EpgInput> epgInputs = EpgInputs.queryEpgInputs(mContext.getContentResolver());
+ if (DEBUG) Log.d(TAG, "getEpgInputs " + epgInputs);
+ return epgInputs;
+ }
+
private Integer fetchEpgForBuiltInTuner() {
try {
Integer failureReason = prepareFetchEpg(false);
diff --git a/src/com/android/tv/dvr/data/RecordedProgram.java b/src/com/android/tv/dvr/data/RecordedProgram.java
index d40904e..899e65a 100644
--- a/src/com/android/tv/dvr/data/RecordedProgram.java
+++ b/src/com/android/tv/dvr/data/RecordedProgram.java
@@ -122,11 +122,10 @@
}
index++;
if (TvProviderUtils.getRecordedProgramHasSeriesIdColumn()) {
- builder.setSeriesId(StringUtils.nullToEmpty(cursor.getString(index)));
+ builder.setSeriesId(StringUtils.nullToEmpty(cursor.getString(index++)));
}
- index++;
if (TvProviderUtils.getRecordedProgramHasStateColumn()) {
- builder.setState(cursor.getString(index));
+ builder.setState(cursor.getString(index++));
}
return builder.build();
}
diff --git a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
index 8654e6e..696038c 100644
--- a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
+++ b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
@@ -29,7 +29,6 @@
import android.util.LongSparseArray;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.util.CollectionUtils;
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.data.Program;
@@ -260,14 +259,11 @@
}
private void executeFetchSeriesInfoTask(SeriesRecording seriesRecording) {
- if (Experiments.CLOUD_EPG.get()) {
- FetchSeriesInfoTask task =
- new FetchSeriesInfoTask(
- seriesRecording,
- TvSingletons.getSingletons(mContext).providesEpgReader());
- task.execute();
- mFetchSeriesInfoTasks.put(seriesRecording.getId(), task);
- }
+ FetchSeriesInfoTask task =
+ new FetchSeriesInfoTask(
+ seriesRecording, TvSingletons.getSingletons(mContext).providesEpgReader());
+ task.execute();
+ mFetchSeriesInfoTasks.put(seriesRecording.getId(), task);
}
/** Pauses the updates of the series recordings. */
diff --git a/src/com/android/tv/features/TvFeatures.java b/src/com/android/tv/features/TvFeatures.java
index 4f6e8d9..208d53f 100644
--- a/src/com/android/tv/features/TvFeatures.java
+++ b/src/com/android/tv/features/TvFeatures.java
@@ -16,10 +16,12 @@
package com.android.tv.features;
-import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
+import static com.android.tv.common.feature.BuildTypeFeature.ASOP_FEATURE;
+import static com.android.tv.common.feature.BuildTypeFeature.ENG_ONLY_FEATURE;
import static com.android.tv.common.feature.FeatureUtils.OFF;
import static com.android.tv.common.feature.FeatureUtils.ON;
import static com.android.tv.common.feature.FeatureUtils.and;
+import static com.android.tv.common.feature.FeatureUtils.not;
import static com.android.tv.common.feature.FeatureUtils.or;
import android.content.Context;
@@ -39,7 +41,6 @@
import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.common.util.PermissionUtils;
-
/**
* List of {@link Feature} for the Live TV App.
*
@@ -60,6 +61,24 @@
*/
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);
+
+ /**
+ * Enable cloud EPG for third parties.
+ *
+ * @see <a href="http://go/cloud-epg-3p-proposal">go/cloud-epg-3p-proposal</a>
+ */
+ // TODO verify customization for N
+ public static final TestableFeature CLOUD_EPG_FOR_3RD_PARTY =
+ TestableFeature.createTestableFeature(
+ and(
+ not(ASOP_FEATURE),
+ // TODO(b/66696290): use newer version of robolectric.
+ or(
+ TV_PROVIDER_ALLOWS_INSERT_TO_PROGRAM_TABLE,
+ FeatureUtils.ROBOLECTRIC)));
+
// TODO(b/76149661): Fix EPG search or remove it
public static final Feature EPG_SEARCH = OFF;
@@ -70,7 +89,7 @@
context -> HasSingletons.get(HasUiFlags.class, context),
input -> input.getUiFlags().uhideLauncher()),
// If LC app runs as non-system app, we unhide the app.
- FeatureUtils.not(PermissionUtils::hasAccessAllEpg));
+ not(PermissionUtils::hasAccessAllEpg));
public static final Feature PICTURE_IN_PICTURE =
new Feature() {
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index 69e2d68..bc1b11b 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -65,6 +65,7 @@
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.BackendKnobsFlags;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -182,14 +183,17 @@
Runnable preShowRunnable,
Runnable postHideRunnable) {
mActivity = activity;
- mPerformanceMonitor = TvSingletons.getSingletons(mActivity).getPerformanceMonitor();
+ TvSingletons singletons = TvSingletons.getSingletons(mActivity);
+ mPerformanceMonitor = singletons.getPerformanceMonitor();
+ BackendKnobsFlags backendKnobsFlags = singletons.getBackendKnobs();
mProgramManager =
new ProgramManager(
tvInputManagerHelper,
channelDataManager,
programDataManager,
dvrDataManager,
- dvrScheduleManager);
+ dvrScheduleManager,
+ backendKnobsFlags);
mChannelTuner = channelTuner;
mTracker = tracker;
mPreShowRunnable = preShowRunnable;
diff --git a/src/com/android/tv/guide/ProgramManager.java b/src/com/android/tv/guide/ProgramManager.java
index 9a70ddd..3a5a4a0 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -32,6 +32,7 @@
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;
@@ -59,6 +60,7 @@
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;
@@ -114,12 +116,26 @@
}
};
- private final ProgramDataManager.Listener mProgramDataManagerListener =
- new ProgramDataManager.Listener() {
+ private final ProgramDataManager.Callback mProgramDataManagerCallback =
+ new ProgramDataManager.Callback() {
@Override
public void onProgramUpdated() {
updateTableEntries(true);
}
+
+ @Override
+ 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();
+ }
};
private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
@@ -199,19 +215,21 @@
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) {
mProgramDataManager.setPauseProgramUpdate(visible);
if (visible) {
mChannelDataManager.addListener(mChannelDataManagerListener);
- mProgramDataManager.addListener(mProgramDataManagerListener);
+ mProgramDataManager.addCallback(mProgramDataManagerCallback);
if (mDvrDataManager != null) {
if (!mDvrDataManager.isDvrScheduleLoadFinished()) {
mDvrDataManager.addDvrScheduleLoadFinishedListener(mDvrLoadedListener);
@@ -224,7 +242,7 @@
}
} else {
mChannelDataManager.removeListener(mChannelDataManagerListener);
- mProgramDataManager.removeListener(mProgramDataManagerListener);
+ mProgramDataManager.removeCallback(mProgramDataManagerCallback);
if (mDvrDataManager != null) {
mDvrDataManager.removeDvrScheduleLoadFinishedListener(mDvrLoadedListener);
mDvrDataManager.removeScheduledRecordingListener(mScheduledRecordingListener);
@@ -413,6 +431,9 @@
* (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
*/
TableEntry getTableEntry(long channelId, int index) {
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mProgramDataManager.prefetchChannel(channelId);
+ }
return mChannelIdEntriesMap.get(channelId).get(index);
}
diff --git a/src/com/android/tv/modules/TvApplicationModule.java b/src/com/android/tv/modules/TvApplicationModule.java
index a252723..45383ae 100644
--- a/src/com/android/tv/modules/TvApplicationModule.java
+++ b/src/com/android/tv/modules/TvApplicationModule.java
@@ -15,11 +15,20 @@
*/
package com.android.tv.modules;
+import android.content.Context;
import com.android.tv.MainActivity;
import com.android.tv.TvApplication;
+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.onboarding.OnboardingActivity;
+import com.android.tv.util.AsyncDbTask;
+import com.android.tv.util.TvInputManagerHelper;
import dagger.Module;
+import dagger.Provides;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import javax.inject.Singleton;
/** Dagger module for {@link TvApplication}. */
@Module(
@@ -29,4 +38,21 @@
MainActivity.Module.class,
OnboardingActivity.Module.class
})
-public class TvApplicationModule {}
+public class TvApplicationModule {
+ private static final NamedThreadFactory THREAD_FACTORY = new NamedThreadFactory("tv-app-db");
+
+ @Provides
+ @AsyncDbTask.DbExecutor
+ @Singleton
+ Executor providesDbExecutor() {
+ return Executors.newSingleThreadExecutor(THREAD_FACTORY);
+ }
+
+ @Provides
+ @Singleton
+ TvInputManagerHelper providesTvInputManagerHelper(@ApplicationContext Context context) {
+ TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context);
+ tvInputManagerHelper.start();
+ return tvInputManagerHelper;
+ }
+}
diff --git a/src/com/android/tv/modules/TvSingletonsModule.java b/src/com/android/tv/modules/TvSingletonsModule.java
index 3959347..f998c08 100644
--- a/src/com/android/tv/modules/TvSingletonsModule.java
+++ b/src/com/android/tv/modules/TvSingletonsModule.java
@@ -18,7 +18,6 @@
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.util.TvInputManagerHelper;
import dagger.Module;
import dagger.Provides;
@@ -28,6 +27,7 @@
* <p>Use this module to inject items directly instead of using {@code TvSingletons}.
*/
@Module
+@SuppressWarnings("deprecation")
public class TvSingletonsModule {
private final TvSingletons mTvSingletons;
@@ -44,9 +44,4 @@
ProgramDataManager providesProgramDataManager() {
return mTvSingletons.getProgramDataManager();
}
-
- @Provides
- TvInputManagerHelper providesTvInputManagerHelper() {
- return mTvSingletons.getTvInputManagerHelper();
- }
}
diff --git a/src/com/android/tv/receiver/BootCompletedReceiver.java b/src/com/android/tv/receiver/BootCompletedReceiver.java
index 8ed926e..0eb03be 100644
--- a/src/com/android/tv/receiver/BootCompletedReceiver.java
+++ b/src/com/android/tv/receiver/BootCompletedReceiver.java
@@ -70,7 +70,7 @@
// Grant permission to already set up packages after the system has finished booting.
SetupUtils.grantEpgPermissionToSetUpPackages(context);
- if (TvFeatures.UNHIDE.isEnabled(context)) {
+ if (TvFeatures.UNHIDE.isEnabled(context.getApplicationContext())) {
if (OnboardingUtils.isFirstBoot(context)) {
// Enable the application if this is the first "unhide" feature is enabled just in
// case when the app has been disabled before.
diff --git a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
index 7dea255..2590a33 100644
--- a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
+++ b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
@@ -174,7 +174,7 @@
for (Channel channel : channels) {
if (channel.isPhysicalTunerChannel()) {
final Program program =
- Utils.getCurrentProgram(mContext, channel.getId());
+ Utils.getCurrentProgram(mContext, channel.getId());
if (program != null
&& isChannelRecommendationApplicable(channel, program)) {
programs.add(program);
@@ -246,6 +246,17 @@
}
}
});
+ } else if (mJobService != null && mJobParams != null) {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "Preview channel not created because there is only "
+ + programs.size()
+ + " programs");
+ }
+ mJobService.jobFinished(mJobParams, false);
+ mJobService = null;
+ mJobParams = null;
}
} else {
updatePreviewProgramsForPreviewChannel(
diff --git a/src/com/android/tv/search/DataManagerSearch.java b/src/com/android/tv/search/DataManagerSearch.java
index 304ef98..a649c0a 100644
--- a/src/com/android/tv/search/DataManagerSearch.java
+++ b/src/com/android/tv/search/DataManagerSearch.java
@@ -249,7 +249,7 @@
result.setIntentData(buildIntentData(channelId));
result.setContentType(Programs.CONTENT_ITEM_TYPE);
result.setIsLive(true);
- result.setProgressPercentage(LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE);
+ result.setProgressPercentage(SearchInterface.PROGRESS_PERCENTAGE_HIDE);
} else {
result.setTitle(program.getTitle());
result.setDescription(
@@ -293,7 +293,7 @@
private int getProgressPercentage(long startUtcMillis, long endUtcMillis) {
long current = System.currentTimeMillis();
if (startUtcMillis > current || endUtcMillis <= current) {
- return LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE;
+ return SearchInterface.PROGRESS_PERCENTAGE_HIDE;
}
return (int) (100 * (current - startUtcMillis) / (endUtcMillis - startUtcMillis));
}
diff --git a/src/com/android/tv/search/LocalSearchProvider.java b/src/com/android/tv/search/LocalSearchProvider.java
index 7f15f66..5652c98 100644
--- a/src/com/android/tv/search/LocalSearchProvider.java
+++ b/src/com/android/tv/search/LocalSearchProvider.java
@@ -49,8 +49,6 @@
/** The authority for LocalSearchProvider. */
public static final String AUTHORITY = CommonConstants.BASE_PACKAGE + ".search";
- public static final int PROGRESS_PERCENTAGE_HIDE = -1;
-
// TODO: Remove this once added to the SearchManager.
private static final String SUGGEST_COLUMN_PROGRESS_BAR_PERCENTAGE = "progress_bar_percentage";
diff --git a/src/com/android/tv/search/SearchInterface.java b/src/com/android/tv/search/SearchInterface.java
index 4866ee8..d16270e 100644
--- a/src/com/android/tv/search/SearchInterface.java
+++ b/src/com/android/tv/search/SearchInterface.java
@@ -26,6 +26,7 @@
int ACTION_TYPE_SWITCH_CHANNEL = 2;
int ACTION_TYPE_SWITCH_INPUT = 3;
int ACTION_TYPE_END = 3;
+ int PROGRESS_PERCENTAGE_HIDE = -1;
/**
* Search channels, inputs, or programs. This assumes that parental control settings will not be
diff --git a/src/com/android/tv/search/TvProviderSearch.java b/src/com/android/tv/search/TvProviderSearch.java
index e267fad..8a1f51f 100644
--- a/src/com/android/tv/search/TvProviderSearch.java
+++ b/src/com/android/tv/search/TvProviderSearch.java
@@ -271,7 +271,7 @@
result.setIntentData(buildIntentData(id));
result.setContentType(Programs.CONTENT_ITEM_TYPE);
result.setIsLive(true);
- result.setProgressPercentage(LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE);
+ result.setProgressPercentage(SearchInterface.PROGRESS_PERCENTAGE_HIDE);
searchResults.add(result.build());
@@ -344,7 +344,7 @@
private int getProgressPercentage(long startUtcMillis, long endUtcMillis) {
long current = System.currentTimeMillis();
if (startUtcMillis > current || endUtcMillis <= current) {
- return LocalSearchProvider.PROGRESS_PERCENTAGE_HIDE;
+ return SearchInterface.PROGRESS_PERCENTAGE_HIDE;
}
return (int) (100 * (current - startUtcMillis) / (endUtcMillis - startUtcMillis));
}
diff --git a/src/com/android/tv/tunerinputcontroller/TunerInputController.java b/src/com/android/tv/tunerinputcontroller/TunerInputController.java
index 6c3df1c..f822dbe 100644
--- a/src/com/android/tv/tunerinputcontroller/TunerInputController.java
+++ b/src/com/android/tv/tunerinputcontroller/TunerInputController.java
@@ -17,10 +17,13 @@
package com.android.tv.tunerinputcontroller;
import android.content.Context;
+import android.content.Intent;
/** Controls the package visibility of built in tuner services. */
public interface TunerInputController {
+ Intent createSetupIntent(Context context);
+
void onCheckingUsbTunerStatus(Context context, String action);
void executeNetworkTunerDiscoveryAsyncTask(Context context);
diff --git a/src/com/android/tv/util/AsyncDbTask.java b/src/com/android/tv/util/AsyncDbTask.java
index 261a1ef..b352395 100644
--- a/src/com/android/tv/util/AsyncDbTask.java
+++ b/src/com/android/tv/util/AsyncDbTask.java
@@ -40,6 +40,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
+import javax.inject.Qualifier;
/**
* {@link AsyncTask} that defaults to executing on its own single threaded Executor Service.
@@ -53,6 +54,10 @@
private static final String TAG = "AsyncDbTask";
private static final boolean DEBUG = false;
+ /** Annotation for requesting the {@link Executor} for data base access. */
+ @Qualifier
+ public @interface DbExecutor {}
+
private final Executor mExecutor;
boolean mCalledExecuteOnDbThread;
@@ -78,7 +83,7 @@
private String[] mProjection;
public AsyncQueryTask(
- Executor executor,
+ @DbExecutor Executor executor,
Context context,
Uri uri,
String[] projection,
@@ -117,14 +122,24 @@
if (context == null) {
return null;
}
- if ((Utils.isProgramsUri(mUri)
- && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI))
- || (Utils.isRecordedProgramsUri(mUri)
- && TvProviderUtils.checkSeriesIdColumn(
- context, TvContract.RecordedPrograms.CONTENT_URI)
- && TvProviderUtils.checkStateColumn(
- context, TvContract.RecordedPrograms.CONTENT_URI))) {
- mProjection = TvProviderUtils.addExtraColumnsToProjection(mProjection);
+ if (Utils.isProgramsUri(mUri)
+ && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
+ mProjection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ mProjection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
+ } else if (Utils.isRecordedProgramsUri(mUri)) {
+ if (TvProviderUtils.checkSeriesIdColumn(
+ context, TvContract.RecordedPrograms.CONTENT_URI)) {
+ mProjection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ mProjection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
+ }
+ if (TvProviderUtils.checkStateColumn(
+ context, TvContract.RecordedPrograms.CONTENT_URI)) {
+ mProjection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ mProjection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_STATE);
+ }
}
if (DEBUG) {
Log.v(TAG, "Starting query for " + this);
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index 6d2095c..cb7d985 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -38,6 +38,7 @@
import android.util.Log;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.compat.TvInputInfoCompat;
+import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.SystemProperties;
import com.android.tv.features.TvFeatures;
@@ -53,9 +54,12 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Singleton;
/** Helper class for {@link TvInputManager}. */
@UiThread
+@Singleton
public class TvInputManagerHelper {
private static final String TAG = "TvInputManagerHelper";
private static final boolean DEBUG = false;
@@ -287,7 +291,8 @@
private final Comparator<TvInputInfo> mTvInputInfoComparator;
private boolean mAllow3rdPartyInputs;
- public TvInputManagerHelper(Context context) {
+ @Inject
+ public TvInputManagerHelper(@ApplicationContext Context context) {
this(context, createTvInputManagerWrapper(context));
}
diff --git a/src/com/android/tv/util/TvProviderUtils.java b/src/com/android/tv/util/TvProviderUtils.java
index 67673f3..6b5aaec 100644
--- a/src/com/android/tv/util/TvProviderUtils.java
+++ b/src/com/android/tv/util/TvProviderUtils.java
@@ -23,11 +23,14 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.StringDef;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.android.tv.data.BaseProgram;
import com.android.tv.features.PartnerFeatures;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -42,6 +45,11 @@
public static final String EXTRA_PROGRAM_COLUMN_SERIES_ID = BaseProgram.COLUMN_SERIES_ID;
public static final String EXTRA_PROGRAM_COLUMN_STATE = BaseProgram.COLUMN_STATE;
+ /** Possible extra columns in TV provider. */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({EXTRA_PROGRAM_COLUMN_SERIES_ID, EXTRA_PROGRAM_COLUMN_STATE})
+ public @interface TvProviderExtraColumn {}
+
private static boolean sProgramHasSeriesIdColumn;
private static boolean sRecordedProgramHasSeriesIdColumn;
private static boolean sRecordedProgramHasStateColumn;
@@ -136,13 +144,11 @@
return TRUE.equals(sRecordedProgramHasStateColumn);
}
- public static String[] addExtraColumnsToProjection(String[] projection) {
+ public static String[] addExtraColumnsToProjection(String[] projection,
+ @TvProviderExtraColumn String column) {
List<String> projectionList = new ArrayList<>(Arrays.asList(projection));
- if (!projectionList.contains(EXTRA_PROGRAM_COLUMN_SERIES_ID)) {
- projectionList.add(EXTRA_PROGRAM_COLUMN_SERIES_ID);
- }
- if (!projectionList.contains(EXTRA_PROGRAM_COLUMN_STATE)) {
- projectionList.add(EXTRA_PROGRAM_COLUMN_STATE);
+ if (!projectionList.contains(column)) {
+ projectionList.add(column);
}
projection = projectionList.toArray(projection);
return projection;
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index 53ed82f..5117373 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -327,7 +327,9 @@
String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, TvContract.Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
- projection = TvProviderUtils.addExtraColumnsToProjection(projection);
+ projection =
+ TvProviderUtils.addExtraColumnsToProjection(
+ projection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
}
}
try (Cursor cursor = resolver.query(uri, projection, null, null, null)) {
diff --git a/tests/common/src/com/android/tv/testing/TestSingletonApp.java b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
index c918ba8..74fc192 100644
--- a/tests/common/src/com/android/tv/testing/TestSingletonApp.java
+++ b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
@@ -17,8 +17,6 @@
package com.android.tv.testing;
import android.app.Application;
-import android.content.Context;
-import android.content.Intent;
import android.media.tv.TvInputManager;
import android.os.AsyncTask;
import com.android.tv.InputSessionManager;
@@ -51,8 +49,9 @@
import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
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.TunerSessionFactory.HasTunerSessionFactory;
import com.android.tv.tuner.tvinput.factory.TunerSessionFactoryImpl;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.android.tv.util.SetupUtils;
@@ -64,10 +63,7 @@
/** Test application for Live TV. */
public class TestSingletonApp extends Application
- implements TvSingletons,
- TunerSingletons,
- HasTunerSessionFactory,
- HasSingletons<TvSingletons> {
+ implements TvSingletons, TunerSingletons, HasSingletons<TvSingletons> {
public final FakeClock fakeClock = FakeClock.createWithCurrentTime();
public final FakeEpgReader epgReader = new FakeEpgReader(fakeClock);
public final FakeEpgFetcher epgFetcher = new FakeEpgFetcher();
@@ -84,8 +80,13 @@
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 DefaultExoplayer2Flags(), mConcurrentDvrPlaybackFlags);
+ new TunerSessionFactoryImpl(
+ new DefaultExoplayer2Flags(),
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
private PerformanceMonitor mPerformanceMonitor;
private ChannelDataManager mChannelDataManager;
@@ -228,11 +229,6 @@
}
@Override
- public Intent getTunerSetupIntent(Context context) {
- return null;
- }
-
- @Override
public boolean isRunningInMainProcess() {
return false;
}
@@ -280,7 +276,6 @@
return mConcurrentDvrPlaybackFlags;
}
- @Override
public TunerSessionFactory getTunerSessionFactory() {
return mTunerSessionFactory;
}
diff --git a/tests/unit/src/com/android/tv/util/MockTvSingletons.java b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
index 534be83..fd4b43c 100644
--- a/tests/unit/src/com/android/tv/util/MockTvSingletons.java
+++ b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
@@ -17,7 +17,6 @@
package com.android.tv.util;
import android.content.Context;
-import android.content.Intent;
import com.android.tv.InputSessionManager;
import com.android.tv.MainActivityWrapper;
import com.android.tv.TvApplication;
@@ -184,11 +183,6 @@
}
@Override
- public Intent getTunerSetupIntent(Context context) {
- return mApp.getTunerSetupIntent(context);
- }
-
- @Override
public boolean isRunningInMainProcess() {
return mApp.isRunningInMainProcess();
}
diff --git a/tuner/SampleDvbTuner/Android.mk b/tuner/SampleDvbTuner/Android.mk
deleted file mode 100644
index 759c910..0000000
--- a/tuner/SampleDvbTuner/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Include all java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := SampleDvbTuner
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := \
- tv-guava-android-jar \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- tv-auto-value-jar \
- android-support-annotations \
- tv-error-prone-annotations-jar \
- jsr330 \
- tv-lib-dagger \
- tv-lib-exoplayer \
- tv-lib-exoplayer-v2-core \
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- tv-lib-dagger-android \
- live-channels-partner-support \
- live-tv-tuner \
- tv-common \
-
-LOCAL_ANNOTATION_PROCESSORS := \
- tv-guava-jre-jar \
- jsr330 \
- tv-lib-dagger-android-processor \
- tv-lib-dagger-compiler \
-
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := \
- dagger.internal.codegen.ComponentProcessor,dagger.android.processor.AndroidProcessor
-
-
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_SDK_VERSION := system_current
-LOCAL_MIN_SDK_VERSION := 23 # M
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-include $(BUILD_PACKAGE)
diff --git a/tuner/SampleDvbTuner/AndroidManifest.xml b/tuner/SampleDvbTuner/AndroidManifest.xml
index 5a73d4c..5ad927e 100755
--- a/tuner/SampleDvbTuner/AndroidManifest.xml
+++ b/tuner/SampleDvbTuner/AndroidManifest.xml
@@ -23,15 +23,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.FOREGROUND_SERVICE" />
<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" />
@@ -53,12 +50,10 @@
<application
android:name="com.android.tv.tuner.sample.dvb.app.SampleDvbTuner"
+ android:appComponentFactory="android.support.v4.app.CoreComponentFactory"
android:icon="@mipmap/ic_launcher"
android:label="@string/sample_dvb_tuner_app_name" >
- <activity
- android:name="com.google.android.gms.common.api.GoogleApiActivity"
- android:exported="false"
- android:theme="@android:style/Theme.Translucent.NoTitleBar" />
+
<activity
android:name="com.android.tv.tuner.sample.dvb.setup.SampleDvbTunerSetupActivity"
@@ -76,7 +71,7 @@
android:name="com.android.tv.tuner.sample.dvb.tvinput.SampleDvbTunerTvInputService"
android:label="@string/sample_dvb_tuner_app_name"
android:permission="android.permission.BIND_TV_INPUT"
- android:process="com.google.android.tv.tuner.sample.dvb.tvinput" >
+ android:process="com.android.tv.tuner.sample.dvb.tvinput" >
<intent-filter>
<action android:name="android.media.tv.TvInputService" />
</intent-filter>
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 47c2dc0..dc04228 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
@@ -37,5 +37,9 @@
<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="27" android:minSdkVersion="23"/>
- <application />
+ <application
+ android:name=".app.SampleDvbTuner"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/sample_dvb_tuner_app_name"
+ />
</manifest>
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 bbb6779..568e3c9 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
@@ -17,54 +17,42 @@
package com.android.tv.tuner.sample.dvb.app;
import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
import android.media.tv.TvContract;
import com.android.tv.common.BaseApplication;
-import com.android.tv.common.actions.InputSetupActionUtils;
-import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
-import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
-import com.android.tv.common.flags.impl.DefaultExoplayer2Flags;
import com.android.tv.common.singletons.HasSingletons;
-import com.android.tv.common.util.CommonUtils;
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.setup.LiveTvTunerSetupActivity;
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. */
public class SampleDvbTuner extends BaseApplication
implements SampleDvbSingletons, HasSingletons<SampleDvbSingletons> {
private String mEmbeddedInputId;
- private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
- private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
- new DefaultConcurrentDvrPlaybackFlags();
- private final DefaultExoplayer2Flags mExoplayer2Flags = new DefaultExoplayer2Flags();
- private final TunerSessionFactoryImpl mTunerSessionFactory =
- new TunerSessionFactoryImpl(mExoplayer2Flags, mConcurrentDvrPlaybackFlags);
+ @Inject CloudEpgFlags mCloudEpgFlags;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TunerSessionFactoryImpl mTunerSessionFactory;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
@Override
protected AndroidInjector<SampleDvbTuner> applicationInjector() {
return DaggerSampleDvbTunerComponent.builder()
+ .sampleDvbTunerModule(new SampleDvbTunerModule(this))
.tunerSingletonsModule(new TunerSingletonsModule(this))
.build();
}
@Override
- public Intent getTunerSetupIntent(Context context) {
- // Make an intent to launch the setup activity of TV tuner input.
- Intent intent =
- CommonUtils.createSetupIntent(
- new Intent(context, LiveTvTunerSetupActivity.class), mEmbeddedInputId);
- intent.putExtra(InputSetupActionUtils.EXTRA_INPUT_ID, mEmbeddedInputId);
- return intent;
- }
-
- @Override
public synchronized String getEmbeddedTunerInputId() {
if (mEmbeddedInputId == null) {
mEmbeddedInputId =
@@ -75,7 +63,7 @@
}
@Override
- public DefaultCloudEpgFlags getCloudEpgFlags() {
+ public CloudEpgFlags getCloudEpgFlags() {
return mCloudEpgFlags;
}
@@ -85,7 +73,7 @@
}
@Override
- public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ public ConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
return mConcurrentDvrPlaybackFlags;
}
@@ -94,7 +82,6 @@
return this;
}
- @Override
public TunerSessionFactory getTunerSessionFactory() {
return mTunerSessionFactory;
}
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerComponent.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerComponent.java
index cb529ce..e6c80ea 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerComponent.java
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/app/SampleDvbTunerComponent.java
@@ -18,7 +18,9 @@
import dagger.Component;
import dagger.android.AndroidInjectionModule;
import dagger.android.AndroidInjector;
+import javax.inject.Singleton;
/** Dagger component for {@link SampleDvbTuner}. */
+@Singleton
@Component(modules = {AndroidInjectionModule.class, SampleDvbTunerModule.class})
public interface SampleDvbTunerComponent extends AndroidInjector<SampleDvbTuner> {}
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 7297ff2..4da3ca9 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,9 +15,38 @@
*/
package com.android.tv.tuner.sample.dvb.app;
+import com.android.tv.common.flags.impl.DefaultFlagsModule;
+import com.android.tv.tuner.api.TunerFactory;
+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 = {TunerModule.class})
-class SampleDvbTunerModule {}
+@Module(
+ includes = {
+ 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 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 c85562a..f9ef29c 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
@@ -35,7 +35,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.BuiltInTunerHalFactory;
import com.android.tv.tuner.sample.dvb.R;
import com.android.tv.tuner.setup.BaseTunerSetupActivity;
import com.android.tv.tuner.setup.ConnectionTypeFragment;
@@ -96,9 +95,7 @@
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... arg0) {
- return BuiltInTunerHalFactory.INSTANCE.getTunerTypeAndCount(
- SampleDvbTunerSetupActivity.this)
- .first;
+ return mTunerFactory.getTunerTypeAndCount(SampleDvbTunerSetupActivity.this).first;
}
@Override
diff --git a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/tvinput/SampleDvbTunerTvInputService.java b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/tvinput/SampleDvbTunerTvInputService.java
index ae15aff..a31faa8 100644
--- a/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/tvinput/SampleDvbTunerTvInputService.java
+++ b/tuner/SampleDvbTuner/src/com/android/tv/tuner/sample/dvb/tvinput/SampleDvbTunerTvInputService.java
@@ -16,6 +16,18 @@
package com.android.tv.tuner.sample.dvb.tvinput;
import com.android.tv.tuner.tvinput.BaseTunerTvInputService;
+import dagger.android.ContributesAndroidInjector;
/** Sample DVB Tuner {@link android.media.tv.TvInputService}. */
-public class SampleDvbTunerTvInputService extends BaseTunerTvInputService {}
+public class SampleDvbTunerTvInputService extends BaseTunerTvInputService {
+
+ /**
+ * Exports {@link SampleDvbTunerTvInputService} for Dagger codegen to create the appropriate
+ * injector.
+ */
+ @dagger.Module
+ public abstract static class Module {
+ @ContributesAndroidInjector
+ abstract SampleDvbTunerTvInputService contributesSampleDvbTunerTvInputServiceInjector();
+ }
+}
diff --git a/tuner/SampleNetworkTuner/Android.mk b/tuner/SampleNetworkTuner/Android.mk
deleted file mode 100644
index 3fca65e..0000000
--- a/tuner/SampleNetworkTuner/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Include all java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := SampleNetworkTuner
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := \
- tv-guava-android-jar \
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- tv-auto-value-jar \
- android-support-annotations \
- tv-error-prone-annotations-jar \
- jsr330 \
- tv-lib-dagger \
- tv-lib-exoplayer \
- tv-lib-exoplayer-v2-core \
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- tv-lib-dagger-android \
- live-channels-partner-support \
- live-tv-tuner \
- tv-common \
-
-LOCAL_ANNOTATION_PROCESSORS := \
- tv-guava-jre-jar \
- jsr330 \
- tv-lib-dagger-android-processor\
- tv-lib-dagger-compiler \
-
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := \
- dagger.internal.codegen.ComponentProcessor,dagger.android.processor.AndroidProcessor
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_SDK_VERSION := system_current
-LOCAL_MIN_SDK_VERSION := 23 # M
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-include $(BUILD_PACKAGE)
diff --git a/tuner/SampleNetworkTuner/AndroidManifest.xml b/tuner/SampleNetworkTuner/AndroidManifest.xml
index 5e099d2..0ec9afc 100755
--- a/tuner/SampleNetworkTuner/AndroidManifest.xml
+++ b/tuner/SampleNetworkTuner/AndroidManifest.xml
@@ -23,7 +23,6 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<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" />
@@ -51,12 +50,10 @@
<application
android:name="com.android.tv.tuner.sample.network.app.SampleNetworkTuner"
+ android:appComponentFactory="android.support.v4.app.CoreComponentFactory"
android:icon="@mipmap/ic_launcher"
android:label="@string/sample_network_tuner_app_name" >
- <activity
- android:name="com.google.android.gms.common.api.GoogleApiActivity"
- android:exported="false"
- android:theme="@android:style/Theme.Translucent.NoTitleBar" />
+
<activity
android:name="com.android.tv.tuner.sample.network.setup.SampleNetworkTunerSetupActivity"
@@ -74,7 +71,7 @@
android:name="com.android.tv.tuner.sample.network.tvinput.SampleNetworkTunerTvInputService"
android:label="@string/sample_network_tuner_app_name"
android:permission="android.permission.BIND_TV_INPUT"
- android:process="com.google.android.tv.tuner.sample.network.tvinput" >
+ android:process="com.android.tv.tuner.sample.network.tvinput" >
<intent-filter>
<action android:name="android.media.tv.TvInputService" />
</intent-filter>
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 a678097..dddd8a4 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
@@ -37,5 +37,9 @@
<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="27" android:minSdkVersion="23"/>
- <application />
+ <application
+ android:name=".app.SampleNetworkTuner"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/sample_network_tuner_app_name"
+ />
</manifest>
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 5eb44e9..eb5b2ad 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
@@ -17,54 +17,42 @@
package com.android.tv.tuner.sample.network.app;
import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
import android.media.tv.TvContract;
import com.android.tv.common.BaseApplication;
-import com.android.tv.common.actions.InputSetupActionUtils;
-import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
-import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
-import com.android.tv.common.flags.impl.DefaultExoplayer2Flags;
import com.android.tv.common.singletons.HasSingletons;
-import com.android.tv.common.util.CommonUtils;
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.setup.LiveTvTunerSetupActivity;
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. */
public class SampleNetworkTuner extends BaseApplication
implements SampleNetworkSingletons, HasSingletons<SampleNetworkSingletons> {
private String mEmbeddedInputId;
- private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
- private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
- new DefaultConcurrentDvrPlaybackFlags();
- private final DefaultExoplayer2Flags mExoplayer2Flags = new DefaultExoplayer2Flags();
- private final TunerSessionFactoryImpl mTunerSessionFactory =
- new TunerSessionFactoryImpl(mExoplayer2Flags, mConcurrentDvrPlaybackFlags);
+ @Inject CloudEpgFlags mCloudEpgFlags;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TunerSessionFactoryImpl mTunerSessionFactory;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
@Override
protected AndroidInjector<SampleNetworkTuner> applicationInjector() {
return DaggerSampleNetworkTunerComponent.builder()
+ .sampleNetworkTunerModule(new SampleNetworkTunerModule(this))
.tunerSingletonsModule(new TunerSingletonsModule(this))
.build();
}
@Override
- public Intent getTunerSetupIntent(Context context) {
- // Make an intent to launch the setup activity of TV tuner input.
- Intent intent =
- CommonUtils.createSetupIntent(
- new Intent(context, LiveTvTunerSetupActivity.class), mEmbeddedInputId);
- intent.putExtra(InputSetupActionUtils.EXTRA_INPUT_ID, mEmbeddedInputId);
- return intent;
- }
-
- @Override
public synchronized String getEmbeddedTunerInputId() {
if (mEmbeddedInputId == null) {
mEmbeddedInputId =
@@ -75,7 +63,7 @@
}
@Override
- public DefaultCloudEpgFlags getCloudEpgFlags() {
+ public CloudEpgFlags getCloudEpgFlags() {
return mCloudEpgFlags;
}
@@ -85,7 +73,7 @@
}
@Override
- public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ public ConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
return mConcurrentDvrPlaybackFlags;
}
@@ -94,7 +82,6 @@
return this;
}
- @Override
public TunerSessionFactory getTunerSessionFactory() {
return mTunerSessionFactory;
}
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerComponent.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerComponent.java
index 71a20be..b10105b 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerComponent.java
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/app/SampleNetworkTunerComponent.java
@@ -18,7 +18,9 @@
import dagger.Component;
import dagger.android.AndroidInjectionModule;
import dagger.android.AndroidInjector;
+import javax.inject.Singleton;
/** Dagger component for {@link SampleNetworkTuner}. */
+@Singleton
@Component(modules = {AndroidInjectionModule.class, SampleNetworkTunerModule.class})
public interface SampleNetworkTunerComponent extends AndroidInjector<SampleNetworkTuner> {}
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 57e4ee6..d974e20 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,9 +15,38 @@
*/
package com.android.tv.tuner.sample.network.app;
+import com.android.tv.common.flags.impl.DefaultFlagsModule;
+import com.android.tv.tuner.api.TunerFactory;
+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 = {TunerModule.class})
-class SampleNetworkTunerModule {}
+@Module(
+ includes = {
+ 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 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 d11e62a..fd783c4 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
@@ -35,7 +35,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.BuiltInTunerHalFactory;
import com.android.tv.tuner.sample.network.R;
import com.android.tv.tuner.setup.BaseTunerSetupActivity;
import com.android.tv.tuner.setup.ConnectionTypeFragment;
@@ -96,8 +95,7 @@
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... arg0) {
- return BuiltInTunerHalFactory.INSTANCE.getTunerTypeAndCount(
- SampleNetworkTunerSetupActivity.this)
+ return mTunerFactory.getTunerTypeAndCount(SampleNetworkTunerSetupActivity.this)
.first;
}
diff --git a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/tvinput/SampleNetworkTunerTvInputService.java b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/tvinput/SampleNetworkTunerTvInputService.java
index e3abde5..de5ff22 100644
--- a/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/tvinput/SampleNetworkTunerTvInputService.java
+++ b/tuner/SampleNetworkTuner/src/com/android/tv/tuner/sample/network/tvinput/SampleNetworkTunerTvInputService.java
@@ -16,6 +16,19 @@
package com.android.tv.tuner.sample.network.tvinput;
import com.android.tv.tuner.tvinput.BaseTunerTvInputService;
+import dagger.android.ContributesAndroidInjector;
/** Sample DVB Tuner {@link android.media.tv.TvInputService}. */
-public class SampleNetworkTunerTvInputService extends BaseTunerTvInputService {}
+public class SampleNetworkTunerTvInputService extends BaseTunerTvInputService {
+
+ /**
+ * Exports {@link SampleNetworkTunerTvInputService} for Dagger codegen to create the appropriate
+ * injector.
+ */
+ @dagger.Module
+ public abstract static class Module {
+ @ContributesAndroidInjector
+ abstract SampleNetworkTunerTvInputService
+ contributesSampleNetworkTunerTvInputServiceInjector();
+ }
+}
diff --git a/tuner/src/com/android/tv/tuner/api/TunerFactory.java b/tuner/src/com/android/tv/tuner/api/TunerFactory.java
new file mode 100644
index 0000000..bc29c7c
--- /dev/null
+++ b/tuner/src/com/android/tv/tuner/api/TunerFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.api;
+
+import android.content.Context;
+import android.support.annotation.WorkerThread;
+import android.util.Pair;
+
+/** Factory for {@link Tuner}. */
+public interface TunerFactory {
+ @WorkerThread
+ Tuner createInstance(Context context);
+
+ boolean useBuiltInTuner(Context context);
+
+ @WorkerThread
+ Pair<Integer, Integer> getTunerTypeAndCount(Context context);
+}
diff --git a/tuner/src/com/android/tv/tuner/BuiltInTunerHalFactory.java b/tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java
similarity index 90%
rename from tuner/src/com/android/tv/tuner/BuiltInTunerHalFactory.java
rename to tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java
index 92e9c38..9a0be74 100644
--- a/tuner/src/com/android/tv/tuner/BuiltInTunerHalFactory.java
+++ b/tuner/src/com/android/tv/tuner/builtin/BuiltInTunerHalFactory.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.tuner;
+package com.android.tv.tuner.builtin;
import android.content.Context;
import android.support.annotation.WorkerThread;
@@ -22,17 +22,19 @@
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 BuiltInTunerHalFactory {
+public final class BuiltInTunerHalFactory implements TunerFactory {
private static final String TAG = "BuiltInTunerHalFactory";
private static final boolean DEBUG = false;
private Integer mBuiltInTunerType;
- public static final BuiltInTunerHalFactory INSTANCE = new BuiltInTunerHalFactory();
+ public static final TunerFactory INSTANCE = new BuiltInTunerHalFactory();
private BuiltInTunerHalFactory() {}
@@ -54,6 +56,7 @@
* @param context context for creating the TunerHal instance
* @return the TunerHal instance
*/
+ @Override
@WorkerThread
public synchronized Tuner createInstance(Context context) {
Tuner tunerHal = null;
@@ -68,11 +71,13 @@
* Returns if tuner input service would use built-in tuners instead of USB tuners or network
* tuners.
*/
+ @Override
public boolean useBuiltInTuner(Context context) {
return getBuiltInTunerType(context) != 0;
}
/** Gets the number of tuner devices currently present. */
+ @Override
@WorkerThread
public Pair<Integer, Integer> getTunerTypeAndCount(Context context) {
if (useBuiltInTuner(context)) {
diff --git a/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java b/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
index b5411d9..e48cb03 100644
--- a/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
+++ b/tuner/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
@@ -365,7 +365,9 @@
mMediaPeriod =
mSampleSource.createPeriod(
new MediaSource.MediaPeriodId(0),
- new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE));
+ new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE)
+// AOSP_Comment_Out , 0
+ );
mMediaPeriod.prepare(this, 0);
try {
mMediaPeriod.maybeThrowPrepareError();
diff --git a/tuner/src/com/android/tv/tuner/livetuner/LiveTvTunerTvInputService.java b/tuner/src/com/android/tv/tuner/livetuner/LiveTvTunerTvInputService.java
index f741fdb..92701db 100644
--- a/tuner/src/com/android/tv/tuner/livetuner/LiveTvTunerTvInputService.java
+++ b/tuner/src/com/android/tv/tuner/livetuner/LiveTvTunerTvInputService.java
@@ -17,6 +17,18 @@
package com.android.tv.tuner.livetuner;
import com.android.tv.tuner.tvinput.BaseTunerTvInputService;
+import dagger.android.ContributesAndroidInjector;
/** Live TV embedded tuner. */
-public class LiveTvTunerTvInputService extends BaseTunerTvInputService {}
+public class LiveTvTunerTvInputService extends BaseTunerTvInputService {
+
+ /**
+ * Exports {@link LiveTvTunerTvInputService} for Dagger codegen to create the appropriate
+ * injector.
+ */
+ @dagger.Module
+ public abstract static class Module {
+ @ContributesAndroidInjector
+ abstract LiveTvTunerTvInputService contributesLiveTvTunerTvInputServiceInjector();
+ }
+}
diff --git a/tuner/src/com/android/tv/tuner/modules/TunerModule.java b/tuner/src/com/android/tv/tuner/modules/TunerModule.java
index b0b58e8..4843f38 100644
--- a/tuner/src/com/android/tv/tuner/modules/TunerModule.java
+++ b/tuner/src/com/android/tv/tuner/modules/TunerModule.java
@@ -15,8 +15,9 @@
*/
package com.android.tv.tuner.modules;
+import com.android.tv.tuner.source.TunerSourceModule;
import dagger.Module;
/** Dagger module for TV Tuners. */
-@Module(includes = {TunerSingletonsModule.class})
+@Module(includes = {TunerSingletonsModule.class, TunerSourceModule.class})
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 00d7ff2..44f689b 100644
--- a/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java
+++ b/tuner/src/com/android/tv/tuner/setup/BaseTunerSetupActivity.java
@@ -22,6 +22,7 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -36,7 +37,6 @@
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
-import com.android.tv.common.BaseApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.ui.setup.SetupActivity;
@@ -44,11 +44,12 @@
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.common.util.AutoCloseableUtils;
import com.android.tv.common.util.PostalCodeUtils;
-import com.android.tv.tuner.BuiltInTunerHalFactory;
import com.android.tv.tuner.R;
import com.android.tv.tuner.api.Tuner;
+import com.android.tv.tuner.api.TunerFactory;
import com.android.tv.tuner.prefs.TunerPreferences;
import java.util.concurrent.Executor;
+import javax.inject.Inject;
/** The base setup activity class for tuner. */
public abstract class BaseTunerSetupActivity extends SetupActivity {
@@ -85,6 +86,7 @@
protected String mPreviousPostalCode;
protected boolean mActivityStopped;
protected boolean mPendingShowInitialFragment;
+ @Inject protected TunerFactory mTunerFactory;
private TunerHalCreator mTunerHalCreator;
@@ -93,11 +95,12 @@
if (DEBUG) {
Log.d(TAG, "onCreate");
}
+ super.onCreate(savedInstanceState);
mActivityStopped = false;
executeGetTunerTypeAndCountAsyncTask();
mTunerHalCreator =
- new TunerHalCreator(getApplicationContext(), AsyncTask.THREAD_POOL_EXECUTOR);
- super.onCreate(savedInstanceState);
+ new TunerHalCreator(
+ getApplicationContext(), AsyncTask.THREAD_POOL_EXECUTOR, mTunerFactory);
try {
// Updating postal code takes time, therefore we called it here for "warm-up".
mPreviousPostalCode = PostalCodeUtils.getLastPostalCode(this);
@@ -329,25 +332,28 @@
/**
* A callback to be invoked when the TvInputService is enabled or disabled.
*
+ * @param tunerSetupIntent
* @param context a {@link Context} instance
* @param enabled {@code true} for the {@link TunerTvInputService} to be enabled; otherwise
* {@code false}
*/
- public static void onTvInputEnabled(Context context, boolean enabled, Integer tunerType) {
+ public static void onTvInputEnabled(
+ Context context, boolean enabled, Integer tunerType, Intent tunerSetupIntent) {
// Send a notification for tuner setup if there's no channels and the tuner TV input
// setup has been not done.
boolean channelScanDoneOnPreference = TunerPreferences.isScanDone(context);
int channelCountOnPreference = TunerPreferences.getScannedChannelCount(context);
if (enabled && !channelScanDoneOnPreference && channelCountOnPreference == 0) {
TunerPreferences.setShouldShowSetupActivity(context, true);
- sendNotification(context, tunerType);
+ sendNotification(context, tunerType, tunerSetupIntent);
} else {
TunerPreferences.setShouldShowSetupActivity(context, false);
cancelNotification(context);
}
}
- private static void sendNotification(Context context, Integer tunerType) {
+ private static void sendNotification(
+ Context context, Integer tunerType, Intent tunerSetupIntent) {
SoftPreconditions.checkState(
tunerType != null, TAG, "tunerType is null when send notification");
if (tunerType == null) {
@@ -370,16 +376,16 @@
}
String contentText = resources.getString(contentTextId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- sendNotificationInternal(context, contentTitle, contentText);
+ sendNotificationInternal(context, contentTitle, contentText, tunerSetupIntent);
} else {
Bitmap largeIcon =
BitmapFactory.decodeResource(resources, R.drawable.recommendation_antenna);
- sendRecommendationCard(context, contentTitle, contentText, largeIcon);
+ sendRecommendationCard(context, contentTitle, contentText, largeIcon, tunerSetupIntent);
}
}
private static void sendNotificationInternal(
- Context context, String contentTitle, String contentText) {
+ Context context, String contentTitle, String contentText, Intent tunerSetupIntent) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(
@@ -396,7 +402,8 @@
context.getResources()
.getIdentifier(
TAG_ICON, TAG_DRAWABLE, context.getPackageName()))
- .setContentIntent(createPendingIntentForSetupActivity(context))
+ .setContentIntent(
+ createPendingIntentForSetupActivity(context, tunerSetupIntent))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.extend(new Notification.TvExtender())
.build();
@@ -406,10 +413,15 @@
/**
* Sends the recommendation card to start the tuner TV input setup activity.
*
+ * @param tunerSetupIntent
* @param context a {@link Context} instance
*/
private static void sendRecommendationCard(
- Context context, String contentTitle, String contentText, Bitmap largeIcon) {
+ Context context,
+ String contentTitle,
+ String contentText,
+ Bitmap largeIcon,
+ Intent tunerSetupIntent) {
// Build and send the notification.
Notification notification =
new NotificationCompat.BigPictureStyle(
@@ -427,7 +439,8 @@
TAG_DRAWABLE,
context.getPackageName()))
.setContentIntent(
- createPendingIntentForSetupActivity(context)))
+ createPendingIntentForSetupActivity(
+ context, tunerSetupIntent)))
.build();
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -438,13 +451,12 @@
* Returns a {@link PendingIntent} to launch the tuner TV input service.
*
* @param context a {@link Context} instance
+ * @param tunerSetupIntent
*/
- private static PendingIntent createPendingIntentForSetupActivity(Context context) {
+ private static PendingIntent createPendingIntentForSetupActivity(
+ Context context, Intent tunerSetupIntent) {
return PendingIntent.getActivity(
- context,
- 0,
- BaseApplication.getSingletons(context).getTunerSetupIntent(context),
- PendingIntent.FLAG_UPDATE_CURRENT);
+ context, 0, tunerSetupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/** Creates {@link Tuner} instances in a worker thread * */
@@ -454,14 +466,12 @@
@VisibleForTesting Tuner mTunerHal;
private TunerHalCreator.GenerateTunerHalTask mGenerateTunerHalTask;
private final Executor mExecutor;
+ private final TunerFactory mTunerFactory;
- TunerHalCreator(Context context) {
- this(context, AsyncTask.SERIAL_EXECUTOR);
- }
-
- TunerHalCreator(Context context, Executor executor) {
+ TunerHalCreator(Context context, Executor executor, TunerFactory tunerFactory) {
mContext = context;
mExecutor = executor;
+ mTunerFactory = tunerFactory;
}
/**
@@ -507,7 +517,7 @@
@WorkerThread
protected Tuner createInstance() {
- return BuiltInTunerHalFactory.INSTANCE.createInstance(mContext);
+ return mTunerFactory.createInstance(mContext);
}
class GenerateTunerHalTask extends AsyncTask<Void, Void, Tuner> {
diff --git a/tuner/src/com/android/tv/tuner/ChannelScanFileParser.java b/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
similarity index 95%
rename from tuner/src/com/android/tv/tuner/ChannelScanFileParser.java
rename to tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
index e27b084..43c584e 100644
--- a/tuner/src/com/android/tv/tuner/ChannelScanFileParser.java
+++ b/tuner/src/com/android/tv/tuner/setup/ChannelScanFileParser.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.tuner;
+package com.android.tv.tuner.setup;
import android.util.Log;
import com.android.tv.tuner.api.ScanChannel;
@@ -26,7 +26,7 @@
import java.util.List;
/** Parses plain text formatted scan files, which contain the list of channels. */
-public class ChannelScanFileParser {
+public final class ChannelScanFileParser {
private static final String TAG = "ChannelScanFileParser";
/**
@@ -65,4 +65,6 @@
}
return scanChannelList;
}
+
+ private ChannelScanFileParser(){}
}
diff --git a/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java b/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java
index ec965f3..741edc7 100644
--- a/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java
+++ b/tuner/src/com/android/tv/tuner/setup/LiveTvTunerSetupActivity.java
@@ -22,9 +22,7 @@
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.KeyEvent;
-import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.util.PostalCodeUtils;
-import com.android.tv.tuner.BuiltInTunerHalFactory;
import dagger.android.ContributesAndroidInjector;
/** An activity that serves tuner setup process. */
@@ -49,9 +47,7 @@
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... arg0) {
- return BuiltInTunerHalFactory.INSTANCE.getTunerTypeAndCount(
- LiveTvTunerSetupActivity.this)
- .first;
+ return mTunerFactory.getTunerTypeAndCount(LiveTvTunerSetupActivity.this).first;
}
@Override
@@ -98,9 +94,7 @@
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION) {
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED
- && Experiments.CLOUD_EPG.get()) {
+ 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,
diff --git a/tuner/src/com/android/tv/tuner/setup/ScanFragment.java b/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
index 6213da8..7d59284 100644
--- a/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
+++ b/tuner/src/com/android/tv/tuner/setup/ScanFragment.java
@@ -37,7 +37,6 @@
import android.widget.TextView;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.ui.setup.SetupFragment;
-import com.android.tv.tuner.ChannelScanFileParser;
import com.android.tv.tuner.R;
import com.android.tv.tuner.api.ScanChannel;
import com.android.tv.tuner.api.Tuner;
@@ -100,7 +99,7 @@
if (DEBUG) Log.d(TAG, "onCreateView");
View view = super.onCreateView(inflater, container, savedInstanceState);
mChannelNumbers = new ArrayList<>();
- mChannelDataManager = new ChannelDataManager(getActivity());
+ mChannelDataManager = new ChannelDataManager(getActivity().getApplicationContext());
mChannelDataManager.checkDataVersion(getActivity());
mAdapter = new ChannelAdapter();
mProgressBar = (ProgressBar) view.findViewById(R.id.tune_progress);
diff --git a/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java b/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
index abaebf3..48b17dc 100644
--- a/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
+++ b/tuner/src/com/android/tv/tuner/singletons/TunerSingletons.java
@@ -16,7 +16,6 @@
package com.android.tv.tuner.singletons;
import com.android.tv.common.singletons.HasTvInputId;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
/** Singletons used in tuner applications */
-public interface TunerSingletons extends HasTvInputId, TunerSessionFactory.HasTunerSessionFactory {}
+public interface TunerSingletons extends HasTvInputId {}
diff --git a/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java b/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
index 507ff03..28756a9 100644
--- a/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
+++ b/tuner/src/com/android/tv/tuner/source/TsDataSourceManager.java
@@ -22,45 +22,54 @@
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;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.Inject;
+import javax.inject.Provider;
/**
- * Manages {@link DataSource} for playback and recording. The class hides handling of {@link Tuner}
- * and {@link TsStreamer} from other classes. One TsDataSourceManager should be created for per
- * session.
+ * Manages {@link TsDataSource} for playback and recording. The class hides handling of {@link
+ * Tuner} and {@link TsStreamer} from other classes. One TsDataSourceManager should be created for
+ * per session.
*/
+@AutoFactory
public class TsDataSourceManager {
- private static final Object sLock = new Object();
private static final Map<TsDataSource, TsStreamer> sTsStreamers = new ConcurrentHashMap<>();
- private static int sSequenceId;
+ private static final AtomicInteger sSequenceId = new AtomicInteger();
- private final int mId;
+ private final int mId = sSequenceId.incrementAndGet();
private final boolean mIsRecording;
- private final TunerTsStreamerManager mTunerStreamerManager =
- TunerTsStreamerManager.getInstance();
+ private final TunerTsStreamerManager mTunerStreamerManager;
private boolean mKeepTuneStatus;
/**
- * Creates TsDataSourceManager to create and release {@link DataSource} which will be used for
- * playing and recording.
+ * Factory for {@link }TsDataSourceManager}.
*
- * @param isRecording {@code true} when for recording, {@code false} otherwise
- * @return {@link TsDataSourceManager}
+ * <p>This wrapper class keeps other classes from needing to reference the {@link AutoFactory}
+ * generated class.
*/
- public static TsDataSourceManager createSourceManager(boolean isRecording) {
- int id;
- synchronized (sLock) {
- id = ++sSequenceId;
+ public static final class Factory {
+ private final TsDataSourceManagerFactory mDelegate;
+
+ @Inject
+ public Factory(Provider<TunerTsStreamerManager> tunerStreamerManagerProvider) {
+ mDelegate = new TsDataSourceManagerFactory(tunerStreamerManagerProvider);
}
- return new TsDataSourceManager(id, isRecording);
+
+ public TsDataSourceManager create(boolean isRecording) {
+ return mDelegate.create(isRecording);
+ }
}
- private TsDataSourceManager(int id, boolean isRecording) {
- mId = id;
+ TsDataSourceManager(
+ boolean isRecording, @Provided TunerTsStreamerManager tunerStreamerManager) {
mIsRecording = isRecording;
+ this.mTunerStreamerManager = tunerStreamerManager;
mKeepTuneStatus = true;
}
@@ -114,10 +123,10 @@
}
/**
- * Indicates whether the underlying {@link TunerHal} should be kept or not when data source is
+ * Indicates whether the underlying {@link Tuner} should be kept or not when data source is
* being released. TODO: If b/30750953 is fixed, we can remove this function.
*
- * @param keepTuneStatus underlying {@link TunerHal} will be reused when data source releasing.
+ * @param keepTuneStatus underlying {@link Tuner} will be reused when data source releasing.
*/
public void setKeepTuneStatus(boolean keepTuneStatus) {
mKeepTuneStatus = keepTuneStatus;
diff --git a/tuner/src/com/android/tv/tuner/source/TunerSourceModule.java b/tuner/src/com/android/tv/tuner/source/TunerSourceModule.java
new file mode 100644
index 0000000..12d2de1
--- /dev/null
+++ b/tuner/src/com/android/tv/tuner/source/TunerSourceModule.java
@@ -0,0 +1,31 @@
+/*
+ * 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.source;
+
+import com.android.tv.tuner.api.TunerFactory;
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Singleton;
+
+/** Dagger module for TV Tuners Sources. */
+@Module()
+public class TunerSourceModule {
+ @Provides
+ @Singleton
+ TunerTsStreamerManager providesTunerTsStreamerManager(TunerFactory tunerFactory) {
+ return new TunerTsStreamerManager(tunerFactory);
+ }
+}
diff --git a/tuner/src/com/android/tv/tuner/source/TunerTsStreamerManager.java b/tuner/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
index 15e8d51..076206c 100644
--- a/tuner/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
+++ b/tuner/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
@@ -17,10 +17,11 @@
package com.android.tv.tuner.source;
import android.content.Context;
+import android.support.annotation.VisibleForTesting;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.AutoCloseableUtils;
-import com.android.tv.tuner.BuiltInTunerHalFactory;
import com.android.tv.tuner.api.Tuner;
+import com.android.tv.tuner.api.TunerFactory;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.ts.EventDetector.EventListener;
import java.util.HashMap;
@@ -28,13 +29,17 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import javax.inject.Inject;
+import javax.inject.Singleton;
/**
* Manages {@link TunerTsStreamer} for playback and recording. The class hides handling of {@link
* Tuner} from other classes. This class is used by {@link TsDataSourceManager}. Don't use this
* class directly.
*/
-class TunerTsStreamerManager {
+@Singleton
+@VisibleForTesting
+public class TunerTsStreamerManager {
// The lock will protect mStreamerFinder, mSourceToStreamerMap and some part of TsStreamCreator
// to support timely {@link TunerTsStreamer} cancellation due to a new tune request from
// the same session.
@@ -43,23 +48,14 @@
private final Map<Integer, TsStreamerCreator> mCreators = new HashMap<>();
private final Map<Integer, EventListener> mListeners = new HashMap<>();
private final Map<TsDataSource, TunerTsStreamer> mSourceToStreamerMap = new HashMap<>();
- private final TunerHalManager mTunerHalManager = new TunerHalManager();
- private static TunerTsStreamerManager sInstance;
+ private final TunerHalManager mTunerHalManager;
- /**
- * Returns the singleton instance for the class
- *
- * @return TunerTsStreamerManager
- */
- static synchronized TunerTsStreamerManager getInstance() {
- if (sInstance == null) {
- sInstance = new TunerTsStreamerManager();
- }
- return sInstance;
+ @Inject
+ @VisibleForTesting
+ public TunerTsStreamerManager(TunerFactory tunerFactory) {
+ mTunerHalManager = new TunerHalManager(tunerFactory);
}
- private TunerTsStreamerManager() {}
-
synchronized TsDataSource createDataSource(
Context context,
TunerChannel channel,
@@ -253,6 +249,11 @@
*/
private static class TunerHalManager {
private final Map<Integer, Tuner> mTunerHals = new HashMap<>();
+ private final TunerFactory mTunerFactory;
+
+ private TunerHalManager(TunerFactory mTunerFactory) {
+ this.mTunerFactory = mTunerFactory;
+ }
private Tuner getOrCreateTunerHal(Context context, int sessionId) {
// Handles session affinity.
@@ -269,7 +270,7 @@
mTunerHals.remove(key);
return hal;
}
- return BuiltInTunerHalFactory.INSTANCE.createInstance(context);
+ return mTunerFactory.createInstance(context);
}
private void releaseTunerHal(Tuner hal, int sessionId, boolean reuse) {
diff --git a/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java b/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
index 7967657..d22b639 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/BaseTunerTvInputService.java
@@ -23,14 +23,16 @@
import android.media.tv.TvInputService;
import android.util.Log;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.flags.has.HasConcurrentDvrPlaybackFlags;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
-import com.android.tv.tuner.tvinput.factory.TunerSessionFactory.HasTunerSessionFactory;
+import com.android.tv.tuner.tvinput.factory.TunerSessionFactory;
+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. */
public class BaseTunerTvInputService extends TvInputService {
@@ -41,7 +43,9 @@
private final Set<Session> mTunerSessions = Collections.newSetFromMap(new WeakHashMap<>());
private ChannelDataManager mChannelDataManager;
- private ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject TsDataSourceManager.Factory mTsDataSourceManagerFactory;
+ @Inject TunerSessionFactory mTunerSessionFactory;
@Override
public void onCreate() {
@@ -50,11 +54,10 @@
this.stopSelf();
return;
}
+ AndroidInjection.inject(this);
super.onCreate();
if (DEBUG) Log.d(TAG, "onCreate");
mChannelDataManager = new ChannelDataManager(getApplicationContext());
- mConcurrentDvrPlaybackFlags =
- HasConcurrentDvrPlaybackFlags.fromContext(getApplicationContext());
if (CommonFeatures.DVR.isEnabled(this)) {
JobScheduler jobScheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
@@ -84,7 +87,11 @@
@Override
public RecordingSession onCreateRecordingSession(String inputId) {
return new TunerRecordingSession(
- this, inputId, mChannelDataManager, mConcurrentDvrPlaybackFlags);
+ this,
+ inputId,
+ mChannelDataManager,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
}
@Override
@@ -97,9 +104,7 @@
return null;
}
final Session session =
- HasTunerSessionFactory.cast(this)
- .getTunerSessionFactory()
- .create(this, mChannelDataManager, this::onReleased);
+ mTunerSessionFactory.create(this, mChannelDataManager, this::onReleased);
mTunerSessions.add(session);
session.setOverlayViewEnabled(true);
return session;
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
index 4bb705a..5561693 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSession.java
@@ -23,6 +23,7 @@
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.android.tv.common.compat.RecordingSessionCompat;
+import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.datamanager.ChannelDataManager;
import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
@@ -37,11 +38,17 @@
Context context,
String inputId,
ChannelDataManager channelDataManager,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
mSessionWorker =
new TunerRecordingSessionWorker(
- context, inputId, channelDataManager, this, concurrentDvrPlaybackFlags);
+ context,
+ inputId,
+ channelDataManager,
+ this,
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
}
// RecordingSession
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
index 0ef9250..2c0c09a 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
@@ -174,7 +174,8 @@
String inputId,
ChannelDataManager dataManager,
TunerRecordingSession session,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
mRandom.setSeed(System.nanoTime());
mContext = context;
@@ -185,7 +186,7 @@
BaseApplication.getSingletons(context).getRecordingStorageStatusManager();
mChannelDataManager = dataManager;
mChannelDataManager.checkDataVersion(context);
- mSourceManager = TsDataSourceManager.createSourceManager(true);
+ mSourceManager = tsDataSourceManagerFactory.create(true);
mCapabilities = new DvbDeviceAccessor(context).getRecordingCapability(inputId);
mInputId = inputId;
if (DEBUG) Log.d(TAG, mCapabilities.toString());
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
index 8292341..fedb5f6 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSession.java
@@ -30,6 +30,7 @@
import com.android.tv.common.CommonPreferences.CommonPreferencesChangedListener;
import com.android.tv.common.compat.TisSessionCompat;
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.SessionReleasedCallback;
import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
@@ -53,7 +54,8 @@
Context context,
ChannelDataManager channelDataManager,
SessionReleasedCallback releasedCallback,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
mReleasedCallback = releasedCallback;
mTunerSessionOverlay = new TunerSessionOverlay(context);
@@ -63,7 +65,8 @@
channelDataManager,
this,
mTunerSessionOverlay,
- concurrentDvrPlaybackFlags);
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
TunerPreferences.setCommonPreferencesChangedListener(this);
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
index 2c5995b..4eca44d 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionExoV2.java
@@ -30,6 +30,7 @@
import com.android.tv.common.CommonPreferences.CommonPreferencesChangedListener;
import com.android.tv.common.compat.TisSessionCompat;
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.SessionReleasedCallback;
import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
@@ -51,7 +52,8 @@
Context context,
ChannelDataManager channelDataManager,
SessionReleasedCallback releasedCallback,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
super(context);
mReleasedCallback = releasedCallback;
mTunerSessionOverlay = new TunerSessionOverlay(context);
@@ -61,7 +63,8 @@
channelDataManager,
this,
mTunerSessionOverlay,
- concurrentDvrPlaybackFlags);
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
TunerPreferences.setCommonPreferencesChangedListener(this);
}
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
index 770e243..d3f9409 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
@@ -241,14 +241,16 @@
ChannelDataManager channelDataManager,
TunerSession tunerSession,
TunerSessionOverlay tunerSessionOverlay,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
this(
context,
channelDataManager,
tunerSession,
tunerSessionOverlay,
null,
- concurrentDvrPlaybackFlags);
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
}
@VisibleForTesting
@@ -258,7 +260,8 @@
TunerSession tunerSession,
TunerSessionOverlay tunerSessionOverlay,
@Nullable Handler handler,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
this.mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
if (DEBUG) Log.d(TAG, "TunerSessionWorker created");
mContext = context;
@@ -276,7 +279,7 @@
mChannelDataManager = channelDataManager;
mChannelDataManager.setListener(this);
mChannelDataManager.checkDataVersion(mContext);
- mSourceManager = TsDataSourceManager.createSourceManager(false);
+ mSourceManager = tsDataSourceManagerFactory.create(false);
mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
mTvTracks = new ArrayList<>();
mAudioCapabilitiesReceiver =
diff --git a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
index 2f07952..82afff1 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2.java
@@ -240,14 +240,16 @@
ChannelDataManager channelDataManager,
TunerSessionExoV2 tunerSession,
TunerSessionOverlay tunerSessionOverlay,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
this(
context,
channelDataManager,
tunerSession,
tunerSessionOverlay,
null,
- concurrentDvrPlaybackFlags);
+ concurrentDvrPlaybackFlags,
+ tsDataSourceManagerFactory);
}
@VisibleForTesting
@@ -257,7 +259,8 @@
TunerSessionExoV2 tunerSession,
TunerSessionOverlay tunerSessionOverlay,
@Nullable Handler handler,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
if (DEBUG) {
Log.d(TAG, "TunerSessionWorkerExoV2 created");
@@ -277,7 +280,7 @@
mChannelDataManager = channelDataManager;
mChannelDataManager.setListener(this);
mChannelDataManager.checkDataVersion(mContext);
- mSourceManager = TsDataSourceManager.createSourceManager(false);
+ mSourceManager = tsDataSourceManagerFactory.create(false);
mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
mTvTracks = new ArrayList<>();
mAudioCapabilitiesReceiver =
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 9ab6872..a27cb22 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactory.java
@@ -7,17 +7,6 @@
/** {@link android.media.tv.TvInputService.Session} factory */
public interface TunerSessionFactory {
- /** Has a {@link TunerSessionFactory}. */
- interface HasTunerSessionFactory {
- static HasTunerSessionFactory cast(Context context) {
- Context appContext = context.getApplicationContext();
- context = appContext != null ? appContext : context;
- return (HasTunerSessionFactory) context;
- }
-
- TunerSessionFactory getTunerSessionFactory();
- }
-
/** Called when a session is released */
interface SessionReleasedCallback {
diff --git a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java
index 1864ad6..6617995 100644
--- a/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java
+++ b/tuner/src/com/android/tv/tuner/tvinput/factory/TunerSessionFactoryImpl.java
@@ -2,22 +2,29 @@
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.Exoplayer2Flags;
+import javax.inject.Inject;
/** Creates a {@link TunerSessionFactory}. */
public class TunerSessionFactoryImpl implements TunerSessionFactory {
+
private final Exoplayer2Flags mExoplayer2Flags;
private final ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ private final TsDataSourceManager.Factory mTsDataSourceManagerFactory;
+ @Inject
public TunerSessionFactoryImpl(
Exoplayer2Flags exoplayer2Flags,
- ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags) {
+ ConcurrentDvrPlaybackFlags concurrentDvrPlaybackFlags,
+ TsDataSourceManager.Factory tsDataSourceManagerFactory) {
mExoplayer2Flags = exoplayer2Flags;
mConcurrentDvrPlaybackFlags = concurrentDvrPlaybackFlags;
+ mTsDataSourceManagerFactory = tsDataSourceManagerFactory;
}
@Override
@@ -27,8 +34,16 @@
SessionReleasedCallback releasedCallback) {
return mExoplayer2Flags.enabled()
? new TunerSessionExoV2(
- context, channelDataManager, releasedCallback, mConcurrentDvrPlaybackFlags)
+ context,
+ channelDataManager,
+ releasedCallback,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory)
: new TunerSession(
- context, channelDataManager, releasedCallback, mConcurrentDvrPlaybackFlags);
+ context,
+ channelDataManager,
+ releasedCallback,
+ mConcurrentDvrPlaybackFlags,
+ mTsDataSourceManagerFactory);
}
}