aboutsummaryrefslogtreecommitdiff
path: root/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/tv/LauncherActivity.java8
-rw-r--r--src/com/android/tv/MainActivity.java116
-rw-r--r--src/com/android/tv/MediaSessionWrapper.java3
-rw-r--r--src/com/android/tv/SetupPassthroughActivity.java97
-rw-r--r--src/com/android/tv/TimeShiftManager.java25
-rw-r--r--src/com/android/tv/TvApplication.java128
-rw-r--r--src/com/android/tv/TvSingletons.java46
-rw-r--r--src/com/android/tv/app/LiveTvApplication.java67
-rw-r--r--src/com/android/tv/app/LiveTvApplicationComponent.java8
-rw-r--r--src/com/android/tv/app/LiveTvModule.java31
-rw-r--r--src/com/android/tv/data/BaseProgram.java208
-rw-r--r--src/com/android/tv/data/BaseProgramImpl.java86
-rw-r--r--src/com/android/tv/data/ChannelDataManager.java30
-rw-r--r--src/com/android/tv/data/InternalDataUtils.java7
-rw-r--r--src/com/android/tv/data/OnCurrentProgramUpdatedListener.java2
-rw-r--r--src/com/android/tv/data/PreviewDataManager.java15
-rw-r--r--src/com/android/tv/data/PreviewProgramContent.java10
-rw-r--r--src/com/android/tv/data/Program.java (renamed from src/com/android/tv/data/ProgramImpl.java)191
-rw-r--r--src/com/android/tv/data/ProgramDataManager.java190
-rw-r--r--src/com/android/tv/data/api/BaseProgram.java141
-rw-r--r--src/com/android/tv/data/api/Program.java141
-rw-r--r--src/com/android/tv/data/epg/EpgFetchHelper.java13
-rw-r--r--src/com/android/tv/data/epg/EpgFetchService.java14
-rw-r--r--src/com/android/tv/data/epg/EpgFetcherImpl.java56
-rw-r--r--src/com/android/tv/data/epg/EpgInputWhiteList.java16
-rw-r--r--src/com/android/tv/data/epg/EpgReader.java9
-rw-r--r--src/com/android/tv/data/epg/StubEpgReader.java10
-rw-r--r--src/com/android/tv/dialog/PinDialogFragment.java33
-rw-r--r--src/com/android/tv/dialog/picker/PinPicker.java131
-rw-r--r--src/com/android/tv/dialog/picker/TvPinPicker.java54
-rw-r--r--src/com/android/tv/dvr/DvrDataManagerImpl.java60
-rw-r--r--src/com/android/tv/dvr/DvrManager.java6
-rw-r--r--src/com/android/tv/dvr/DvrScheduleManager.java8
-rw-r--r--src/com/android/tv/dvr/DvrStorageStatusManager.java2
-rw-r--r--src/com/android/tv/dvr/DvrWatchedPositionManager.java4
-rw-r--r--src/com/android/tv/dvr/data/RecordedProgram.java5
-rw-r--r--src/com/android/tv/dvr/data/ScheduledRecording.java6
-rw-r--r--src/com/android/tv/dvr/data/SeriesRecording.java10
-rw-r--r--src/com/android/tv/dvr/provider/DvrContract.java9
-rw-r--r--src/com/android/tv/dvr/provider/DvrDatabaseHelper.java19
-rw-r--r--src/com/android/tv/dvr/provider/DvrDbFuture.java98
-rw-r--r--src/com/android/tv/dvr/provider/DvrDbSync.java24
-rw-r--r--src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java13
-rw-r--r--src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java12
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrConflictFragment.java9
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrScheduleFragment.java13
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java22
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java8
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java24
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java7
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java18
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java10
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrUiHelper.java54
-rw-r--r--src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/SortedArrayAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java25
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContent.java13
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java4
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java23
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java18
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java8
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingCardView.java18
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java24
-rw-r--r--src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java20
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java44
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java10
-rw-r--r--src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java3
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java3
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java7
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java19
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java18
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java65
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlayer.java13
-rw-r--r--src/com/android/tv/features/TvFeatures.java22
-rw-r--r--src/com/android/tv/guide/GenreListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramGrid.java17
-rw-r--r--src/com/android/tv/guide/ProgramGuide.java25
-rw-r--r--src/com/android/tv/guide/ProgramItemView.java22
-rw-r--r--src/com/android/tv/guide/ProgramListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramManager.java40
-rw-r--r--src/com/android/tv/guide/ProgramRow.java2
-rw-r--r--src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java4
-rw-r--r--src/com/android/tv/guide/ProgramTableAdapter.java44
-rw-r--r--src/com/android/tv/guide/TimeListAdapter.java2
-rw-r--r--src/com/android/tv/guide/TimelineGridView.java4
-rw-r--r--src/com/android/tv/menu/ActionCardView.java8
-rw-r--r--src/com/android/tv/menu/AppLinkCardView.java2
-rw-r--r--src/com/android/tv/menu/BaseCardView.java8
-rw-r--r--src/com/android/tv/menu/ChannelCardView.java4
-rw-r--r--src/com/android/tv/menu/ChannelsPosterPrefetcher.java4
-rw-r--r--src/com/android/tv/menu/ChannelsRow.java1
-rw-r--r--src/com/android/tv/menu/ChannelsRowAdapter.java14
-rw-r--r--src/com/android/tv/menu/ItemListRowView.java15
-rw-r--r--src/com/android/tv/menu/Menu.java2
-rw-r--r--src/com/android/tv/menu/MenuLayoutManager.java8
-rw-r--r--src/com/android/tv/menu/MenuRow.java17
-rw-r--r--src/com/android/tv/menu/MenuRowFactory.java17
-rw-r--r--src/com/android/tv/menu/MenuRowView.java16
-rw-r--r--src/com/android/tv/menu/MenuView.java59
-rw-r--r--src/com/android/tv/menu/PlayControlsButton.java8
-rw-r--r--src/com/android/tv/menu/PlayControlsRowView.java8
-rw-r--r--src/com/android/tv/menu/TvOptionsRowAdapter.java11
-rw-r--r--src/com/android/tv/modules/TvApplicationModule.java70
-rw-r--r--src/com/android/tv/modules/TvSingletonsModule.java7
-rw-r--r--src/com/android/tv/onboarding/OnboardingActivity.java4
-rw-r--r--src/com/android/tv/onboarding/SetupSourcesFragment.java63
-rw-r--r--src/com/android/tv/onboarding/WelcomeFragment.java8
-rw-r--r--src/com/android/tv/parental/ContentRatingsManager.java16
-rw-r--r--src/com/android/tv/parental/ParentalControlSettings.java8
-rw-r--r--src/com/android/tv/perf/PerformanceMonitor.java10
-rw-r--r--src/com/android/tv/perf/PerformanceMonitorManager.java38
-rw-r--r--src/com/android/tv/perf/PerformanceMonitorManagerFactory.java (renamed from src/com/android/tv/perf/StartupMeasureFactory.java)28
-rw-r--r--src/com/android/tv/perf/StartupMeasure.java12
-rw-r--r--src/com/android/tv/perf/stub/StubPerformanceMonitor.java5
-rw-r--r--src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java36
-rw-r--r--src/com/android/tv/receiver/AudioCapabilitiesReceiver.java2
-rw-r--r--src/com/android/tv/receiver/PackageIntentsReceiver.java2
-rw-r--r--src/com/android/tv/recommendation/ChannelPreviewUpdater.java5
-rw-r--r--src/com/android/tv/recommendation/ChannelRecord.java4
-rw-r--r--src/com/android/tv/recommendation/NotificationService.java4
-rw-r--r--src/com/android/tv/recommendation/RecommendationDataManager.java12
-rw-r--r--src/com/android/tv/recommendation/Recommender.java4
-rw-r--r--src/com/android/tv/recommendation/RoutineWatchEvaluator.java4
-rw-r--r--src/com/android/tv/recommendation/WatchedProgram.java2
-rw-r--r--src/com/android/tv/search/DataManagerSearch.java5
-rw-r--r--src/com/android/tv/search/LocalSearchProvider.java31
-rw-r--r--src/com/android/tv/search/ProgramGuideSearchFragment.java24
-rw-r--r--src/com/android/tv/search/TvProviderSearch.java2
-rw-r--r--src/com/android/tv/setup/SystemSetupActivity.java23
-rw-r--r--src/com/android/tv/ui/AppLayerTvView.java15
-rw-r--r--src/com/android/tv/ui/ChannelBannerView.java50
-rw-r--r--src/com/android/tv/ui/DetailsActivity.java19
-rw-r--r--src/com/android/tv/ui/GuidedActionsStylistWithDivider.java6
-rw-r--r--src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java2
-rw-r--r--src/com/android/tv/ui/ProgramDetailsFragment.java28
-rw-r--r--src/com/android/tv/ui/SelectInputView.java4
-rw-r--r--src/com/android/tv/ui/TunableTvView.java44
-rw-r--r--src/com/android/tv/ui/TvOverlayManager.java27
-rw-r--r--src/com/android/tv/ui/ViewUtils.java5
-rw-r--r--src/com/android/tv/ui/sidepanel/ChannelCheckItem.java3
-rw-r--r--src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java56
-rw-r--r--src/com/android/tv/ui/sidepanel/SettingsFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragment.java18
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java29
-rw-r--r--src/com/android/tv/util/AsyncDbTask.java34
-rw-r--r--src/com/android/tv/util/OnboardingUtils.java9
-rw-r--r--src/com/android/tv/util/SetupUtils.java3
-rw-r--r--src/com/android/tv/util/SqlParams.java75
-rw-r--r--src/com/android/tv/util/TvInputManagerHelper.java29
-rw-r--r--src/com/android/tv/util/TvProviderUtils.java12
-rw-r--r--src/com/android/tv/util/TvTrackInfoUtils.java135
-rw-r--r--src/com/android/tv/util/Utils.java40
-rw-r--r--src/com/android/tv/util/account/AccountHelper.java7
-rw-r--r--src/com/android/tv/util/account/AccountHelperImpl.java12
-rw-r--r--src/com/android/tv/util/images/ImageLoader.java80
184 files changed, 1795 insertions, 2558 deletions
diff --git a/src/com/android/tv/LauncherActivity.java b/src/com/android/tv/LauncherActivity.java
index ccc5600a..679d612d 100644
--- a/src/com/android/tv/LauncherActivity.java
+++ b/src/com/android/tv/LauncherActivity.java
@@ -27,10 +27,10 @@ import android.util.Log;
* An activity to launch a new activity.
*
* <p>In the case when {@link MainActivity} starts a new activity using {@link
- * Activity#startActivity} or {@link Activity#startActivityForResult}, TV app is terminated if the
- * new activity crashes. That's because the {@link android.app.ActivityManager} terminates the
- * activity which is just below the crashed activity in the activity stack. To avoid this, we need
- * to locate an additional activity between these activities in the activity stack.
+ * Activity#startActivity} or {@link Activity#startActivityForResult}, Live TV app is
+ * terminated if the new activity crashes. That's because the {@link android.app.ActivityManager}
+ * terminates the activity which is just below the crashed activity in the activity stack. To avoid
+ * this, we need to locate an additional activity between these activities in the activity stack.
*/
public class LauncherActivity extends Activity {
private static final String TAG = "LauncherActivity";
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index 7a591500..b4cf71db 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -16,8 +16,6 @@
package com.android.tv;
-import static com.android.tv.common.feature.SystemAppFeature.SYSTEM_APP_FEATURE;
-
import android.app.Activity;
import android.app.PendingIntent;
import android.app.SearchManager;
@@ -46,7 +44,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
-import android.provider.BaseColumns;
import android.provider.Settings;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
@@ -68,7 +65,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.Toast;
-
import com.android.tv.MainActivity.MySingletons;
import com.android.tv.analytics.SendChannelStatusRunnable;
import com.android.tv.analytics.SendConfigInfoRunnable;
@@ -82,7 +78,6 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.compat.TvInputInfoCompat;
-import com.android.tv.common.dev.DeveloperPreferences;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.memory.MemoryManageable;
import com.android.tv.common.singletons.HasSingletons;
@@ -96,13 +91,11 @@ import com.android.tv.common.util.SystemProperties;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
@@ -113,12 +106,11 @@ import com.android.tv.dvr.recorder.ConflictChecker;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.features.TvFeatures;
-import com.android.tv.guide.ProgramItemView;
import com.android.tv.menu.Menu;
import com.android.tv.onboarding.OnboardingActivity;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.receiver.AudioCapabilitiesReceiver;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
@@ -134,7 +126,6 @@ import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.BlockScreenType;
import com.android.tv.ui.TunableTvView.OnTuneListener;
import com.android.tv.ui.TvOverlayManager;
-import com.android.tv.ui.TvOverlayManagerFactory;
import com.android.tv.ui.TvViewUiManager;
import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.CustomizeChannelListFragment;
@@ -144,7 +135,6 @@ import com.android.tv.ui.sidepanel.MultiAudioFragment;
import com.android.tv.ui.sidepanel.SettingsFragment;
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment;
-import com.android.tv.ui.sidepanel.parentalcontrols.RatingsFragment;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.CaptionSettings;
@@ -160,17 +150,9 @@ import com.android.tv.util.account.AccountHelper;
import com.android.tv.util.images.ImageCache;
import com.google.common.base.Optional;
-
import dagger.android.AndroidInjection;
-import dagger.android.AndroidInjector;
import dagger.android.ContributesAndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-import com.android.tv.common.flags.LegacyFlags;
-import com.android.tv.common.flags.StartupFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
@@ -181,17 +163,15 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-
import javax.inject.Inject;
import javax.inject.Provider;
-/** The main activity for the TV app. */
+/** The main activity for the Live TV app. */
public class MainActivity extends Activity
implements OnActionClickListener,
OnPinCheckedListener,
ChannelChanger,
- HasSingletons<MySingletons>,
- HasAndroidInjector {
+ HasSingletons<MySingletons> {
private static final String TAG = "MainActivity";
private static final boolean DEBUG = false;
private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
@@ -278,11 +258,10 @@ public class MainActivity extends Activity
private static final long START_UP_TIMER_RESET_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(3);
{
- StartupMeasureFactory.create().onActivityInit();
+ PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
}
private final MySingletonsImpl mMySingletons = new MySingletonsImpl();
- @Inject DispatchingAndroidInjector<Object> mAndroidInjector;
@Inject @DbExecutor Executor mDbExecutor;
private AccessibilityManager mAccessibilityManager;
@@ -299,12 +278,8 @@ public class MainActivity extends Activity
private DvrManager mDvrManager;
private ConflictChecker mDvrConflictChecker;
@Inject BackendKnobsFlags mBackendKnobs;
- @Inject LegacyFlags mLegacyFlags;
- @Inject StartupFlags mStartupFlags;
@Inject SetupUtils mSetupUtils;
@Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
- @Inject AccountHelper mAccountHelper;
- @Inject EpgFetcher mEpgFetcher;
@VisibleForTesting protected TunableTvView mTvView;
private View mContentView;
@@ -339,7 +314,6 @@ public class MainActivity extends Activity
private boolean mIsFilmModeSet;
private float mDefaultRefreshRate;
- @Inject TvOverlayManagerFactory mOverlayFactory;
private TvOverlayManager mOverlayManager;
// mIsCurrentChannelUnblockedByUser and mWasChannelUnblockedBeforeShrunkenByUser are used for
@@ -503,6 +477,7 @@ public class MainActivity extends Activity
AndroidInjection.inject(this);
mAccessibilityManager =
(AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(this);
DurationTimer startUpDebugTimer = Debug.getTimer(Debug.TAG_START_UP_TIMER);
if (!startUpDebugTimer.isStarted()
|| startUpDebugTimer.getDuration() > START_UP_TIMER_RESET_THRESHOLD_MS) {
@@ -521,7 +496,6 @@ public class MainActivity extends Activity
finishAndRemoveTask();
return;
}
- mAccountHelper.init();
TvSingletons tvApplication = (TvSingletons) getApplication();
// In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
@@ -540,8 +514,8 @@ public class MainActivity extends Activity
return;
}
setContentView(R.layout.activity_tv);
- mTvView = findViewById(R.id.main_tunable_tv_view);
- mTvView.initialize(mProgramDataManager, mTvInputManagerHelper, mLegacyFlags);
+ mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
+ mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
mTvView.setOnUnhandledInputEventListener(
new OnUnhandledInputEventListener() {
@Override
@@ -571,13 +545,12 @@ public class MainActivity extends Activity
String inputId = Utils.getLastWatchedTunerInputId(this);
if (!isPassthroughInput
&& inputId != null
- && !mStartupFlags.warmupInputidBlacklist().getElementList().contains(inputId)
&& channelId != Channel.INVALID_ID) {
mTvView.warmUpInput(inputId, TvContract.buildChannelUri(channelId));
}
tvApplication.getMainActivityWrapper().onMainActivityCreated(this);
- if (BuildConfig.ENG && DeveloperPreferences.ALLOW_STRICT_MODE.get(this)) {
+ if (BuildConfig.ENG && SystemProperties.ALLOW_STRICT_MODE.getValue()) {
Toast.makeText(this, "Using Strict Mode for eng builds", Toast.LENGTH_SHORT).show();
}
mTracker = tvApplication.getTracker();
@@ -639,10 +612,13 @@ public class MainActivity extends Activity
}
mTvViewUiManager =
new TvViewUiManager(
- this, mTvView, findViewById(android.R.id.content), mTvOptionsManager);
+ this,
+ mTvView,
+ (FrameLayout) findViewById(android.R.id.content),
+ mTvOptionsManager);
mContentView = findViewById(android.R.id.content);
- ViewGroup sceneContainer = findViewById(R.id.scene_container);
+ ViewGroup sceneContainer = (ViewGroup) findViewById(R.id.scene_container);
ChannelBannerView channelBannerView =
(ChannelBannerView)
getLayoutInflater().inflate(R.layout.channel_banner, sceneContainer, false);
@@ -695,7 +671,7 @@ public class MainActivity extends Activity
});
mSearchFragment = new ProgramGuideSearchFragment();
mOverlayManager =
- mOverlayFactory.create(
+ new TvOverlayManager(
this,
mChannelTuner,
mTvView,
@@ -733,6 +709,8 @@ public class MainActivity extends Activity
SendChannelStatusRunnable.startChannelStatusRecurringRunner(
this, mTracker, mChannelDataManager);
+ // To avoid not updating Rating systems when changing language.
+ mTvInputManagerHelper.getContentRatingsManager().update();
if (CommonFeatures.DVR.isEnabled(this)
&& TvFeatures.SHOW_UPCOMING_CONFLICT_DIALOG.isEnabled(this)) {
mDvrConflictChecker = new ConflictChecker(this);
@@ -764,7 +742,7 @@ public class MainActivity extends Activity
mChannelDataManager.reload();
mProgramDataManager.reload();
- // Restart TV app.
+ // Restart live channels.
Intent intent = getIntent();
finish();
startActivity(intent);
@@ -852,7 +830,7 @@ public class MainActivity extends Activity
.getTunerInputController()
.executeNetworkTunerDiscoveryAsyncTask(this);
}
- mEpgFetcher.fetchImmediatelyIfNeeded();
+ TvSingletons.getSingletons(this).getEpgFetcher().fetchImmediatelyIfNeeded();
}
@Override
@@ -1149,8 +1127,8 @@ public class MainActivity extends Activity
Toast.makeText(this, R.string.msg_no_setup_activity, Toast.LENGTH_SHORT).show();
return;
}
- // Even though other app can handle the intent, the setup launched by TV app
- // should go through TV app SetupPassthroughActivity.
+ // Even though other app can handle the intent, the setup launched by Live channels
+ // should go through Live channels SetupPassthroughActivity.
intent.setComponent(new ComponentName(this, SetupPassthroughActivity.class));
try {
// Now we know that the user intends to set up this input. Grant permission for writing
@@ -1420,9 +1398,7 @@ public class MainActivity extends Activity
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
- Log.d(TAG, "dispatchKeyEvent(" + event + ")");
- }
+ if (SystemProperties.LOG_KEYEVENT.getValue()) Log.d(TAG, "dispatchKeyEvent(" + event + ")");
// If an activity is closed on a back key down event, back key down events with none zero
// repeat count or a back key up event can be happened without the first back key down
// event which should be ignored in this activity.
@@ -1527,7 +1503,7 @@ public class MainActivity extends Activity
new AsyncQueryProgramTask(
mDbExecutor,
programUriFromIntent,
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
null,
@@ -1558,7 +1534,7 @@ public class MainActivity extends Activity
String inputId = mInitChannelUri.getQueryParameter("input");
long channelId = Utils.getLastWatchedChannelIdForInput(this, inputId);
if (channelId == Channel.INVALID_ID) {
- String[] projection = {BaseColumns._ID};
+ String[] projection = {Channels._ID};
long time = System.currentTimeMillis();
try (Cursor cursor =
getContentResolver().query(uri, projection, null, null, null)) {
@@ -1606,7 +1582,7 @@ public class MainActivity extends Activity
protected Program onQuery(Cursor c) {
Program program = null;
if (c != null && c.moveToNext()) {
- program = ProgramImpl.fromCursor(c);
+ program = Program.fromCursor(c);
}
return program;
}
@@ -1622,7 +1598,7 @@ public class MainActivity extends Activity
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra(DetailsActivity.CHANNEL_ID, mChannelIdFromIntent);
intent.putExtra(DetailsActivity.DETAILS_VIEW_TYPE, DetailsActivity.PROGRAM_VIEW);
- intent.putExtra(DetailsActivity.PROGRAM, program.toParcelable());
+ intent.putExtra(DetailsActivity.PROGRAM, program);
intent.putExtra(DetailsActivity.INPUT_ID, channel.getInputId());
startActivity(intent);
}
@@ -2101,7 +2077,7 @@ public class MainActivity extends Activity
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "onKeyDown(" + keyCode + ", " + event + ")");
}
switch (mOverlayManager.onKeyDown(keyCode, event)) {
@@ -2191,7 +2167,7 @@ public class MainActivity extends Activity
* W debug: toggle screen size
* V KEYCODE_MEDIA_RECORD debug: record the current channel for 30 sec
*/
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "onKeyUp(" + keyCode + ", " + event + ")");
}
// If we are in the middle of channel change, finish it before showing overlays.
@@ -2289,7 +2265,7 @@ public class MainActivity extends Activity
// Channel change is already done in the head of this method.
return true;
case KeyEvent.KEYCODE_S:
- if (!DeveloperPreferences.USE_DEBUG_KEYS.get(this)) {
+ if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
// fall through.
@@ -2297,7 +2273,7 @@ public class MainActivity extends Activity
mOverlayManager.getSideFragmentManager().show(new ClosedCaptionFragment());
return true;
case KeyEvent.KEYCODE_A:
- if (!DeveloperPreferences.USE_DEBUG_KEYS.get(this)) {
+ if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
// fall through.
@@ -2363,7 +2339,7 @@ public class MainActivity extends Activity
// in case that TV isn't showing properly (e.g. no browsable channel)
return true;
}
- if (DeveloperPreferences.USE_DEBUG_KEYS.get(this) || BuildConfig.ENG) {
+ if (SystemProperties.USE_DEBUG_KEYS.getValue() || BuildConfig.ENG) {
switch (keyCode) {
case KeyEvent.KEYCODE_W:
mDebugNonFullSizeScreen = !mDebugNonFullSizeScreen;
@@ -2419,7 +2395,7 @@ public class MainActivity extends Activity
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) Log.d(TAG, "onKeyLongPress(" + event);
+ if (SystemProperties.LOG_KEYEVENT.getValue()) Log.d(TAG, "onKeyLongPress(" + event);
if (USE_BACK_KEY_LONG_PRESS) {
// Treat the BACK key long press as the normal press since we changed the behavior in
// onBackPressed().
@@ -2489,7 +2465,7 @@ public class MainActivity extends Activity
}
private boolean dispatchKeyEventToSession(final KeyEvent event) {
- if (DeveloperPreferences.LOG_KEYEVENT.get(this)) {
+ if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "dispatchKeyEventToSession(" + event + ")");
}
boolean handled = false;
@@ -2742,10 +2718,7 @@ public class MainActivity extends Activity
return;
}
- // Only try to set the channels browseable if we are a system app.
- if (SYSTEM_APP_FEATURE.isEnabled(getApplicationContext())) {
- Utils.enableAllChannels(this);
- }
+ Utils.enableAllChannels(this);
}
// Lazy initialization
@@ -2805,11 +2778,6 @@ public class MainActivity extends Activity
}
}
- @Override
- public AndroidInjector<Object> androidInjector() {
- return mAndroidInjector;
- }
-
private static class MainActivityHandler extends WeakHandler<MainActivity> {
MainActivityHandler(MainActivity mainActivity) {
super(mainActivity);
@@ -2855,8 +2823,11 @@ public class MainActivity extends Activity
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.MyOnTuneListener.onTune");
mChannel = channel;
mWasUnderShrunkenTvView = wasUnderShrunkenTvView;
- // Fetch complete projection of tuned channel.
- mProgramDataManager.onChannelTuned(channel.getId());
+
+ if (mBackendKnobs.enablePartialProgramFetch()) {
+ // Fetch complete projection of tuned channel.
+ mProgramDataManager.prefetchChannel(channel.getId());
+ }
}
@Override
@@ -3011,14 +2982,5 @@ public class MainActivity extends Activity
public abstract static class Module {
@ContributesAndroidInjector
abstract MainActivity contributesMainActivityActivityInjector();
-
- @ContributesAndroidInjector
- abstract DeveloperOptionFragment contributesDeveloperOptionFragment();
-
- @ContributesAndroidInjector
- abstract RatingsFragment contributesRatingsFragment();
-
- @ContributesAndroidInjector
- abstract ProgramItemView contributesProgramItemView();
}
}
diff --git a/src/com/android/tv/MediaSessionWrapper.java b/src/com/android/tv/MediaSessionWrapper.java
index df886391..a647a06f 100644
--- a/src/com/android/tv/MediaSessionWrapper.java
+++ b/src/com/android/tv/MediaSessionWrapper.java
@@ -34,9 +34,8 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
-
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 25049f1d..5185b122 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -18,7 +18,7 @@ package com.android.tv;
import android.app.Activity;
import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
@@ -26,8 +26,6 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.MainThread;
import android.util.Log;
-
-import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.actions.InputSetupActionUtils;
import com.android.tv.data.ChannelDataManager;
@@ -38,16 +36,9 @@ import com.android.tv.features.TvFeatures;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
import com.google.android.tv.partner.support.EpgContract;
-
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
/**
* An activity to launch a TV input setup activity.
*
@@ -64,20 +55,18 @@ public class SetupPassthroughActivity extends Activity {
private TvInputInfo mTvInputInfo;
private Intent mActivityAfterCompletion;
private boolean mEpgFetcherDuringScan;
- @Inject EpgInputWhiteList mEpgInputWhiteList;
- @Inject TvInputManagerHelper mInputManager;
- @Inject SetupUtils mSetupUtils;
- @Inject ChannelDataManager mChannelDataManager;
- @Inject EpgFetcher mEpgFetcher;
+ private EpgInputWhiteList mEpgInputWhiteList;
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate");
- AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(this);
+ TvInputManagerHelper inputManager = tvSingletons.getTvInputManagerHelper();
Intent intent = getIntent();
String inputId = intent.getStringExtra(InputSetupActionUtils.EXTRA_INPUT_ID);
- mTvInputInfo = mInputManager.getTvInputInfo(inputId);
+ mTvInputInfo = inputManager.getTvInputInfo(inputId);
+ mEpgInputWhiteList = new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
mActivityAfterCompletion = InputSetupActionUtils.getExtraActivityAfter(intent);
boolean needToFetchEpg =
mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId());
@@ -117,17 +106,6 @@ public class SetupPassthroughActivity extends Activity {
InputSetupActionUtils.removeSetupIntent(extras);
setupIntent.putExtras(extras);
try {
- ComponentName callingActivity = getCallingActivity();
- if (callingActivity != null
- && !callingActivity.getPackageName().equals(CommonConstants.BASE_PACKAGE)) {
- Log.w(
- TAG,
- "Calling activity "
- + callingActivity.getPackageName()
- + " is not trusted. Not forwarding intent.");
- finish();
- return;
- }
startActivityForResult(setupIntent, REQUEST_START_SETUP_ACTIVITY);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Can't find activity: " + setupIntent.getComponent());
@@ -136,10 +114,10 @@ public class SetupPassthroughActivity extends Activity {
}
if (needToFetchEpg) {
if (sScanTimeoutMonitor == null) {
- sScanTimeoutMonitor = new ScanTimeoutMonitor(mEpgFetcher, mChannelDataManager);
+ sScanTimeoutMonitor = new ScanTimeoutMonitor(this);
}
sScanTimeoutMonitor.startMonitoring();
- mEpgFetcher.onChannelScanStarted();
+ TvSingletons.getSingletons(this).getEpgFetcher().onChannelScanStarted();
}
}
}
@@ -155,25 +133,15 @@ public class SetupPassthroughActivity extends Activity {
boolean setupComplete =
requestCode == REQUEST_START_SETUP_ACTIVITY && resultCode == Activity.RESULT_OK;
// Tells EpgFetcher that channel source setup is finished.
-
+ EpgFetcher epgFetcher = TvSingletons.getSingletons(this).getEpgFetcher();
if (mEpgFetcherDuringScan) {
- mEpgFetcher.onChannelScanFinished();
+ epgFetcher.onChannelScanFinished();
}
if (!setupComplete) {
setResult(resultCode, data);
finish();
return;
}
- if (TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.isEnabled(this)
- && data != null
- && data.getBooleanExtra(EpgContract.EXTRA_USE_CLOUD_EPG, false)) {
- if (DEBUG) Log.d(TAG, "extra " + data.getExtras());
- String inputId = data.getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
- if (mEpgInputWhiteList.isInputWhiteListed(inputId)) {
- mEpgFetcher.fetchImmediately();
- }
- }
-
if (mTvInputInfo == null) {
Log.w(
TAG,
@@ -184,19 +152,21 @@ public class SetupPassthroughActivity extends Activity {
finish();
return;
}
- mSetupUtils.onTvInputSetupFinished(
- mTvInputInfo.getId(),
- () -> {
- if (mActivityAfterCompletion != null) {
- try {
- startActivity(mActivityAfterCompletion);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Activity launch failed", e);
- }
- }
- setResult(resultCode, data);
- finish();
- });
+ TvSingletons.getSingletons(this)
+ .getSetupUtils()
+ .onTvInputSetupFinished(
+ mTvInputInfo.getId(),
+ () -> {
+ if (mActivityAfterCompletion != null) {
+ try {
+ startActivity(mActivityAfterCompletion);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity launch failed", e);
+ }
+ }
+ setResult(resultCode, data);
+ finish();
+ });
}
/**
@@ -209,7 +179,7 @@ public class SetupPassthroughActivity extends Activity {
// Set timeout long enough. The message in Sony TV says the scanning takes about 30 minutes.
private static final long SCAN_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(30);
- private final EpgFetcher mEpgFetcher;
+ private final Context mContext;
private final ChannelDataManager mChannelDataManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Runnable mScanTimeoutRunnable =
@@ -237,9 +207,9 @@ public class SetupPassthroughActivity extends Activity {
};
private boolean mStarted;
- private ScanTimeoutMonitor(EpgFetcher epgFetcher, ChannelDataManager mChannelDataManager) {
- mEpgFetcher = epgFetcher;
- this.mChannelDataManager = mChannelDataManager;
+ private ScanTimeoutMonitor(Context context) {
+ mContext = context.getApplicationContext();
+ mChannelDataManager = TvSingletons.getSingletons(context).getChannelDataManager();
}
private void startMonitoring() {
@@ -267,14 +237,7 @@ public class SetupPassthroughActivity extends Activity {
private void onScanTimedOut() {
stopMonitoring();
- mEpgFetcher.onChannelScanFinished();
+ TvSingletons.getSingletons(mContext).getEpgFetcher().onChannelScanFinished();
}
}
-
- /** Exports {@link MainActivity} for Dagger codegen to create the appropriate injector. */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract SetupPassthroughActivity contributesSetupPassthroughActivity();
- }
}
diff --git a/src/com/android/tv/TimeShiftManager.java b/src/com/android/tv/TimeShiftManager.java
index f08b5e85..779e8df6 100644
--- a/src/com/android/tv/TimeShiftManager.java
+++ b/src/com/android/tv/TimeShiftManager.java
@@ -26,21 +26,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.analytics.Tracker;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.api.TunableTvViewPlayingApi.TimeShiftListener;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TimeShiftUtils;
import com.android.tv.util.Utils;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -53,7 +50,7 @@ import java.util.Queue;
import java.util.concurrent.TimeUnit;
/**
- * A class which manages the time shift feature in TV app. It consists of two parts. {@link
+ * A class which manages the time shift feature in Live TV. It consists of two parts. {@link
* PlayController} controls the playback such as play/pause, rewind and fast-forward using {@link
* TunableTvView} which communicates with TvInputService through {@link
* android.media.tv.TvInputService.Session}. {@link ProgramManager} loads programs of the current
@@ -147,8 +144,8 @@ public class TimeShiftManager {
DISABLE_ACTION_THRESHOLD + 3 * REQUEST_CURRENT_POSITION_INTERVAL;
/**
* The current position sent from TIS can not be exactly the same as the current system time due
- * to the elapsed time to pass the message from TIS to TV app. So the boundary threshold is
- * necessary. The same goes for the recording start time. It's the same {@link
+ * to the elapsed time to pass the message from TIS to Live TV. So the boundary threshold
+ * is necessary. The same goes for the recording start time. It's the same {@link
* #REQUEST_CURRENT_POSITION_INTERVAL}.
*/
private static final long RECORDING_BOUNDARY_THRESHOLD = REQUEST_CURRENT_POSITION_INTERVAL;
@@ -622,8 +619,8 @@ public class TimeShiftManager {
< mAvailablityChangedTimeMs - ALLOWED_START_TIME_OFFSET) {
Log.e(
TAG,
- "The start time is too earlier than the time of"
- + " availability: {startTime: "
+ "The start time is too earlier than the time of availability: {"
+ + "startTime: "
+ recordStartTimeMs
+ ", availability: "
+ mAvailablityChangedTimeMs);
@@ -635,9 +632,9 @@ public class TimeShiftManager {
// clock,, use system's current time instead.
Log.e(
TAG,
- "The start time should not be earlier than the current"
- + " time, reset the start time to the system's current"
- + " time: {startTime: "
+ "The start time should not be earlier than the current time, "
+ + "reset the start time to the system's current time: {"
+ + "startTime: "
+ recordStartTimeMs
+ ", current time: "
+ System.currentTimeMillis());
@@ -1106,7 +1103,7 @@ public class TimeShiftManager {
long end = Utils.ceilTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
while (end < endTimeMs) {
programs.add(
- new ProgramImpl.Builder()
+ new Program.Builder()
.setStartTimeUtcMillis(start)
.setEndTimeUtcMillis(end)
.build());
@@ -1114,7 +1111,7 @@ public class TimeShiftManager {
end += MAX_DUMMY_PROGRAM_DURATION;
}
programs.add(
- new ProgramImpl.Builder()
+ new Program.Builder()
.setStartTimeUtcMillis(start)
.setEndTimeUtcMillis(endTimeMs)
.build());
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index bc8226cf..5f25a24b 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -35,19 +35,20 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;
-
import com.android.tv.common.BaseApplication;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
+import com.android.tv.common.util.Clock;
import com.android.tv.common.util.Debug;
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.data.epg.EpgReader;
+import com.android.tv.data.epg.EpgFetcherImpl;
import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrStorageStatusManager;
@@ -55,9 +56,8 @@ import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.recorder.RecordingScheduler;
import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
import com.android.tv.features.TvFeatures;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.StartupMeasure;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManager;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.RecordedProgramPreviewUpdater;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
@@ -66,30 +66,27 @@ import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
import com.google.common.base.Optional;
-
import dagger.Lazy;
-
-import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.List;
import java.util.concurrent.Executor;
-
import javax.inject.Inject;
/**
- * TV application.
+ * Live TV application.
*
* <p>This includes all the Google specific hooks.
*/
public abstract class TvApplication extends BaseApplication implements TvSingletons, Starter {
- protected static final StartupMeasure STARTUP_MEASURE = StartupMeasureFactory.create();
+ protected static final PerformanceMonitorManager PERFORMANCE_MONITOR_MANAGER =
+ PerformanceMonitorManagerFactory.create();
private static final String TAG = "TvApplication";
private static final boolean DEBUG = false;
+ /** Namespace for LiveChannels configs. LiveChannels configs are kept in piper. */
+ public static final String CONFIGNS_P4 = "configns:p4";
+
/**
* Broadcast Action: The user has updated LC to a new version that supports tuner input. {@link
* TunerInputController} will receive this intent to check the existence of tuner input when the
@@ -105,12 +102,12 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
private SelectInputActivity mSelectInputActivity;
- @Inject Lazy<ChannelDataManager> mChannelDataManager;
+ private ChannelDataManager mChannelDataManager;
private volatile ProgramDataManager mProgramDataManager;
private PreviewDataManager mPreviewDataManager;
private DvrManager mDvrManager;
private DvrScheduleManager mDvrScheduleManager;
- @Inject Lazy<DvrDataManager> mDvrDataManager;
+ private DvrDataManager mDvrDataManager;
private DvrWatchedPositionManager mDvrWatchedPositionManager;
private RecordingScheduler mRecordingScheduler;
private RecordingStorageStatusManager mDvrStorageStatusManager;
@@ -120,16 +117,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
private Boolean mRunningInMainProcess;
@Inject Lazy<TvInputManagerHelper> mLazyTvInputManagerHelper;
private boolean mStarted;
- @Inject EpgFetcher mEpgFetcher;
+ private EpgFetcher mEpgFetcher;
@Inject Optional<BuiltInTunerManager> mOptionalBuiltInTunerManager;
@Inject SetupUtils mSetupUtils;
@Inject @DbExecutor Executor mDbExecutor;
- @Inject Lazy<EpgReader> mEpgReader;
- @Inject BuildType mBuildType;
- @Inject CloudEpgFlags mCloudEpgFlags;
- @Inject LegacyFlags mLegacyFlags;
- @Inject PerformanceMonitor mPerformanceMonitor;
@Override
public void onCreate() {
@@ -140,8 +132,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
throw new IllegalStateException(msg);
}
super.onCreate();
- mPerformanceMonitor.startMemoryMonitor();
- mPerformanceMonitor.startCrashMonitor();
SharedPreferencesUtils.initialize(
this,
() -> {
@@ -156,15 +146,16 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
Log.w(TAG, "Unable to find package '" + getPackageName() + "'.", e);
mVersionName = "";
}
- Log.i(TAG, "Starting TV app " + getVersionName());
+ Log.i(TAG, "Starting Live TV " + getVersionName());
// In SetupFragment, transitions are set in the constructor. Because the fragment can be
// created in Activity.onCreate() by the framework, SetupAnimationHelper should be
// initialized here before Activity.onCreate() is called.
+ mEpgFetcher = EpgFetcherImpl.create(this);
SetupAnimationHelper.initialize(this);
getTvInputManagerHelper();
- Log.i(TAG, "Started TV app " + mVersionName);
+ Log.i(TAG, "Started Live TV " + mVersionName);
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.onCreate");
}
@@ -219,10 +210,8 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
mEpgFetcher.startRoutineService();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ChannelPreviewUpdater.getInstance(this).startRoutineService();
- if (CommonFeatures.DVR.isEnabled(this)) {
- RecordedProgramPreviewUpdater.getInstance(this)
- .updatePreviewDataForRecordedPrograms();
- }
+ RecordedProgramPreviewUpdater.getInstance(this)
+ .updatePreviewDataForRecordedPrograms();
}
}
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.start");
@@ -248,6 +237,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
}
@Override
+ public EpgFetcher getEpgFetcher() {
+ return mEpgFetcher;
+ }
+
+ @Override
public synchronized SetupUtils getSetupUtils() {
return mSetupUtils;
}
@@ -292,7 +286,16 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
/** Returns {@link ChannelDataManager}. */
@Override
public ChannelDataManager getChannelDataManager() {
- return mChannelDataManager.get();
+ if (mChannelDataManager == null) {
+ mChannelDataManager = new ChannelDataManager(this, getTvInputManagerHelper());
+ mChannelDataManager.start();
+ }
+ return mChannelDataManager;
+ }
+
+ @Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return mChannelDataManager != null && mChannelDataManager.isDbLoadFinished();
}
/** Returns {@link ProgramDataManager}. */
@@ -311,6 +314,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
return mProgramDataManager;
}
+ @Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return mProgramDataManager != null && mProgramDataManager.isCurrentProgramsLoadFinished();
+ }
+
/** Returns {@link PreviewDataManager}. */
@TargetApi(Build.VERSION_CODES.O)
@Override
@@ -326,7 +334,12 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
@TargetApi(Build.VERSION_CODES.N)
@Override
public DvrDataManager getDvrDataManager() {
- return mDvrDataManager.get();
+ if (mDvrDataManager == null) {
+ DvrDataManagerImpl dvrDataManager = new DvrDataManagerImpl(this, Clock.SYSTEM);
+ mDvrDataManager = dvrDataManager;
+ dvrDataManager.start();
+ }
+ return mDvrDataManager;
}
@Override
@@ -338,11 +351,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
return mDvrStorageStatusManager;
}
- @Override
- public PerformanceMonitor getPerformanceMonitor() {
- return mPerformanceMonitor;
- }
-
/** Returns the main activity information. */
@Override
public MainActivityWrapper getMainActivityWrapper() {
@@ -442,7 +450,7 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
}
/**
- * Returns the version name of the TV app.
+ * Returns the version name of the live channels.
*
* @see PackageInfo#versionName
*/
@@ -481,37 +489,6 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
Optional<String> optionalEmbeddedTunerInputId =
mOptionalBuiltInTunerManager.transform(
BuiltInTunerManager::getEmbeddedTunerInputId);
- // If there is only play movies trailer input, we don't handle input count change.
- final String playMoviesInputIdPrefix = "com.google.android.videos/";
- int tunerInputCount = 0;
- boolean hasPlayMoviesInput = false;
- for (TvInputInfo input : inputs) {
- if (calledByTunerServiceChanged
- && !tunerServiceEnabled
- && optionalEmbeddedTunerInputId.isPresent()
- && optionalEmbeddedTunerInputId.get().equals(input.getId())) {
- continue;
- }
- if (input.getType() == TvInputInfo.TYPE_TUNER) {
- if (DEBUG) Log.d(TAG, "Tuner input: " + input.getId());
- ++tunerInputCount;
- if (input.getId().startsWith(playMoviesInputIdPrefix)) {
- hasPlayMoviesInput = true;
- }
- }
- }
- if (DEBUG) {
- Log.d(
- TAG,
- "Input count: "
- + tunerInputCount
- + " hasPlayMoviesChannel: "
- + hasPlayMoviesInput);
- }
- if (tunerInputCount == 1 && hasPlayMoviesInput) {
- if (DEBUG) Log.d(TAG, "There is only play movies input");
- skipTunerInputCheck = true;
- }
// Enable the TvActivity only if there is at least one tuner type input.
if (!skipTunerInputCheck) {
for (TvInputInfo input : inputs) {
@@ -538,24 +515,13 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
if (packageManager.getComponentEnabledSetting(name) != newState) {
packageManager.setComponentEnabledSetting(
name, newState, dontKillApp ? PackageManager.DONT_KILL_APP : 0);
- Log.i(TAG, (enable ? "Un-hide" : "Hide") + " TV app.");
+ Log.i(TAG, (enable ? "Un-hide" : "Hide") + " Live TV.");
}
mSetupUtils.onInputListUpdated(inputManager);
}
@Override
- @DbExecutor
public Executor getDbExecutor() {
return mDbExecutor;
}
-
- @Override
- public Lazy<EpgReader> providesEpgReader() {
- return mEpgReader;
- }
-
- @Override
- public BuildType getBuildType() {
- return mBuildType;
- }
}
diff --git a/src/com/android/tv/TvSingletons.java b/src/com/android/tv/TvSingletons.java
index 9e4f4620..20edf3d4 100644
--- a/src/com/android/tv/TvSingletons.java
+++ b/src/com/android/tv/TvSingletons.java
@@ -17,15 +17,16 @@
package com.android.tv;
import android.content.Context;
-
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BaseApplication;
import com.android.tv.common.BaseSingletons;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.has.HasUiFlags;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -36,27 +37,14 @@ import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.tunerinputcontroller.HasBuiltInTunerManager;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-
-import dagger.Lazy;
-
+import com.android.tv.util.account.AccountHelper;
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.util.concurrent.Executor;
+import javax.inject.Provider;
/** Interface with getters for application scoped singletons. */
public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, HasUiFlags {
- /*
- * Do not add any new methods here.
- *
- * To move a getter to Injection.
- * 1. Make a type injectable @Singleton.
- * 2. Mark the getter here as deprecated.
- * 3. Lazily inject the object in TvApplication.
- * 4. Move easy usages of getters to injection instead.
- * 5. Delete the method when all usages are migrated.
- */
-
/**
* Returns the @{@link TvSingletons} using the application context.
*
@@ -74,14 +62,24 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
@Deprecated
ChannelDataManager getChannelDataManager();
+ /**
+ * Checks if the {@link ChannelDataManager} instance has been created and all the channels has
+ * been loaded.
+ */
+ boolean isChannelDataManagerLoadFinished();
+
/** @deprecated use injection instead. */
@Deprecated
ProgramDataManager getProgramDataManager();
+ /**
+ * Checks if the {@link ProgramDataManager} instance has been created and the current programs
+ * for all the channels has been loaded.
+ */
+ boolean isProgramDataManagerCurrentProgramsLoadFinished();
+
PreviewDataManager getPreviewDataManager();
- /** @deprecated use injection instead. */
- @Deprecated
DvrDataManager getDvrDataManager();
DvrScheduleManager getDvrScheduleManager();
@@ -90,8 +88,6 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
RecordingScheduler getRecordingScheduler();
- /** @deprecated use injection instead. */
- @Deprecated
DvrWatchedPositionManager getDvrWatchedPositionManager();
InputSessionManager getInputSessionManager();
@@ -100,22 +96,26 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
MainActivityWrapper getMainActivityWrapper();
+ AccountHelper getAccountHelper();
+
boolean isRunningInMainProcess();
- /** @deprecated use injection instead. */
- @Deprecated
PerformanceMonitor getPerformanceMonitor();
/** @deprecated use injection instead. */
@Deprecated
TvInputManagerHelper getTvInputManagerHelper();
- Lazy<EpgReader> providesEpgReader();
+ Provider<EpgReader> providesEpgReader();
+
+ EpgFetcher getEpgFetcher();
/** @deprecated use injection instead. */
@Deprecated
SetupUtils getSetupUtils();
+ ExperimentLoader getExperimentLoader();
+
/** @deprecated use injection instead. */
@Deprecated
Executor getDbExecutor();
diff --git a/src/com/android/tv/app/LiveTvApplication.java b/src/com/android/tv/app/LiveTvApplication.java
index 80906537..38e85e48 100644
--- a/src/com/android/tv/app/LiveTvApplication.java
+++ b/src/com/android/tv/app/LiveTvApplication.java
@@ -22,34 +22,50 @@ import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.StubAnalytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.dagger.ApplicationModule;
+import com.android.tv.common.experiments.ExperimentLoader;
import com.android.tv.common.flags.impl.DefaultBackendKnobsFlags;
import com.android.tv.common.flags.impl.DefaultCloudEpgFlags;
+import com.android.tv.common.flags.impl.DefaultConcurrentDvrPlaybackFlags;
import com.android.tv.common.flags.impl.DefaultUiFlags;
import com.android.tv.common.singletons.HasSingletons;
+import com.android.tv.data.epg.EpgReader;
+import com.android.tv.data.epg.StubEpgReader;
import com.android.tv.modules.TvSingletonsModule;
import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-
+import com.android.tv.util.account.AccountHelper;
+import com.android.tv.util.account.AccountHelperImpl;
import com.google.common.base.Optional;
-
import dagger.android.AndroidInjector;
-
-import javax.inject.Inject;
+import javax.inject.Provider;
/** The top level application for Live TV. */
public class LiveTvApplication extends TvApplication implements HasSingletons<TvSingletons> {
static {
- STARTUP_MEASURE.onAppClassLoaded();
+ PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppClassLoaded();
}
+ private final Provider<EpgReader> mEpgReaderProvider =
+ new Provider<EpgReader>() {
+
+ @Override
+ public EpgReader get() {
+ return new StubEpgReader(LiveTvApplication.this);
+ }
+ };
+
private final DefaultBackendKnobsFlags mBackendKnobsFlags = new DefaultBackendKnobsFlags();
private final DefaultCloudEpgFlags mCloudEpgFlags = new DefaultCloudEpgFlags();
private final DefaultUiFlags mUiFlags = new DefaultUiFlags();
-
+ private final DefaultConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags =
+ new DefaultConcurrentDvrPlaybackFlags();
+ private AccountHelper mAccountHelper;
private Analytics mAnalytics;
private Tracker mTracker;
- @Inject PerformanceMonitor mPerformanceMonitor;
+ private ExperimentLoader mExperimentLoader;
+ private PerformanceMonitor mPerformanceMonitor;
@Override
protected AndroidInjector<LiveTvApplication> applicationInjector() {
@@ -62,15 +78,38 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
@Override
public void onCreate() {
super.onCreate();
- STARTUP_MEASURE.onAppCreate(this);
+ PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppCreate(this);
}
+ /** Returns the {@link AccountHelperImpl}. */
@Override
- public PerformanceMonitor getPerformanceMonitor() {
+ public AccountHelper getAccountHelper() {
+ if (mAccountHelper == null) {
+ mAccountHelper = new AccountHelperImpl(getApplicationContext());
+ }
+ return mAccountHelper;
+ }
+
+ @Override
+ public synchronized PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = PerformanceMonitorManagerFactory.create().initialize(this);
+ }
return mPerformanceMonitor;
}
@Override
+ public Provider<EpgReader> providesEpgReader() {
+ return mEpgReaderProvider;
+ }
+
+ @Override
+ public ExperimentLoader getExperimentLoader() {
+ mExperimentLoader = new ExperimentLoader();
+ return mExperimentLoader;
+ }
+
+ @Override
public DefaultBackendKnobsFlags getBackendKnobs() {
return mBackendKnobsFlags;
}
@@ -109,6 +148,16 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
}
@Override
+ public BuildType getBuildType() {
+ return BuildType.AOSP;
+ }
+
+ @Override
+ public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
+ return mConcurrentDvrPlaybackFlags;
+ }
+
+ @Override
public TvSingletons singletons() {
return this;
}
diff --git a/src/com/android/tv/app/LiveTvApplicationComponent.java b/src/com/android/tv/app/LiveTvApplicationComponent.java
index 71ce1a8a..3d3f0492 100644
--- a/src/com/android/tv/app/LiveTvApplicationComponent.java
+++ b/src/com/android/tv/app/LiveTvApplicationComponent.java
@@ -15,7 +15,6 @@
*/
package com.android.tv.app;
-import com.android.tv.search.LocalSearchProvider;
import dagger.Component;
import dagger.android.AndroidInjectionModule;
import dagger.android.AndroidInjector;
@@ -23,10 +22,5 @@ import javax.inject.Singleton;
/** Dagger component for {@link LiveTvApplication}. */
@Singleton
-@Component(
- modules = {
- AndroidInjectionModule.class,
- LiveTvModule.class,
- LocalSearchProvider.Module.class
- })
+@Component(modules = {AndroidInjectionModule.class, LiveTvModule.class})
public interface LiveTvApplicationComponent extends AndroidInjector<LiveTvApplication> {}
diff --git a/src/com/android/tv/app/LiveTvModule.java b/src/com/android/tv/app/LiveTvModule.java
index db631bc0..a28749bd 100644
--- a/src/com/android/tv/app/LiveTvModule.java
+++ b/src/com/android/tv/app/LiveTvModule.java
@@ -16,49 +16,18 @@
package com.android.tv.app;
import com.android.tv.common.flags.impl.DefaultFlagsModule;
-import com.android.tv.data.epg.EpgReader;
-import com.android.tv.data.epg.StubEpgReader;
import com.android.tv.modules.TvApplicationModule;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.stub.StubPerformanceMonitor;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
-import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
-import com.android.tv.util.account.AccountHelper;
-import com.android.tv.util.account.AccountHelperImpl;
import com.google.common.base.Optional;
import dagger.Module;
import dagger.Provides;
-import javax.inject.Singleton;
/** Dagger module for {@link LiveTvApplication}. */
@Module(includes = {DefaultFlagsModule.class, TvApplicationModule.class})
class LiveTvModule {
@Provides
- static AccountHelper providesAccountHelper(AccountHelperImpl impl) {
- return impl;
- }
-
- @Provides
- static Optional<DeveloperOptionFragment.AdditionalDeveloperItemsFactory>
- providesAdditionalDeveloperItemsFactory() {
- return Optional.absent();
- }
-
- @Provides
Optional<BuiltInTunerManager> providesBuiltInTunerManager() {
return Optional.absent();
}
-
- @Provides
- @Singleton
- PerformanceMonitor providesPerformanceMonitor() {
- return new StubPerformanceMonitor();
- }
-
- @Provides
- @Singleton
- static EpgReader providesEpgReader(StubEpgReader impl) {
- return impl;
- }
}
diff --git a/src/com/android/tv/data/BaseProgram.java b/src/com/android/tv/data/BaseProgram.java
new file mode 100644
index 00000000..9650fd18
--- /dev/null
+++ b/src/com/android/tv/data/BaseProgram.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.data;
+
+import android.content.Context;
+import android.media.tv.TvContentRating;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.tv.R;
+import com.google.common.collect.ImmutableList;
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * Base class for {@link com.android.tv.data.Program} and {@link
+ * com.android.tv.dvr.data.RecordedProgram}.
+ */
+public abstract class BaseProgram {
+ /**
+ * Comparator used to compare {@link BaseProgram} according to its season and episodes number.
+ * If a program's season or episode number is null, it will be consider "smaller" than programs
+ * with season or episode numbers.
+ */
+ public static final Comparator<BaseProgram> EPISODE_COMPARATOR = new EpisodeComparator(false);
+
+ /**
+ * Comparator used to compare {@link BaseProgram} according to its season and episodes number
+ * with season numbers in a reversed order. If a program's season or episode number is null, it
+ * will be consider "smaller" than programs with season or episode numbers.
+ */
+ public static final Comparator<BaseProgram> SEASON_REVERSED_EPISODE_COMPARATOR =
+ new EpisodeComparator(true);
+
+ public static final String COLUMN_SERIES_ID = "series_id";
+
+ public static final String COLUMN_STATE = "state";
+
+ private static class EpisodeComparator implements Comparator<BaseProgram> {
+ private final boolean mReversedSeason;
+
+ EpisodeComparator(boolean reversedSeason) {
+ mReversedSeason = reversedSeason;
+ }
+
+ @Override
+ public int compare(BaseProgram lhs, BaseProgram rhs) {
+ if (lhs == rhs) {
+ return 0;
+ }
+ int seasonNumberCompare = numberCompare(lhs.getSeasonNumber(), rhs.getSeasonNumber());
+ if (seasonNumberCompare != 0) {
+ return mReversedSeason ? -seasonNumberCompare : seasonNumberCompare;
+ } else {
+ return numberCompare(lhs.getEpisodeNumber(), rhs.getEpisodeNumber());
+ }
+ }
+ }
+
+ /** Compares two strings represent season numbers or episode numbers of programs. */
+ public static int numberCompare(String s1, String s2) {
+ if (Objects.equals(s1, s2)) {
+ return 0;
+ } else if (s1 == null) {
+ return -1;
+ } else if (s2 == null) {
+ return 1;
+ } else if (s1.equals(s2)) {
+ return 0;
+ }
+ try {
+ return Integer.compare(Integer.parseInt(s1), Integer.parseInt(s2));
+ } catch (NumberFormatException e) {
+ return s1.compareTo(s2);
+ }
+ }
+
+ /** Returns ID of the program. */
+ public abstract long getId();
+
+ /** Returns the title of the program. */
+ public abstract String getTitle();
+
+ /** Returns the episode title. */
+ public abstract String getEpisodeTitle();
+
+ /** Returns the displayed title of the program episode. */
+ @Nullable
+ public String getEpisodeDisplayTitle(Context context) {
+ String episodeNumber = getEpisodeNumber();
+ String episodeTitle = getEpisodeTitle();
+ if (!TextUtils.isEmpty(episodeNumber)) {
+ episodeTitle = episodeTitle == null ? "" : episodeTitle;
+ String seasonNumber = getSeasonNumber();
+ if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
+ // Do not show "S0: ".
+ return context.getResources()
+ .getString(
+ R.string.display_episode_title_format_no_season_number,
+ episodeNumber,
+ episodeTitle);
+ } else {
+ return context.getResources()
+ .getString(
+ R.string.display_episode_title_format,
+ seasonNumber,
+ episodeNumber,
+ episodeTitle);
+ }
+ }
+ return episodeTitle;
+ }
+
+ /**
+ * Returns the content description of the program episode, suitable for being spoken by an
+ * accessibility service.
+ */
+ public String getEpisodeContentDescription(Context context) {
+ String episodeNumber = getEpisodeNumber();
+ String episodeTitle = getEpisodeTitle();
+ if (!TextUtils.isEmpty(episodeNumber)) {
+ episodeTitle = episodeTitle == null ? "" : episodeTitle;
+ String seasonNumber = getSeasonNumber();
+ if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
+ // Do not list season if it is empty or 0
+ return context.getResources()
+ .getString(
+ R.string.content_description_episode_format_no_season_number,
+ episodeNumber,
+ episodeTitle);
+ } else {
+ return context.getResources()
+ .getString(
+ R.string.content_description_episode_format,
+ seasonNumber,
+ episodeNumber,
+ episodeTitle);
+ }
+ }
+ return episodeTitle;
+ }
+
+ /** Returns the description of the program. */
+ public abstract String getDescription();
+
+ /** Returns the long description of the program. */
+ public abstract String getLongDescription();
+
+ /** Returns the start time of the program in Milliseconds. */
+ public abstract long getStartTimeUtcMillis();
+
+ /** Returns the end time of the program in Milliseconds. */
+ public abstract long getEndTimeUtcMillis();
+
+ /** Returns the duration of the program in Milliseconds. */
+ public abstract long getDurationMillis();
+
+ /** Returns the series ID. */
+ @Nullable
+ public abstract String getSeriesId();
+
+ /** Returns the season number. */
+ public abstract String getSeasonNumber();
+
+ /** Returns the episode number. */
+ public abstract String getEpisodeNumber();
+
+ /** Returns URI of the program's poster. */
+ public abstract String getPosterArtUri();
+
+ /** Returns URI of the program's thumbnail. */
+ public abstract String getThumbnailUri();
+
+ /** Returns the array of the ID's of the canonical genres. */
+ public abstract int[] getCanonicalGenreIds();
+
+ /** Returns the array of content ratings. */
+ public abstract ImmutableList<TvContentRating> getContentRatings();
+
+ /** Returns channel's ID of the program. */
+ public abstract long getChannelId();
+
+ /** Returns if the program is valid. */
+ public abstract boolean isValid();
+
+ /** Checks whether the program is episodic or not. */
+ public boolean isEpisodic() {
+ return getSeriesId() != null;
+ }
+
+ /** Generates the series ID for the other inputs than the tuner TV input. */
+ public static String generateSeriesId(String packageName, String title) {
+ return packageName + "/" + title;
+ }
+}
diff --git a/src/com/android/tv/data/BaseProgramImpl.java b/src/com/android/tv/data/BaseProgramImpl.java
deleted file mode 100644
index 9c8d0256..00000000
--- a/src/com/android/tv/data/BaseProgramImpl.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.data;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.data.api.BaseProgram;
-
-/** Base class for {@link ProgramImpl} and {@link com.android.tv.dvr.data.RecordedProgram}. */
-public abstract class BaseProgramImpl implements BaseProgram {
-
- @Override
- @Nullable
- public String getEpisodeDisplayTitle(Context context) {
- String episodeNumber = getEpisodeNumber();
- String episodeTitle = getEpisodeTitle();
- if (!TextUtils.isEmpty(episodeNumber)) {
- episodeTitle = episodeTitle == null ? "" : episodeTitle;
- String seasonNumber = getSeasonNumber();
- if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
- // Do not show "S0: ".
- return context.getResources()
- .getString(
- R.string.display_episode_title_format_no_season_number,
- episodeNumber,
- episodeTitle);
- } else {
- return context.getResources()
- .getString(
- R.string.display_episode_title_format,
- seasonNumber,
- episodeNumber,
- episodeTitle);
- }
- }
- return episodeTitle;
- }
-
- @Override
- public String getEpisodeContentDescription(Context context) {
- String episodeNumber = getEpisodeNumber();
- String episodeTitle = getEpisodeTitle();
- if (!TextUtils.isEmpty(episodeNumber)) {
- episodeTitle = episodeTitle == null ? "" : episodeTitle;
- String seasonNumber = getSeasonNumber();
- if (TextUtils.isEmpty(seasonNumber) || TextUtils.equals(seasonNumber, "0")) {
- // Do not list season if it is empty or 0
- return context.getResources()
- .getString(
- R.string.content_description_episode_format_no_season_number,
- episodeNumber,
- episodeTitle);
- } else {
- return context.getResources()
- .getString(
- R.string.content_description_episode_format,
- seasonNumber,
- episodeNumber,
- episodeTitle);
- }
- }
- return episodeTitle;
- }
-
- @Override
- public boolean isEpisodic() {
- return !TextUtils.isEmpty(getSeriesId());
- }
-}
diff --git a/src/com/android/tv/data/ChannelDataManager.java b/src/com/android/tv/data/ChannelDataManager.java
index 67c32309..a5c786cf 100644
--- a/src/com/android/tv/data/ChannelDataManager.java
+++ b/src/com/android/tv/data/ChannelDataManager.java
@@ -37,18 +37,15 @@ import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
import android.util.MutableInt;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.data.api.Channel;
import com.android.tv.util.AsyncDbTask;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
@@ -59,7 +56,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
-import javax.inject.Singleton;
/**
* The class to manage channel data. Basic features: reading channel list and each channel's current
@@ -68,8 +64,6 @@ import javax.inject.Singleton;
* methods are called in only the main thread.
*/
@AnyThread
-@AutoFactory
-@Singleton
public class ChannelDataManager {
private static final String TAG = "ChannelDataManager";
private static final boolean DEBUG = false;
@@ -149,11 +143,21 @@ public class ChannelDataManager {
};
@MainThread
- public ChannelDataManager(
- @Provided @ApplicationContext Context context,
- @Provided TvInputManagerHelper inputManager,
- @Provided @DbExecutor Executor executor,
- @Provided ContentResolver contentResolver) {
+ public ChannelDataManager(Context context, TvInputManagerHelper inputManager) {
+ this(
+ context,
+ inputManager,
+ TvSingletons.getSingletons(context).getDbExecutor(),
+ context.getContentResolver());
+ }
+
+ @MainThread
+ @VisibleForTesting
+ ChannelDataManager(
+ Context context,
+ TvInputManagerHelper inputManager,
+ Executor executor,
+ ContentResolver contentResolver) {
mContext = context;
mInputManager = inputManager;
mDbExecutor = executor;
@@ -725,7 +729,7 @@ public class ChannelDataManager {
/**
* Updates a column {@code columnName} of DB table {@code uri} with the value {@code
* columnValue}. The selective rows in the ID list {@code ids} will be updated. The DB
- * operations will run on @{@link DbExecutor}.
+ * operations will run on {@link TvSingletons#getDbExecutor()}.
*/
private void updateOneColumnValue(
final String columnName, final int columnValue, final List<Long> ids) {
diff --git a/src/com/android/tv/data/InternalDataUtils.java b/src/com/android/tv/data/InternalDataUtils.java
index b17ed092..4c30d395 100644
--- a/src/com/android/tv/data/InternalDataUtils.java
+++ b/src/com/android/tv/data/InternalDataUtils.java
@@ -19,11 +19,8 @@ package com.android.tv.data;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-
-import com.android.tv.data.api.Program;
-import com.android.tv.data.api.Program.CriticScore;
+import com.android.tv.data.Program.CriticScore;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -52,7 +49,7 @@ public final class InternalDataUtils {
* @param bytes the bytes to be deserialized
* @param builder the builder for the Program class
*/
- public static void deserializeInternalProviderData(byte[] bytes, ProgramImpl.Builder builder) {
+ public static void deserializeInternalProviderData(byte[] bytes, Program.Builder builder) {
if (bytes == null || bytes.length == 0) {
return;
}
diff --git a/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java b/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
index 2332cda4..edb33556 100644
--- a/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
+++ b/src/com/android/tv/data/OnCurrentProgramUpdatedListener.java
@@ -16,8 +16,6 @@
package com.android.tv.data;
-import com.android.tv.data.api.Program;
-
public interface OnCurrentProgramUpdatedListener {
/** Called when the current program is updated. */
void onCurrentProgramUpdated(long channelId, Program program);
diff --git a/src/com/android/tv/data/PreviewDataManager.java b/src/com/android/tv/data/PreviewDataManager.java
index dbe6028c..8616aeec 100644
--- a/src/com/android/tv/data/PreviewDataManager.java
+++ b/src/com/android/tv/data/PreviewDataManager.java
@@ -32,14 +32,10 @@ import android.support.annotation.IntDef;
import android.support.annotation.MainThread;
import android.util.Log;
import android.util.Pair;
-
import androidx.tvprovider.media.tv.ChannelLogoUtils;
import androidx.tvprovider.media.tv.PreviewProgram;
-
import com.android.tv.R;
import com.android.tv.common.util.PermissionUtils;
-import com.android.tv.util.images.ImageLoader;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
@@ -222,7 +218,7 @@ public class PreviewDataManager {
Uri previewChannelsUri =
PreviewDataUtils.addQueryParamToUri(
TvContract.Channels.CONTENT_URI,
- Pair.create(PARAM_PREVIEW, String.valueOf(true)));
+ new Pair<>(PARAM_PREVIEW, String.valueOf(true)));
String packageName = mContext.getPackageName();
if (PermissionUtils.hasAccessAllEpg(mContext)) {
try (Cursor cursor =
@@ -432,14 +428,10 @@ public class PreviewDataManager {
continue;
}
try {
- int aspectRatio =
- ImageLoader.getAspectRatioFromPosterArtUri(
- mContext, program.getPosterArtUri().toString());
Uri programUri =
mContentResolver.insert(
TvContract.PreviewPrograms.CONTENT_URI,
- PreviewDataUtils.createPreviewProgramFromContent(
- program, aspectRatio)
+ PreviewDataUtils.createPreviewProgramFromContent(program)
.toContentValues());
if (programUri != null) {
long previewProgramId = ContentUris.parseId(programUri);
@@ -600,14 +592,13 @@ public class PreviewDataManager {
/** Creates a preview program. */
public static PreviewProgram createPreviewProgramFromContent(
- PreviewProgramContent program, int aspectRatio) {
+ PreviewProgramContent program) {
PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(program.getPreviewChannelId())
.setType(program.getType())
.setLive(program.getLive())
.setTitle(program.getTitle())
.setDescription(program.getDescription())
- .setPosterArtAspectRatio(aspectRatio)
.setPosterArtUri(program.getPosterArtUri())
.setIntentUri(program.getIntentUri())
.setPreviewVideoUri(program.getPreviewVideoUri())
diff --git a/src/com/android/tv/data/PreviewProgramContent.java b/src/com/android/tv/data/PreviewProgramContent.java
index 4ee57104..8d4b88cf 100644
--- a/src/com/android/tv/data/PreviewProgramContent.java
+++ b/src/com/android/tv/data/PreviewProgramContent.java
@@ -21,14 +21,10 @@ import android.net.Uri;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Pair;
-
import androidx.tvprovider.media.tv.TvContractCompat;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.util.Objects;
/** A class to store the content of preview programs. */
@@ -45,7 +41,7 @@ public class PreviewProgramContent {
private Uri mIntentUri;
private Uri mPreviewVideoUri;
- /** Create preview program content from {@link ProgramImpl} */
+ /** Create preview program content from {@link Program} */
public static PreviewProgramContent createFromProgram(
Context context, long previewChannelId, Program program) {
Channel channel =
@@ -83,7 +79,7 @@ public class PreviewProgramContent {
.setIntentUri(channel.getUri())
.setPreviewVideoUri(
PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
- channel.getUri(), Pair.create(PARAM_INPUT, channel.getInputId())))
+ channel.getUri(), new Pair<>(PARAM_INPUT, channel.getInputId())))
.build();
}
@@ -103,7 +99,7 @@ public class PreviewProgramContent {
.setPreviewVideoUri(
PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
recordedProgramUri,
- Pair.create(PARAM_INPUT, recordedProgram.getInputId())))
+ new Pair<>(PARAM_INPUT, recordedProgram.getInputId())))
.build();
}
diff --git a/src/com/android/tv/data/ProgramImpl.java b/src/com/android/tv/data/Program.java
index 5097e2d4..b688927a 100644
--- a/src/com/android/tv/data/ProgramImpl.java
+++ b/src/com/android/tv/data/Program.java
@@ -32,26 +32,24 @@ import android.support.annotation.UiThread;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
-
+import android.util.Log;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.util.CollectionUtils;
import com.android.tv.common.util.CommonUtils;
-import com.android.tv.data.api.BaseProgram;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvProviderUtils;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
-
import com.google.common.collect.ImmutableList;
-
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/** A convenience class to create and insert program information entries into the database. */
-public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Program {
+public final class Program extends BaseProgram implements Comparable<Program>, Parcelable {
private static final boolean DEBUG = false;
private static final boolean DEBUG_DUMP_DESCRIPTION = false;
private static final String TAG = "Program";
@@ -181,8 +179,8 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return builder.build();
}
- public static ProgramImpl fromParcel(Parcel in) {
- ProgramImpl program = new ProgramImpl();
+ public static Program fromParcel(Parcel in) {
+ Program program = new Program();
program.mId = in.readLong();
program.mPackageName = in.readString();
program.mChannelId = in.readLong();
@@ -221,7 +219,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
new Parcelable.Creator<Program>() {
@Override
public Program createFromParcel(Parcel in) {
- return ProgramImpl.fromParcel(in);
+ return Program.fromParcel(in);
}
@Override
@@ -253,21 +251,19 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
private ImmutableList<TvContentRating> mContentRatings;
private boolean mRecordingProhibited;
- private ProgramImpl() {
+ private Program() {
// Do nothing.
}
- @Override
public long getId() {
return mId;
}
- @Override
+ /** Returns the package name of this program. */
public String getPackageName() {
return mPackageName;
}
- @Override
public long getChannelId() {
return mChannelId;
}
@@ -278,6 +274,11 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mChannelId >= 0;
}
+ /** Returns {@code true} if the program is valid and {@code false} otherwise. */
+ public static boolean isProgramValid(Program program) {
+ return program != null && program.isValid();
+ }
+
@Override
public String getTitle() {
return mTitle;
@@ -301,11 +302,6 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
@Override
- public String getSeasonTitle() {
- return mSeasonTitle;
- }
-
- @Override
public String getEpisodeNumber() {
return mEpisodeNumber;
}
@@ -320,7 +316,6 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mEndTimeUtcMillis;
}
- @Override
public String getDurationString(Context context) {
// TODO(b/71717446): expire the calculated string
if (mDurationString == null) {
@@ -346,17 +341,15 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mLongDescription;
}
- @Override
public int getVideoWidth() {
return mVideoWidth;
}
- @Override
public int getVideoHeight() {
return mVideoHeight;
}
- @Override
+ /** Returns the list of Critic Scores for this program */
@Nullable
public List<CriticScore> getCriticScores() {
return mCriticScores;
@@ -378,12 +371,12 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mThumbnailUri;
}
- @Override
+ /** Returns {@code true} if the recording of this program is prohibited. */
public boolean isRecordingProhibited() {
return mRecordingProhibited;
}
- @Override
+ /** Returns array of canonical genres for this program. This is expected to be called rarely. */
@Nullable
public String[] getCanonicalGenres() {
if (mCanonicalGenreIds == null) {
@@ -402,7 +395,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return mCanonicalGenreIds;
}
- @Override
+ /** Returns if this program has the genre. */
public boolean hasGenre(int genreId) {
if (genreId == GenreItems.ID_ALL_CHANNELS) {
return true;
@@ -443,11 +436,11 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
@Override
public boolean equals(Object other) {
- if (!(other instanceof ProgramImpl)) {
+ if (!(other instanceof Program)) {
return false;
}
// Compare all the properties because program ID can be invalid for the dummy programs.
- ProgramImpl program = (ProgramImpl) other;
+ Program program = (Program) other;
return Objects.equals(mPackageName, program.mPackageName)
&& mChannelId == program.mChannelId
&& mStartTimeUtcMillis == program.mStartTimeUtcMillis
@@ -471,7 +464,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
@Override
public int compareTo(@NonNull Program other) {
- return Long.compare(mStartTimeUtcMillis, other.getStartTimeUtcMillis());
+ return Long.compare(mStartTimeUtcMillis, other.mStartTimeUtcMillis);
}
@Override
@@ -523,7 +516,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
/**
- * Translates a {@link ProgramImpl} to {@link ContentValues} that are ready to be written into
+ * Translates a {@link Program} to {@link ContentValues} that are ready to be written into
* Database.
*/
@SuppressLint("InlinedApi")
@@ -602,37 +595,37 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
return;
}
- mId = other.getId();
- mPackageName = other.getPackageName();
- mChannelId = other.getChannelId();
- mTitle = other.getTitle();
- mSeriesId = other.getSeriesId();
- mEpisodeTitle = other.getEpisodeTitle();
- mSeasonNumber = other.getSeasonNumber();
- mSeasonTitle = other.getSeasonTitle();
- mEpisodeNumber = other.getEpisodeNumber();
- mStartTimeUtcMillis = other.getStartTimeUtcMillis();
- mEndTimeUtcMillis = other.getEndTimeUtcMillis();
+ mId = other.mId;
+ mPackageName = other.mPackageName;
+ mChannelId = other.mChannelId;
+ mTitle = other.mTitle;
+ mSeriesId = other.mSeriesId;
+ mEpisodeTitle = other.mEpisodeTitle;
+ mSeasonNumber = other.mSeasonNumber;
+ mSeasonTitle = other.mSeasonTitle;
+ mEpisodeNumber = other.mEpisodeNumber;
+ mStartTimeUtcMillis = other.mStartTimeUtcMillis;
+ mEndTimeUtcMillis = other.mEndTimeUtcMillis;
mDurationString = null; // Recreate Duration when needed.
- mDescription = other.getDescription();
- mLongDescription = other.getLongDescription();
- mVideoWidth = other.getVideoWidth();
- mVideoHeight = other.getVideoHeight();
- mCriticScores = other.getCriticScores();
- mPosterArtUri = other.getPosterArtUri();
- mThumbnailUri = other.getThumbnailUri();
- mCanonicalGenreIds = other.getCanonicalGenreIds();
- mContentRatings = other.getContentRatings();
- mRecordingProhibited = other.isRecordingProhibited();
+ mDescription = other.mDescription;
+ mLongDescription = other.mLongDescription;
+ mVideoWidth = other.mVideoWidth;
+ mVideoHeight = other.mVideoHeight;
+ mCriticScores = other.mCriticScores;
+ mPosterArtUri = other.mPosterArtUri;
+ mThumbnailUri = other.mThumbnailUri;
+ mCanonicalGenreIds = other.mCanonicalGenreIds;
+ mContentRatings = other.mContentRatings;
+ mRecordingProhibited = other.mRecordingProhibited;
}
/** A Builder for the Program class */
public static final class Builder {
- private final ProgramImpl mProgram;
+ private final Program mProgram;
/** Creates a Builder for this Program class */
public Builder() {
- mProgram = new ProgramImpl();
+ mProgram = new Program();
// Fill initial data.
mProgram.mPackageName = null;
mProgram.mChannelId = Channel.INVALID_ID;
@@ -657,7 +650,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
*/
@VisibleForTesting
public Builder(Program other) {
- mProgram = new ProgramImpl();
+ mProgram = new Program();
mProgram.copyFrom(other);
}
@@ -913,7 +906,7 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
*
* @return the Program object constructed
*/
- public ProgramImpl build() {
+ public Program build() {
// Generate the series ID for the episodic program of other TV input.
if (TextUtils.isEmpty(mProgram.mTitle)) {
// If title is null, series cannot be generated for this program.
@@ -923,13 +916,17 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
// If series ID is not set, generate it for the episodic program of other TV input.
setSeriesId(BaseProgram.generateSeriesId(mProgram.mPackageName, mProgram.mTitle));
}
- ProgramImpl program = new ProgramImpl();
+ Program program = new Program();
program.copyFrom(mProgram);
return program;
}
}
- @Override
+ /**
+ * Prefetches the program poster art.
+ *
+ * <p>
+ */
public void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight) {
if (mPosterArtUri == null) {
return;
@@ -937,13 +934,20 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
ImageLoader.prefetchBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight);
}
- @Override
+ /**
+ * Loads the program poster art and returns it via {@code callback}.
+ *
+ * <p>Note that it may directly call {@code callback} if the program poster art already is
+ * loaded.
+ *
+ * @return {@code true} if the load is complete and the callback is executed.
+ */
@UiThread
public boolean loadPosterArt(
Context context,
int posterArtWidth,
int posterArtHeight,
- ImageLoader.ImageLoaderCallback<?> callback) {
+ ImageLoader.ImageLoaderCallback callback) {
if (mPosterArtUri == null) {
return false;
}
@@ -951,9 +955,24 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
}
- @Override
- public Parcelable toParcelable() {
- return this;
+ public static boolean isDuplicate(Program p1, Program p2) {
+ if (p1 == null || p2 == null) {
+ return false;
+ }
+ boolean isDuplicate =
+ p1.getChannelId() == p2.getChannelId()
+ && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
+ && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
+ if (DEBUG && BuildConfig.ENG && isDuplicate) {
+ Log.w(
+ TAG,
+ "Duplicate programs detected! - \""
+ + p1.getTitle()
+ + "\" and \""
+ + p2.getTitle()
+ + "\"");
+ }
+ return isDuplicate;
}
@Override
@@ -990,4 +1009,54 @@ public final class ProgramImpl extends BaseProgramImpl implements Parcelable, Pr
}
out.writeByte((byte) (mRecordingProhibited ? 1 : 0));
}
+
+ /** Holds one type of critic score and its source. */
+ public static final class CriticScore implements Serializable, Parcelable {
+ /** The source of the rating. */
+ public final String source;
+ /** The score. */
+ public final String score;
+ /** The url of the logo image */
+ public final String logoUrl;
+
+ public static final Parcelable.Creator<CriticScore> CREATOR =
+ new Parcelable.Creator<CriticScore>() {
+ @Override
+ public CriticScore createFromParcel(Parcel in) {
+ String source = in.readString();
+ String score = in.readString();
+ String logoUri = in.readString();
+ return new CriticScore(source, score, logoUri);
+ }
+
+ @Override
+ public CriticScore[] newArray(int size) {
+ return new CriticScore[size];
+ }
+ };
+
+ /**
+ * Constructor for this class.
+ *
+ * @param source the source of the rating
+ * @param score the score
+ */
+ public CriticScore(String source, String score, String logoUrl) {
+ this.source = source;
+ this.score = score;
+ this.logoUrl = logoUrl;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int i) {
+ out.writeString(source);
+ out.writeString(score);
+ out.writeString(logoUrl);
+ }
+ }
}
diff --git a/src/com/android/tv/data/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index a866c78e..2f20c89a 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -33,24 +33,19 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.LruCache;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.memory.MemoryManageable;
import com.android.tv.common.util.Clock;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.MultiLongSparseArray;
-import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvProviderUtils;
import com.android.tv.util.Utils;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -80,11 +75,6 @@ public class ProgramDataManager implements MemoryManageable {
private static final long CURRENT_PROGRAM_UPDATE_WAIT_MS = TimeUnit.SECONDS.toMillis(5);
@VisibleForTesting static final long PROGRAM_GUIDE_SNAP_TIME_MS = TimeUnit.MINUTES.toMillis(30);
- // Default fetch hours
- private static final long FETCH_HOURS_MS = TimeUnit.HOURS.toMillis(24);
- // Load data earlier for smooth scrolling.
- private static final long BUFFER_HOURS_MS = TimeUnit.HOURS.toMillis(6);
-
// TODO: Use TvContract constants, once they become public.
private static final String PARAM_START_TIME = "start_time";
private static final String PARAM_END_TIME = "end_time";
@@ -96,20 +86,10 @@ public class ProgramDataManager implements MemoryManageable {
+ Programs.COLUMN_CHANNEL_ID
+ ", "
+ Programs.COLUMN_END_TIME_UTC_MILLIS;
- private static final String SORT_BY_CHANNEL_ID =
- Programs.COLUMN_CHANNEL_ID
- + ", "
- + Programs.COLUMN_START_TIME_UTC_MILLIS
- + " DESC, "
- + Programs.COLUMN_END_TIME_UTC_MILLIS
- + " ASC, "
- + Programs._ID
- + " DESC";
private static final int MSG_UPDATE_CURRENT_PROGRAMS = 1000;
private static final int MSG_UPDATE_ONE_CURRENT_PROGRAM = 1001;
private static final int MSG_UPDATE_PREFETCH_PROGRAM = 1002;
- private static final int MSG_UPDATE_CONTENT_RATINGS = 1003;
private final Context mContext;
private final Clock mClock;
@@ -118,7 +98,6 @@ public class ProgramDataManager implements MemoryManageable {
private final BackendKnobsFlags mBackendKnobsFlags;
private final PerformanceMonitor mPerformanceMonitor;
private final ChannelDataManager mChannelDataManager;
- private final TvInputManagerHelper mTvInputManagerHelper;
private boolean mStarted;
// Updated only on the main thread.
private volatile boolean mCurrentProgramsLoadFinished;
@@ -146,11 +125,6 @@ public class ProgramDataManager implements MemoryManageable {
private boolean mPauseProgramUpdate = false;
private final LruCache<Long, Program> mZeroLengthProgramCache = new LruCache<>(10);
- // Current tuned channel.
- private long mTunedChannelId;
- // Hours of data to be fetched, it is updated during horizontal scroll.
- // Note that it should never exceed programGuideMaxHours.
- private long mMaxFetchHoursMs = FETCH_HOURS_MS;
@MainThread
public ProgramDataManager(Context context) {
@@ -162,8 +136,7 @@ public class ProgramDataManager implements MemoryManageable {
Looper.myLooper(),
TvSingletons.getSingletons(context).getBackendKnobs(),
TvSingletons.getSingletons(context).getPerformanceMonitor(),
- TvSingletons.getSingletons(context).getChannelDataManager(),
- TvSingletons.getSingletons(context).getTvInputManagerHelper());
+ TvSingletons.getSingletons(context).getChannelDataManager());
}
@VisibleForTesting
@@ -175,8 +148,7 @@ public class ProgramDataManager implements MemoryManageable {
Looper looper,
BackendKnobsFlags backendKnobsFlags,
PerformanceMonitor performanceMonitor,
- ChannelDataManager channelDataManager,
- TvInputManagerHelper tvInputManagerHelper) {
+ ChannelDataManager channelDataManager) {
mContext = context;
mDbExecutor = executor;
mClock = time;
@@ -185,7 +157,6 @@ public class ProgramDataManager implements MemoryManageable {
mBackendKnobsFlags = backendKnobsFlags;
mPerformanceMonitor = performanceMonitor;
mChannelDataManager = channelDataManager;
- mTvInputManagerHelper = tvInputManagerHelper;
mProgramObserver =
new ContentObserver(mHandler) {
@Override
@@ -234,7 +205,6 @@ public class ProgramDataManager implements MemoryManageable {
// Should be called directly instead of posting MSG_UPDATE_CURRENT_PROGRAMS message
// to the handler. If not, another DB task can be executed before loading current programs.
handleUpdateCurrentPrograms();
- mHandler.sendEmptyMessage(MSG_UPDATE_CONTENT_RATINGS);
if (mPrefetchEnabled) {
mHandler.sendEmptyMessage(MSG_UPDATE_PREFETCH_PROGRAM);
}
@@ -289,67 +259,15 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- /**
- * Prefetch program data if needed.
- *
- * @param channelId ID of the channel to prefetch
- * @param selectedProgramIndex index of selected program.
- */
- public void prefetchChannel(long channelId, int selectedProgramIndex) {
- long startTimeMs =
- Utils.floorTime(
- mClock.currentTimeMillis() - PROGRAM_GUIDE_SNAP_TIME_MS,
- PROGRAM_GUIDE_SNAP_TIME_MS);
- long programGuideMaxHoursMs =
- TimeUnit.HOURS.toMillis(mBackendKnobsFlags.programGuideMaxHours());
- long endTimeMs = 0;
- if (mMaxFetchHoursMs < programGuideMaxHoursMs
- && isHorizontalLoadNeeded(startTimeMs, channelId, selectedProgramIndex)) {
- // Horizontal scrolling needs to load data of further days.
- mMaxFetchHoursMs = Math.min(programGuideMaxHoursMs, mMaxFetchHoursMs + FETCH_HOURS_MS);
- mCompleteInfoChannelIds.clear();
- }
- // Load max hours complete data for first channel.
- if (mCompleteInfoChannelIds.isEmpty()) {
- endTimeMs = startTimeMs + programGuideMaxHoursMs;
- } else if (!mCompleteInfoChannelIds.contains(channelId)) {
- endTimeMs = startTimeMs + mMaxFetchHoursMs;
- }
- if (endTimeMs > 0) {
- mCompleteInfoChannelIds.add(channelId);
- new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs).executeOnDbThread();
- }
- }
-
public void prefetchChannel(long channelId) {
- prefetchChannel(channelId, 0);
- }
-
- /**
- * Check if enough data is present for horizontal scroll, otherwise prefetch programs.
- *
- * <p>If end time of current program is past {@code BUFFER_HOURS_MS} less than the fetched time
- * we need to prefetch proceeding programs.
- *
- * @param startTimeMs Fetch start time, it is used to get fetch end time.
- * @param channelId
- * @param selectedProgramIndex
- * @return {@code true} If data load is needed, else {@code false}.
- */
- private boolean isHorizontalLoadNeeded(
- long startTimeMs, long channelId, int selectedProgramIndex) {
- if (mChannelIdProgramCache.containsKey(channelId)) {
- ArrayList<Program> programs = mChannelIdProgramCache.get(channelId);
- long marginEndTime = startTimeMs + mMaxFetchHoursMs - BUFFER_HOURS_MS;
- return programs.size() > selectedProgramIndex &&
- programs.get(selectedProgramIndex).getEndTimeUtcMillis() > marginEndTime;
+ if (mCompleteInfoChannelIds.add(channelId)) {
+ long startTimeMs =
+ Utils.floorTime(
+ mClock.currentTimeMillis() - PROGRAM_GUIDE_SNAP_TIME_MS,
+ PROGRAM_GUIDE_SNAP_TIME_MS);
+ long endTimeMs = startTimeMs + TimeUnit.HOURS.toMillis(getFetchDuration());
+ new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs).executeOnDbThread();
}
- return false;
- }
-
- public void onChannelTuned(long channelId) {
- mTunedChannelId = channelId;
- prefetchChannel(channelId);
}
/** A Callback interface to receive notification on program data retrieval from DB. */
@@ -362,10 +280,12 @@ public class ProgramDataManager implements MemoryManageable {
void onProgramUpdated();
/**
- * Called when we update program data during scrolling. Data is loaded from DB on request
- * basis. It loads data based on horizontal scrolling as well.
+ * Called when we update complete program data of specific channel during scrolling. Data is
+ * loaded from DB on request basis.
+ *
+ * @param channelId
*/
- void onChannelUpdated();
+ void onSingleChannelUpdated(long channelId);
}
/** Adds the {@link Callback}. */
@@ -392,7 +312,7 @@ public class ProgramDataManager implements MemoryManageable {
} else {
mPrefetchEnabled = false;
cancelPrefetchTask();
- clearChannelInfoMap();
+ mChannelIdProgramCache.clear();
mHandler.removeMessages(MSG_UPDATE_PREFETCH_PROGRAM);
}
}
@@ -619,7 +539,10 @@ public class ProgramDataManager implements MemoryManageable {
}
programMap.clear();
- String[] projection = ProgramImpl.PARTIAL_PROJECTION;
+ String[] projection =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.PARTIAL_PROJECTION
+ : Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(mContext, Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
projection =
@@ -639,7 +562,10 @@ public class ProgramDataManager implements MemoryManageable {
}
return null;
}
- Program program = ProgramImpl.fromCursorPartialProjection(c);
+ Program program =
+ mBackendKnobsFlags.enablePartialProgramFetch()
+ ? Program.fromCursorPartialProjection(c)
+ : Program.fromCursor(c);
if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
@@ -649,14 +575,15 @@ public class ProgramDataManager implements MemoryManageable {
ArrayList<Program> programs = programMap.get(program.getChannelId());
if (programs == null) {
programs = new ArrayList<>();
- // To skip already loaded complete data.
- Program currentProgramInfo =
- mChannelIdCurrentProgramMap.get(program.getChannelId());
- if (currentProgramInfo != null
- && Program.isDuplicate(program, currentProgramInfo)) {
- program = currentProgramInfo;
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ // To skip already loaded complete data.
+ Program currentProgramInfo =
+ mChannelIdCurrentProgramMap.get(program.getChannelId());
+ if (currentProgramInfo != null
+ && Program.isDuplicate(program, currentProgramInfo)) {
+ program = currentProgramInfo;
+ }
}
-
programMap.put(program.getChannelId(), programs);
}
programs.add(program);
@@ -701,12 +628,15 @@ public class ProgramDataManager implements MemoryManageable {
mLastPrefetchTaskRunMs + PROGRAM_GUIDE_SNAP_TIME_MS,
PROGRAM_GUIDE_SNAP_TIME_MS)
- currentTime;
+ // Issue second pre-fetch immediately after the first partial update
+ if (mChannelIdProgramCache.isEmpty()) {
+ nextMessageDelayedTime = 0;
+ }
mChannelIdProgramCache = programs;
- // Since cache has partial data we need to reset the map of complete data.
- clearChannelInfoMap();
- // Get complete projection of tuned channel.
- prefetchChannel(mTunedChannelId);
-
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ // Since cache has partial data we need to reset the map of complete data.
+ mCompleteInfoChannelIds.clear();
+ }
notifyProgramUpdated();
if (mFromEmptyCacheTimeEvent != null) {
mPerformanceMonitor.stopTimer(
@@ -724,11 +654,6 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- private void clearChannelInfoMap() {
- mCompleteInfoChannelIds.clear();
- mMaxFetchHoursMs = FETCH_HOURS_MS;
- }
-
private long getFetchDuration() {
if (mChannelIdProgramCache.isEmpty()) {
return Math.max(1L, mBackendKnobsFlags.programGuideInitialFetchHours());
@@ -760,7 +685,7 @@ public class ProgramDataManager implements MemoryManageable {
mDbExecutor,
mContext,
TvContract.buildProgramsUriForChannel(channelId, startTimeMs, endTimeMs),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
SORT_BY_TIME);
@@ -771,7 +696,7 @@ public class ProgramDataManager implements MemoryManageable {
protected ArrayList<Program> onQuery(Cursor c) {
ArrayList<Program> programMap = new ArrayList<>();
while (c.moveToNext()) {
- Program program = ProgramImpl.fromCursor(c);
+ Program program = Program.fromCursor(c);
programMap.add(program);
}
return programMap;
@@ -780,7 +705,7 @@ public class ProgramDataManager implements MemoryManageable {
@Override
protected void onPostExecute(ArrayList<Program> programs) {
mChannelIdProgramCache.put(mChannelId, programs);
- notifyChannelUpdated();
+ notifySingleChannelUpdated(mChannelId);
}
}
@@ -790,9 +715,9 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- private void notifyChannelUpdated() {
+ private void notifySingleChannelUpdated(long channelId) {
for (Callback callback : mCallbacks) {
- callback.onChannelUpdated();
+ callback.onSingleChannelUpdated(channelId);
}
}
@@ -806,10 +731,10 @@ public class ProgramDataManager implements MemoryManageable {
.appendQueryParameter(PARAM_START_TIME, String.valueOf(time))
.appendQueryParameter(PARAM_END_TIME, String.valueOf(time))
.build(),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
- SORT_BY_CHANNEL_ID);
+ SORT_BY_TIME);
}
@Override
@@ -822,21 +747,17 @@ public class ProgramDataManager implements MemoryManageable {
if (isCancelled()) {
return programs;
}
- Program program = ProgramImpl.fromCursor(c);
- // Only one program is expected per channel for this query
- // However, skip overlapping programs from same channel
- if (Program.sameChannel(program, lastReadProgram)
- && Program.isOverlapping(program, lastReadProgram)) {
+ Program program = Program.fromCursor(c);
+ if (Program.isDuplicate(program, lastReadProgram)) {
duplicateCount++;
continue;
} else {
lastReadProgram = program;
}
-
programs.add(program);
}
if (duplicateCount > 0) {
- Log.w(TAG, "Found " + duplicateCount + " overlapping programs");
+ Log.w(TAG, "Found " + duplicateCount + " duplicate programs");
}
}
return programs;
@@ -856,7 +777,9 @@ public class ProgramDataManager implements MemoryManageable {
for (Long channelId : removedChannelIds) {
if (mPrefetchEnabled) {
mChannelIdProgramCache.remove(channelId);
- mCompleteInfoChannelIds.remove(channelId);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mCompleteInfoChannelIds.remove(channelId);
+ }
}
mChannelIdCurrentProgramMap.remove(channelId);
notifyCurrentProgramUpdate(channelId, null);
@@ -874,7 +797,7 @@ public class ProgramDataManager implements MemoryManageable {
mDbExecutor,
mContext,
TvContract.buildProgramsUriForChannel(channelId, time, time),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
SORT_BY_TIME);
@@ -885,7 +808,7 @@ public class ProgramDataManager implements MemoryManageable {
public Program onQuery(Cursor c) {
Program program = null;
if (c != null && c.moveToNext()) {
- program = ProgramImpl.fromCursor(c);
+ program = Program.fromCursor(c);
}
return program;
}
@@ -946,9 +869,6 @@ public class ProgramDataManager implements MemoryManageable {
}
break;
}
- case MSG_UPDATE_CONTENT_RATINGS:
- mTvInputManagerHelper.getContentRatingsManager().update();
- break;
default:
// Do nothing
}
@@ -1012,7 +932,7 @@ public class ProgramDataManager implements MemoryManageable {
// Create dummy program which indicates data isn't loaded yet so DB query is required.
private Program createDummyProgram(long startTimeMs, long endTimeMs) {
- return new ProgramImpl.Builder()
+ return new Program.Builder()
.setChannelId(Channel.INVALID_ID)
.setStartTimeUtcMillis(startTimeMs)
.setEndTimeUtcMillis(endTimeMs)
diff --git a/src/com/android/tv/data/api/BaseProgram.java b/src/com/android/tv/data/api/BaseProgram.java
deleted file mode 100644
index 8acaf79e..00000000
--- a/src/com/android/tv/data/api/BaseProgram.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.android.tv.data.api;
-
-import android.content.Context;
-import android.media.tv.TvContentRating;
-import android.support.annotation.Nullable;
-import com.google.common.collect.ImmutableList;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * Base class for {@link com.android.tv.data.Program} and {@link
- * com.android.tv.dvr.data.RecordedProgram}.
- */
-public interface BaseProgram {
-
- /**
- * Comparator used to compare {@link BaseProgram} according to its season and episodes number.
- * If a program's season or episode number is null, it will be consider "smaller" than programs
- * with season or episode numbers.
- */
- Comparator<BaseProgram> EPISODE_COMPARATOR = new EpisodeComparator(false);
- /**
- * Comparator used to compare {@link BaseProgram} according to its season and episodes number
- * with season numbers in a reversed order. If a program's season or episode number is null, it
- * will be consider "smaller" than programs with season or episode numbers.
- */
- Comparator<BaseProgram> SEASON_REVERSED_EPISODE_COMPARATOR = new EpisodeComparator(true);
-
- String COLUMN_SERIES_ID = "series_id";
- String COLUMN_STATE = "state";
-
- /** Compares two strings represent season numbers or episode numbers of programs. */
- static int numberCompare(String s1, String s2) {
- if (Objects.equals(s1, s2)) {
- return 0;
- } else if (s1 == null) {
- return -1;
- } else if (s2 == null) {
- return 1;
- } else if (s1.equals(s2)) {
- return 0;
- }
- try {
- return Integer.compare(Integer.parseInt(s1), Integer.parseInt(s2));
- } catch (NumberFormatException e) {
- return s1.compareTo(s2);
- }
- }
-
- /** Generates the series ID for the other inputs than the tuner TV input. */
- static String generateSeriesId(String packageName, String title) {
- return packageName + "/" + title;
- }
-
- /** Returns ID of the program. */
- long getId();
-
- /** Returns the title of the program. */
- String getTitle();
-
- /** Returns the episode title. */
- String getEpisodeTitle();
-
- /** Returns the displayed title of the program episode. */
- @Nullable
- String getEpisodeDisplayTitle(Context context);
-
- /**
- * Returns the content description of the program episode, suitable for being spoken by an
- * accessibility service.
- */
- String getEpisodeContentDescription(Context context);
-
- /** Returns the description of the program. */
- String getDescription();
-
- /** Returns the long description of the program. */
- String getLongDescription();
-
- /** Returns the start time of the program in Milliseconds. */
- long getStartTimeUtcMillis();
-
- /** Returns the end time of the program in Milliseconds. */
- long getEndTimeUtcMillis();
-
- /** Returns the duration of the program in Milliseconds. */
- long getDurationMillis();
-
- /** Returns the series ID. */
- @Nullable
- String getSeriesId();
-
- /** Returns the season number. */
- String getSeasonNumber();
-
- /** Returns the episode number. */
- String getEpisodeNumber();
-
- /** Returns URI of the program's poster. */
- String getPosterArtUri();
-
- /** Returns URI of the program's thumbnail. */
- String getThumbnailUri();
-
- /** Returns the array of the ID's of the canonical genres. */
- int[] getCanonicalGenreIds();
-
- /** Returns the array of content ratings. */
- ImmutableList<TvContentRating> getContentRatings();
-
- /** Returns channel's ID of the program. */
- long getChannelId();
-
- /** Returns if the program is valid. */
- boolean isValid();
-
- /** Checks whether the program is episodic or not. */
- boolean isEpisodic();
-
- /** Generates the series ID for the other inputs than the tuner TV input. */
- class EpisodeComparator implements Comparator<BaseProgram> {
- private final boolean mReversedSeason;
-
- EpisodeComparator(boolean reversedSeason) {
- mReversedSeason = reversedSeason;
- }
-
- @Override
- public int compare(BaseProgram lhs, BaseProgram rhs) {
- if (lhs == rhs) {
- return 0;
- }
- int seasonNumberCompare = numberCompare(lhs.getSeasonNumber(), rhs.getSeasonNumber());
- if (seasonNumberCompare != 0) {
- return mReversedSeason ? -seasonNumberCompare : seasonNumberCompare;
- } else {
- return numberCompare(lhs.getEpisodeNumber(), rhs.getEpisodeNumber());
- }
- }
- }
-}
diff --git a/src/com/android/tv/data/api/Program.java b/src/com/android/tv/data/api/Program.java
deleted file mode 100644
index f2221f6e..00000000
--- a/src/com/android/tv/data/api/Program.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.android.tv.data.api;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-
-import com.android.tv.util.images.ImageLoader;
-
-import java.io.Serializable;
-import java.util.List;
-
-/** A convenience interface to create and insert program information entries into the database. */
-public interface Program extends BaseProgram, Comparable<Program> {
-
- /** Returns {@code true} if the program is valid and {@code false} otherwise. */
- static boolean isProgramValid(Program program) {
- return program != null && program.isValid();
- }
-
- static boolean isDuplicate(Program p1, Program p2) {
- if (p1 == null || p2 == null) {
- return false;
- }
- return p1.getChannelId() == p2.getChannelId()
- && p1.getStartTimeUtcMillis() == p2.getStartTimeUtcMillis()
- && p1.getEndTimeUtcMillis() == p2.getEndTimeUtcMillis();
- }
-
- /** True if the start or end times overlap. */
- static boolean isOverlapping(@Nullable Program p1, @Nullable Program p2) {
- return p1 != null
- && p2 != null
- && p1.getStartTimeUtcMillis() < p2.getEndTimeUtcMillis()
- && p1.getEndTimeUtcMillis() > p2.getStartTimeUtcMillis();
- }
-
- /** True if the channels IDs are the same. */
- static boolean sameChannel(@Nullable Program p1, @Nullable Program p2) {
- return p1 != null && p2 != null && p1.getChannelId() == p2.getChannelId();
- }
-
- /** Returns the package name of this program. */
- String getPackageName();
-
- /** Returns the season title */
- String getSeasonTitle();
-
- /** Gets the localized duration of the program */
- String getDurationString(Context context);
-
- int getVideoWidth();
-
- int getVideoHeight();
-
- /** Returns the list of Critic Scores for this program */
- @Nullable
- List<CriticScore> getCriticScores();
-
- /** Returns {@code true} if the recording of this program is prohibited. */
- boolean isRecordingProhibited();
-
- /** Returns array of canonical genres for this program. This is expected to be called rarely. */
- @Nullable
- String[] getCanonicalGenres();
-
- /** Returns if this program has the genre. */
- boolean hasGenre(int genreId);
-
- /** Prefetch the program poster art. */
- void prefetchPosterArt(Context context, int posterArtWidth, int posterArtHeight);
-
- /**
- * Loads the program poster art and returns it via {@code callback}.
- *
- * <p>Note that it may directly call {@code callback} if the program poster art already is
- * loaded.
- *
- * @return {@code true} if the load is complete and the callback is executed.
- */
- @UiThread
- boolean loadPosterArt(
- Context context,
- int posterArtWidth,
- int posterArtHeight,
- ImageLoader.ImageLoaderCallback<?> callback);
-
- /** Returns a {@link Parcelable} representation of this instance. */
- Parcelable toParcelable();
-
- /** Holds one type of critic score and its source. */
- final class CriticScore implements Serializable, Parcelable {
- /** The source of the rating. */
- public final String source;
- /** The score. */
- public final String score;
- /** The url of the logo image */
- public final String logoUrl;
-
- public static final Creator<CriticScore> CREATOR =
- new Creator<CriticScore>() {
- @Override
- public CriticScore createFromParcel(Parcel in) {
- String source = in.readString();
- String score = in.readString();
- String logoUri = in.readString();
- return new CriticScore(source, score, logoUri);
- }
-
- @Override
- public CriticScore[] newArray(int size) {
- return new CriticScore[size];
- }
- };
-
- /**
- * Constructor for this class.
- *
- * @param source the source of the rating
- * @param score the score
- */
- public CriticScore(String source, String score, String logoUrl) {
- this.source = source;
- this.score = score;
- this.logoUrl = logoUrl;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int i) {
- out.writeString(source);
- out.writeString(score);
- out.writeString(logoUrl);
- }
- }
-}
diff --git a/src/com/android/tv/data/epg/EpgFetchHelper.java b/src/com/android/tv/data/epg/EpgFetchHelper.java
index 4e889115..3843ca99 100644
--- a/src/com/android/tv/data/epg/EpgFetchHelper.java
+++ b/src/com/android/tv/data/epg/EpgFetchHelper.java
@@ -28,15 +28,12 @@ import android.preference.PreferenceManager;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.common.CommonConstants;
import com.android.tv.common.util.Clock;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.features.TvFeatures;
import com.android.tv.util.TvProviderUtils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -109,7 +106,7 @@ class EpgFetchHelper {
ops.add(
ContentProviderOperation.newUpdate(
TvContract.buildProgramUri(oldProgram.getId()))
- .withValues(ProgramImpl.toContentValues(newProgram, context))
+ .withValues(Program.toContentValues(newProgram, context))
.build());
oldProgramsIndex++;
newProgramsIndex++;
@@ -135,7 +132,7 @@ class EpgFetchHelper {
if (addNewProgram) {
ops.add(
ContentProviderOperation.newInsert(Programs.CONTENT_URI)
- .withValues(ProgramImpl.toContentValues(newProgram, context))
+ .withValues(Program.toContentValues(newProgram, context))
.build());
}
// Throttle the batch operation not to cause TransactionTooLargeException.
@@ -202,7 +199,7 @@ class EpgFetchHelper {
@WorkerThread
private static List<Program> queryPrograms(
Context context, long channelId, long startTimeMs, long endTimeMs) {
- String[] projection = ProgramImpl.PROJECTION;
+ String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
projection =
TvProviderUtils.addExtraColumnsToProjection(
@@ -222,7 +219,7 @@ class EpgFetchHelper {
}
ArrayList<Program> programs = new ArrayList<>();
while (c.moveToNext()) {
- programs.add(ProgramImpl.fromCursor(c));
+ programs.add(Program.fromCursor(c));
}
return programs;
}
diff --git a/src/com/android/tv/data/epg/EpgFetchService.java b/src/com/android/tv/data/epg/EpgFetchService.java
index cfa79cb0..aa4f3588 100644
--- a/src/com/android/tv/data/epg/EpgFetchService.java
+++ b/src/com/android/tv/data/epg/EpgFetchService.java
@@ -18,24 +18,22 @@ package com.android.tv.data.epg;
import android.app.job.JobParameters;
import android.app.job.JobService;
-
import com.android.tv.Starter;
+import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import dagger.android.AndroidInjection;
-
-import javax.inject.Inject;
-
/** JobService to Fetch EPG data. */
public class EpgFetchService extends JobService {
- @Inject EpgFetcher mEpgFetcher;
- @Inject ChannelDataManager mChannelDataManager;
+ private EpgFetcher mEpgFetcher;
+ private ChannelDataManager mChannelDataManager;
@Override
public void onCreate() {
- AndroidInjection.inject(this);
super.onCreate();
Starter.start(this);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(getApplicationContext());
+ mEpgFetcher = tvSingletons.getEpgFetcher();
+ mChannelDataManager = tvSingletons.getChannelDataManager();
}
@Override
diff --git a/src/com/android/tv/data/epg/EpgFetcherImpl.java b/src/com/android/tv/data/epg/EpgFetcherImpl.java
index 27d7f8d5..b191421f 100644
--- a/src/com/android/tv/data/epg/EpgFetcherImpl.java
+++ b/src/com/android/tv/data/epg/EpgFetcherImpl.java
@@ -38,12 +38,10 @@ import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.buildtype.HasBuildType;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.util.Clock;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.LocationUtils;
@@ -54,22 +52,17 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
import com.android.tv.data.ChannelLogoFetcher;
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.epg.EpgReader.EpgChannel;
import com.android.tv.features.TvFeatures;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.Utils;
-
import com.google.android.tv.partner.support.EpgInput;
import com.google.android.tv.partner.support.EpgInputs;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
import com.android.tv.common.flags.BackendKnobsFlags;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -80,8 +73,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
/**
* The service class to fetch EPG routinely or on-demand during channel scanning
*
@@ -118,6 +109,7 @@ public class EpgFetcherImpl implements EpgFetcher {
private static final int MSG_FINISH_FETCH_DURING_SCAN = 3;
private static final int MSG_RETRY_PREPARE_FETCH_DURING_SCAN = 4;
+ private static final int QUERY_CHANNEL_COUNT = 50;
private static final int MINIMUM_CHANNELS_TO_DECIDE_LINEUP = 3;
private final Context mContext;
@@ -138,9 +130,31 @@ public class EpgFetcherImpl implements EpgFetcher {
private Clock mClock;
- @Inject
- public EpgFetcherImpl(
- @ApplicationContext Context context,
+ public static EpgFetcher create(Context context) {
+ context = context.getApplicationContext();
+ TvSingletons tvSingletons = TvSingletons.getSingletons(context);
+ ChannelDataManager channelDataManager = tvSingletons.getChannelDataManager();
+ PerformanceMonitor performanceMonitor = tvSingletons.getPerformanceMonitor();
+ EpgReader epgReader = tvSingletons.providesEpgReader().get();
+ Clock clock = tvSingletons.getClock();
+ EpgInputWhiteList epgInputWhiteList =
+ new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
+ BackendKnobsFlags backendKnobsFlags = tvSingletons.getBackendKnobs();
+ HasBuildType.BuildType buildType = tvSingletons.getBuildType();
+ return new EpgFetcherImpl(
+ context,
+ epgInputWhiteList,
+ channelDataManager,
+ epgReader,
+ performanceMonitor,
+ clock,
+ backendKnobsFlags,
+ buildType);
+ }
+
+ @VisibleForTesting
+ EpgFetcherImpl(
+ Context context,
EpgInputWhiteList epgInputWhiteList,
ChannelDataManager channelDataManager,
EpgReader epgReader,
@@ -455,16 +469,23 @@ public class EpgFetcherImpl implements EpgFetcher {
if (epgChannels.size() == 0) {
return;
}
- int batchSize = (int) Math.max(1, mBackendKnobsFlags.epgFetcherChannelsPerProgramFetch());
- for (Iterable<EpgChannel> batch : Iterables.partition(epgChannels, batchSize)) {
- batchUpdateEpg(mEpgReader.getPrograms(ImmutableSet.copyOf(batch), durationSec));
+ Set<EpgReader.EpgChannel> batch = new HashSet<>(QUERY_CHANNEL_COUNT);
+ for (EpgReader.EpgChannel epgChannel : epgChannels) {
+ batch.add(epgChannel);
+ if (batch.size() >= QUERY_CHANNEL_COUNT) {
+ batchUpdateEpg(mEpgReader.getPrograms(batch, durationSec));
+ batch.clear();
+ }
+ }
+ if (!batch.isEmpty()) {
+ batchUpdateEpg(mEpgReader.getPrograms(batch, durationSec));
}
}
@WorkerThread
private void batchUpdateEpg(Map<EpgReader.EpgChannel, Collection<Program>> allPrograms) {
for (Map.Entry<EpgReader.EpgChannel, Collection<Program>> entry : allPrograms.entrySet()) {
- List<Program> programs = new ArrayList<>(entry.getValue());
+ List<Program> programs = new ArrayList(entry.getValue());
if (programs == null) {
continue;
}
@@ -583,7 +604,6 @@ public class EpgFetcherImpl implements EpgFetcher {
? ((Integer) REASON_CLOUD_EPG_FAILURE)
: anyCloudEpgSuccess ? null : builtInResult;
}
- clearUnusedLineups(null);
return builtInResult;
} finally {
TrafficStats.setThreadStatsTag(oldTag);
diff --git a/src/com/android/tv/data/epg/EpgInputWhiteList.java b/src/com/android/tv/data/epg/EpgInputWhiteList.java
index 4a5f98bb..24b4fe3d 100644
--- a/src/com/android/tv/data/epg/EpgInputWhiteList.java
+++ b/src/com/android/tv/data/epg/EpgInputWhiteList.java
@@ -21,14 +21,13 @@ import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import com.android.tv.common.BuildConfig;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.flags.CloudEpgFlags;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import javax.inject.Inject;
/** Checks if a package or a input is white listed. */
public final class EpgInputWhiteList {
@@ -37,7 +36,6 @@ public final class EpgInputWhiteList {
private static final String QA_DEV_INPUTS =
"com.example.partnersupportsampletvinput/.SampleTvInputService,"
+ "com.android.tv.tuner.sample.dvb/.tvinput.SampleDvbTunerTvInputService";
- private final LegacyFlags mLegacyFlags;
/** Returns the package portion of a inputId */
@Nullable
@@ -45,12 +43,10 @@ public final class EpgInputWhiteList {
return inputId == null ? null : inputId.substring(0, inputId.indexOf("/"));
}
- private final CloudEpgFlags mCloudEpgFlags;
+ private final CloudEpgFlags cloudEpgFlags;
- @Inject
- public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags, LegacyFlags legacyFlags) {
- mCloudEpgFlags = cloudEpgFlags;
- mLegacyFlags = legacyFlags;
+ public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags) {
+ this.cloudEpgFlags = cloudEpgFlags;
}
public boolean isInputWhiteListed(String inputId) {
@@ -75,8 +71,8 @@ public final class EpgInputWhiteList {
}
private Set<String> getWhiteListedInputs() {
- Set<String> result = toInputSet(mCloudEpgFlags.thirdPartyEpgInputsCsv());
- if (BuildConfig.ENG || mLegacyFlags.enableQaFeatures()) {
+ Set<String> result = toInputSet(cloudEpgFlags.thirdPartyEpgInputsCsv());
+ if (BuildConfig.ENG || Experiments.ENABLE_QA_FEATURES.get()) {
HashSet<String> moreInputs = new HashSet<>(toInputSet(QA_DEV_INPUTS));
if (result.isEmpty()) {
result = moreInputs;
diff --git a/src/com/android/tv/data/epg/EpgReader.java b/src/com/android/tv/data/epg/EpgReader.java
index 8c0e3f09..c9fcd979 100644
--- a/src/com/android/tv/data/epg/EpgReader.java
+++ b/src/com/android/tv/data/epg/EpgReader.java
@@ -19,14 +19,11 @@ package com.android.tv.data.epg;
import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
-
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.SeriesInfo;
-
import com.google.auto.value.AutoValue;
-
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -39,8 +36,8 @@ public interface EpgReader {
/** Value class that holds a EpgChannelId and its corresponding {@link Channel} */
@AutoValue
abstract class EpgChannel {
- public static EpgChannel createEpgChannel(
- Channel channel, String epgChannelId, boolean dbUpdateNeeded) {
+ public static EpgChannel createEpgChannel(Channel channel, String epgChannelId,
+ boolean dbUpdateNeeded) {
return new AutoValue_EpgReader_EpgChannel(channel, epgChannelId, dbUpdateNeeded);
}
diff --git a/src/com/android/tv/data/epg/StubEpgReader.java b/src/com/android/tv/data/epg/StubEpgReader.java
index 19bf786e..3b001481 100644
--- a/src/com/android/tv/data/epg/StubEpgReader.java
+++ b/src/com/android/tv/data/epg/StubEpgReader.java
@@ -16,25 +16,21 @@
package com.android.tv.data.epg;
+import android.content.Context;
import android.support.annotation.NonNull;
-
import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.SeriesInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.inject.Inject;
-
/** A stub class to read EPG. */
public class StubEpgReader implements EpgReader {
- @Inject
- public StubEpgReader() {}
+ public StubEpgReader(@SuppressWarnings("unused") Context context) {}
@Override
public boolean isAvailable() {
diff --git a/src/com/android/tv/dialog/PinDialogFragment.java b/src/com/android/tv/dialog/PinDialogFragment.java
index c7145583..87308093 100644
--- a/src/com/android/tv/dialog/PinDialogFragment.java
+++ b/src/com/android/tv/dialog/PinDialogFragment.java
@@ -18,7 +18,6 @@ package com.android.tv.dialog;
import android.app.ActivityManager;
import android.app.Dialog;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.media.tv.TvContentRating;
@@ -34,13 +33,10 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
import com.android.tv.R;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dialog.picker.TvPinPicker;
-import com.android.tv.util.TvInputManagerHelper;
+import com.android.tv.dialog.picker.PinPicker;
import com.android.tv.util.TvSettings;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.UiFlags;
-import javax.inject.Inject;
public class PinDialogFragment extends SafeDismissDialogFragment {
private static final String TAG = "PinDialogFragment";
@@ -84,8 +80,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private TextView mWrongPinView;
private View mEnterPinView;
private TextView mTitleView;
-
- private TvPinPicker mTvPinPicker;
+ private PinPicker mPicker;
private SharedPreferences mSharedPreferences;
private String mPrevPin;
private String mPin;
@@ -93,8 +88,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private int mWrongPinCount;
private long mDisablePinUntil;
private final Handler mHandler = new Handler();
- @Inject TvInputManagerHelper mTvInputManagerHelper;
- @Inject UiFlags mUiFlags;
public static PinDialogFragment create(int type) {
return create(type, null);
@@ -110,12 +103,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
@Override
- public void onAttach(Context context) {
- AndroidInjection.inject(this);
- super.onAttach(context);
- }
-
- @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRequestType = getArguments().getInt(ARGS_TYPE, PIN_DIALOG_TYPE_ENTER_PIN);
@@ -167,8 +154,8 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mWrongPinView = (TextView) v.findViewById(R.id.wrong_pin);
mEnterPinView = v.findViewById(R.id.enter_pin);
mTitleView = (TextView) mEnterPinView.findViewById(R.id.title);
- mTvPinPicker = v.findViewById(R.id.tv_pin_picker);
- mTvPinPicker.setOnClickListener(
+ mPicker = v.findViewById(R.id.pin_picker);
+ mPicker.setOnClickListener(
view -> {
String pin = getPinInput();
if (!TextUtils.isEmpty(pin)) {
@@ -196,7 +183,8 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mTitleView.setText(
getString(
R.string.pin_enter_unlock_dvr,
- mTvInputManagerHelper
+ TvSingletons.getSingletons(getContext())
+ .getTvInputManagerHelper()
.getContentRatingsManager()
.getDisplayNameForRating(tvContentRating)));
}
@@ -216,8 +204,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
if (mType != PIN_DIALOG_TYPE_NEW_PIN) {
updateWrongPin();
}
-
- mTvPinPicker.requestFocus();
+ mPicker.requestFocus();
return v;
}
@@ -351,11 +338,11 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private String getPinInput() {
- return mTvPinPicker.getPin();
+ return mPicker.getPinInput();
}
private void resetPinInput() {
- mTvPinPicker.resetPin();
+ mPicker.resetPinInput();
}
/**
diff --git a/src/com/android/tv/dialog/picker/PinPicker.java b/src/com/android/tv/dialog/picker/PinPicker.java
new file mode 100644
index 00000000..f501dfd1
--- /dev/null
+++ b/src/com/android/tv/dialog/picker/PinPicker.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tv.dialog.picker;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v17.leanback.widget.picker.Picker;
+import android.support.v17.leanback.widget.picker.PickerColumn;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import java.util.ArrayList;
+import java.util.List;
+
+/** 4 digit picker */
+public final class PinPicker extends Picker {
+ // TODO(b/116144491): use leanback pin picker.
+
+ private final List<PickerColumn> mPickers = new ArrayList<>();
+ private OnClickListener mOnClickListener;
+
+ // the version of picker I link to does not have this constructor
+ public PinPicker(Context context, AttributeSet attributeSet) {
+ this(context, attributeSet, 0);
+ }
+
+ public PinPicker(Context context, AttributeSet attributeSet, int defStyleAttr) {
+ super(context, attributeSet, defStyleAttr);
+
+ for (int i = 0; i < 4; i++) {
+ PickerColumn pickerColumn = new PickerColumn();
+ pickerColumn.setMinValue(0);
+ pickerColumn.setMaxValue(9);
+ pickerColumn.setLabelFormat("%d");
+ mPickers.add(pickerColumn);
+ }
+ setSeparator(" ");
+ setColumns(mPickers);
+ setActivated(true);
+ setFocusable(true);
+ super.setOnClickListener(this::onClick);
+ }
+
+ public String getPinInput() {
+ String result = "";
+ try {
+ for (PickerColumn column : mPickers) {
+
+ result += column.getCurrentValue();
+ }
+ } catch (IllegalStateException e) {
+ result = "";
+ }
+ return result;
+ }
+
+ @Override
+ public void setOnClickListener(@Nullable OnClickListener l) {
+ mOnClickListener = l;
+ }
+
+ private void onClick(View v) {
+ int selectedColumn = getSelectedColumn();
+ int nextColumn = selectedColumn + 1;
+ // Only call the click listener if we are on the last column
+ // Otherwise move to the next column
+ if (nextColumn == getColumnsCount()) {
+ if (mOnClickListener != null) {
+ mOnClickListener.onClick(v);
+ }
+ } else {
+ setSelectedColumn(nextColumn);
+ onRequestFocusInDescendants(ViewGroup.FOCUS_FORWARD, null);
+ }
+ }
+
+ public void resetPinInput() {
+ setActivated(false);
+ for (int i = 0; i < 4; i++) {
+ setColumnValue(i, 0, true);
+ }
+ setSelectedColumn(0);
+ setActivated(true); // This resets the focus
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ int keyCode = event.getKeyCode();
+ int digit = digitFromKeyCode(keyCode);
+ if (digit != -1) {
+ int selectedColumn = getSelectedColumn();
+ setColumnValue(selectedColumn, digit, false);
+ int nextColumn = selectedColumn + 1;
+ if (nextColumn < getColumnsCount()) {
+ setSelectedColumn(nextColumn);
+ onRequestFocusInDescendants(ViewGroup.FOCUS_FORWARD, null);
+ } else {
+ callOnClick();
+ }
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @VisibleForTesting
+ static int digitFromKeyCode(int keyCode) {
+ if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
+ return keyCode - KeyEvent.KEYCODE_0;
+ } else if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyCode <= KeyEvent.KEYCODE_NUMPAD_9) {
+ return keyCode - KeyEvent.KEYCODE_NUMPAD_0;
+ }
+ return -1;
+ }
+}
diff --git a/src/com/android/tv/dialog/picker/TvPinPicker.java b/src/com/android/tv/dialog/picker/TvPinPicker.java
deleted file mode 100644
index 064b7f02..00000000
--- a/src/com/android/tv/dialog/picker/TvPinPicker.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tv.dialog.picker;
-
-import static android.content.Context.ACCESSIBILITY_SERVICE;
-
-import android.content.Context;
-import androidx.leanback.widget.picker.PinPicker;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityManager;
-
-/** 4 digit picker */
-public final class TvPinPicker extends PinPicker {
-
- private boolean mSkipPerformClick = true;
- private boolean mIsAccessibilityEnabled = false;
-
- public TvPinPicker(Context context, AttributeSet attributeSet) {
- this(context, attributeSet, 0);
- }
-
- public TvPinPicker(Context context, AttributeSet attributeSet, int defStyleAttr) {
- super(context, attributeSet, defStyleAttr);
- setActivated(true);
- AccessibilityManager am =
- (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
- mIsAccessibilityEnabled = am.isEnabled();
- }
-
- @Override
- public boolean performClick() {
- // (b/120096347) Skip first click when talkback is enabled
- if (mSkipPerformClick && mIsAccessibilityEnabled) {
- mSkipPerformClick = false;
- /* Force focus to next value */
- setColumnValue(getSelectedColumn(), 1, true);
- return false;
- }
- return super.performClick();
- }
-}
diff --git a/src/com/android/tv/dvr/DvrDataManagerImpl.java b/src/com/android/tv/dvr/DvrDataManagerImpl.java
index 3e26a231..0053650b 100644
--- a/src/com/android/tv/dvr/DvrDataManagerImpl.java
+++ b/src/com/android/tv/dvr/DvrDataManagerImpl.java
@@ -37,10 +37,8 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.recording.RecordingStorageStatusManager.OnStorageMountChangedListener;
import com.android.tv.common.util.Clock;
@@ -50,7 +48,6 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.provider.DvrDatabaseHelper;
import com.android.tv.dvr.provider.DvrDbFuture.AddScheduleFuture;
import com.android.tv.dvr.provider.DvrDbFuture.AddSeriesRecordingFuture;
import com.android.tv.dvr.provider.DvrDbFuture.DeleteScheduleFuture;
@@ -63,14 +60,11 @@ import com.android.tv.dvr.provider.DvrDbSync;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.AsyncDbTask.AsyncRecordedProgramQueryTask;
-import com.android.tv.util.AsyncDbTask.DbExecutor;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvUriMatcher;
-
import com.google.common.base.Predicate;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -82,13 +76,9 @@ import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/** DVR Data manager to handle recordings and schedules. */
@MainThread
@TargetApi(Build.VERSION_CODES.N)
-@Singleton
public class DvrDataManagerImpl extends BaseDvrDataManager {
private static final String TAG = "DvrDataManagerImpl";
private static final boolean DEBUG = false;
@@ -108,7 +98,6 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
private final HashMap<Long, SeriesRecording> mSeriesRecordingsForRemovedInput = new HashMap<>();
private final Context mContext;
- private final DvrDatabaseHelper mDbHelper;
private Executor mDbExecutor;
private final ContentObserver mContentObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@@ -198,28 +187,20 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
return moved;
}
- @Inject
- public DvrDataManagerImpl(
- @ApplicationContext Context context,
- Clock clock,
- TvInputManagerHelper tvInputManagerHelper,
- @DbExecutor Executor dbExecutor,
- DvrDatabaseHelper dbHelper) {
+ public DvrDataManagerImpl(Context context, Clock clock) {
super(context, clock);
mContext = context;
TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- mInputManager = tvInputManagerHelper;
+ mInputManager = tvSingletons.getTvInputManagerHelper();
mStorageStatusManager = tvSingletons.getRecordingStorageStatusManager();
- mDbExecutor = dbExecutor;
- mDbHelper = dbHelper;
- start();
+ mDbExecutor = tvSingletons.getDbExecutor();
}
- private void start() {
+ public void start() {
mInputManager.addCallback(mInputCallback);
mStorageStatusManager.addListener(mStorageMountChangedListener);
DvrQuerySeriesRecordingFuture dvrQuerySeriesRecordingTask =
- new DvrQuerySeriesRecordingFuture(mDbHelper);
+ new DvrQuerySeriesRecordingFuture(mContext);
ListenableFuture<List<SeriesRecording>> dvrQuerySeriesRecordingFuture =
dvrQuerySeriesRecordingTask.executeOnDbThread(
new FutureCallback<List<SeriesRecording>>() {
@@ -232,8 +213,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (SoftPreconditions.checkState(
!seriesIds.contains(r.getSeriesId()),
TAG,
- "Skip loading series recording with duplicate series"
- + " ID: "
+ "Skip loading series recording with duplicate series ID: "
+ r)) {
seriesIds.add(r.getSeriesId());
if (isInputAvailable(r.getInputId())) {
@@ -257,7 +237,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
});
mPendingDvrFuture.add(dvrQuerySeriesRecordingFuture);
- DvrQueryScheduleFuture dvrQueryScheduleTask = new DvrQueryScheduleFuture(mDbHelper);
+ DvrQueryScheduleFuture dvrQueryScheduleTask = new DvrQueryScheduleFuture(mContext);
ListenableFuture<List<ScheduledRecording>> dvrQueryScheduleFuture =
dvrQueryScheduleTask.executeOnDbThread(
new FutureCallback<List<ScheduledRecording>>() {
@@ -661,7 +641,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifyScheduledRecordingAdded(schedules);
}
ListenableFuture addScheduleFuture =
- new AddScheduleFuture(mDbHelper)
+ new AddScheduleFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, schedules);
mNoStopFuture.add(addScheduleFuture);
removeDeletedSchedules(schedules);
@@ -683,7 +663,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingAdded(seriesRecordings);
}
ListenableFuture addSeriesRecordingFuture =
- new AddSeriesRecordingFuture(mDbHelper)
+ new AddSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(addSeriesRecordingFuture);
}
@@ -743,7 +723,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -751,7 +731,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesNotToDelete.isEmpty()) {
ListenableFuture updateScheduleFuture =
- new UpdateScheduleFuture(mDbHelper)
+ new UpdateScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesNotToDelete));
@@ -794,7 +774,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingRemoved(seriesRecordings);
}
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(deleteSeriesRecordingFuture);
removeDeletedSchedules(seriesRecordings);
@@ -849,7 +829,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (updateDb) {
ListenableFuture updateScheduleFuture =
- new UpdateScheduleFuture(mDbHelper)
+ new UpdateScheduleFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, scheduleArray);
mNoStopFuture.add(updateScheduleFuture);
}
@@ -876,7 +856,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
notifySeriesRecordingChanged(seriesRecordings);
}
ListenableFuture updateSeriesRecordingFuture =
- new UpdateSeriesRecordingFuture(mDbHelper)
+ new UpdateSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, seriesRecordings);
mNoStopFuture.add(updateSeriesRecordingFuture);
}
@@ -897,7 +877,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -922,7 +902,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
if (!schedulesToDelete.isEmpty()) {
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
@@ -970,7 +950,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
mSeriesRecordingsForRemovedInput.remove(r.getId());
}
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
SeriesRecording.toArray(removedSeriesRecordings));
@@ -1063,13 +1043,13 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
}
ListenableFuture deleteScheduleFuture =
- new DeleteScheduleFuture(mDbHelper)
+ new DeleteScheduleFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
ScheduledRecording.toArray(schedulesToDelete));
mNoStopFuture.add(deleteScheduleFuture);
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(
removeFromSetOnCompletion,
SeriesRecording.toArray(seriesRecordingsToDelete));
@@ -1105,7 +1085,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (!removedSeriesRecordings.isEmpty()) {
SeriesRecording[] removed = SeriesRecording.toArray(removedSeriesRecordings);
ListenableFuture deleteSeriesRecordingFuture =
- new DeleteSeriesRecordingFuture(mDbHelper)
+ new DeleteSeriesRecordingFuture(mContext)
.executeOnDbThread(removeFromSetOnCompletion, removed);
mNoStopFuture.add(deleteSeriesRecordingFuture);
if (mDvrLoadFinished) {
diff --git a/src/com/android/tv/dvr/DvrManager.java b/src/com/android/tv/dvr/DvrManager.java
index 12982c6c..cc9ad37a 100644
--- a/src/com/android/tv/dvr/DvrManager.java
+++ b/src/com/android/tv/dvr/DvrManager.java
@@ -37,13 +37,12 @@ import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
import com.android.tv.dvr.DvrScheduleManager.OnInitializeListener;
@@ -52,7 +51,6 @@ import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.Utils;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -189,7 +187,7 @@ public class DvrManager {
? mScheduleManager.suggestNewPriority()
: mScheduleManager.suggestHighestPriority(
seriesRecording.getInputId(),
- Range.create(
+ new Range(
program.getStartTimeUtcMillis(),
program.getEndTimeUtcMillis()),
seriesRecording.getPriority()));
diff --git a/src/com/android/tv/dvr/DvrScheduleManager.java b/src/com/android/tv/dvr/DvrScheduleManager.java
index 3afcc422..7202dce0 100644
--- a/src/com/android/tv/dvr/DvrScheduleManager.java
+++ b/src/com/android/tv/dvr/DvrScheduleManager.java
@@ -25,12 +25,11 @@ import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -38,7 +37,6 @@ import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.recorder.InputTaskScheduler;
import com.android.tv.util.CompositeComparator;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -78,7 +76,7 @@ public class DvrScheduleManager {
ScheduledRecording.ID_COMPARATOR);
private final Context mContext;
- private final DvrDataManager mDataManager;
+ private final DvrDataManagerImpl mDataManager;
private final ChannelDataManager mChannelDataManager;
private final Map<String, List<ScheduledRecording>> mInputScheduleMap = new HashMap<>();
@@ -97,7 +95,7 @@ public class DvrScheduleManager {
public DvrScheduleManager(Context context) {
mContext = context;
TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- mDataManager = tvSingletons.getDvrDataManager();
+ mDataManager = (DvrDataManagerImpl) tvSingletons.getDvrDataManager();
mChannelDataManager = tvSingletons.getChannelDataManager();
if (mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished()) {
buildData();
diff --git a/src/com/android/tv/dvr/DvrStorageStatusManager.java b/src/com/android/tv/dvr/DvrStorageStatusManager.java
index a0ae8939..dc347a9e 100644
--- a/src/com/android/tv/dvr/DvrStorageStatusManager.java
+++ b/src/com/android/tv/dvr/DvrStorageStatusManager.java
@@ -114,7 +114,7 @@ public class DvrStorageStatusManager extends RecordingStorageStatusManager {
return;
}
for (TvInputInfo info : tvInputInfoList) {
- if (CommonUtils.isBundledInput(info.getId()) && dvrManager != null) {
+ if (CommonUtils.isBundledInput(info.getId())) {
dvrManager.forgetStorage(info.getId());
}
}
diff --git a/src/com/android/tv/dvr/DvrWatchedPositionManager.java b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
index b4fea7f3..8616962f 100644
--- a/src/com/android/tv/dvr/DvrWatchedPositionManager.java
+++ b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
@@ -20,10 +20,8 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.media.tv.TvInputManager;
import android.support.annotation.IntDef;
-
import com.android.tv.common.util.SharedPreferencesUtils;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -38,7 +36,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
*/
public class DvrWatchedPositionManager {
private SharedPreferences mWatchedPositions;
- private final Map<Long, Set<WatchedPositionChangedListener>> mListeners = new HashMap<>();
+ private final Map<Long, Set> mListeners = new HashMap<>();
/**
* The minimum percentage of recorded program being watched that will be considered as being
diff --git a/src/com/android/tv/dvr/data/RecordedProgram.java b/src/com/android/tv/dvr/data/RecordedProgram.java
index 61430551..899e65ac 100644
--- a/src/com/android/tv/dvr/data/RecordedProgram.java
+++ b/src/com/android/tv/dvr/data/RecordedProgram.java
@@ -36,10 +36,9 @@ import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.data.RecordedProgramState;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.StringUtils;
-import com.android.tv.data.BaseProgramImpl;
+import com.android.tv.data.BaseProgram;
import com.android.tv.data.GenreItems;
import com.android.tv.data.InternalDataUtils;
-import com.android.tv.data.api.BaseProgram;
import com.android.tv.util.TvProviderUtils;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
@@ -50,7 +49,7 @@ import java.util.concurrent.TimeUnit;
/** Immutable instance of {@link android.media.tv.TvContract.RecordedPrograms}. */
@TargetApi(Build.VERSION_CODES.N)
@AutoValue
-public abstract class RecordedProgram extends BaseProgramImpl {
+public abstract class RecordedProgram extends BaseProgram {
public static final int ID_NOT_SET = -1;
private static final String TAG = "RecordedProgram";
diff --git a/src/com/android/tv/dvr/data/ScheduledRecording.java b/src/com/android/tv/dvr/data/ScheduledRecording.java
index 1237fb3e..ba6d3cf9 100644
--- a/src/com/android/tv/dvr/data/ScheduledRecording.java
+++ b/src/com/android/tv/dvr/data/ScheduledRecording.java
@@ -27,17 +27,15 @@ import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Range;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.util.CompositeComparator;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
@@ -494,7 +492,7 @@ public final class ScheduledRecording implements Parcelable {
}
};
- /** The ID internal to TV app */
+ /** The ID internal to Live TV */
private long mId;
/**
diff --git a/src/com/android/tv/dvr/data/SeriesRecording.java b/src/com/android/tv/dvr/data/SeriesRecording.java
index cd7d9662..6cb0e836 100644
--- a/src/com/android/tv/dvr/data/SeriesRecording.java
+++ b/src/com/android/tv/dvr/data/SeriesRecording.java
@@ -22,14 +22,11 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.text.TextUtils;
-
-import com.android.tv.data.BaseProgramImpl;
-import com.android.tv.data.api.BaseProgram;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
import com.android.tv.util.Utils;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -88,8 +85,7 @@ public class SeriesRecording implements Parcelable {
(SeriesRecording lhs, SeriesRecording rhs) -> Long.compare(lhs.mId, rhs.mId);
/**
- * Creates a new Builder with the values set from the series information of {@link
- * BaseProgramImpl}.
+ * Creates a new Builder with the values set from the series information of {@link BaseProgram}.
*/
public static Builder builder(String inputId, BaseProgram p) {
return new Builder()
diff --git a/src/com/android/tv/dvr/provider/DvrContract.java b/src/com/android/tv/dvr/provider/DvrContract.java
index 8539ae36..a5f2e2cd 100644
--- a/src/com/android/tv/dvr/provider/DvrContract.java
+++ b/src/com/android/tv/dvr/provider/DvrContract.java
@@ -20,7 +20,7 @@ import android.provider.BaseColumns;
/**
* The contract between the DVR provider and applications. Contains definitions for the supported
- * columns. It's for the internal use in TV app.
+ * columns. It's for the internal use in Live TV.
*/
public final class DvrContract {
/** Column definition for Schedules table. */
@@ -69,8 +69,8 @@ public final class DvrContract {
public static final String FAILED_REASON_INVALID_CHANNEL = "FAILED_REASON_INVALID_CHANNEL";
/** The recording failed because the scheduler was stopped */
- public static final String FAILED_REASON_SCHEDULER_STOPPED =
- "FAILED_REASON_SCHEDULER_STOPPED";
+ public static final String FAILED_REASON_SCHEDULER_STOPPED
+ = "FAILED_REASON_SCHEDULER_STOPPED";
/** The recording failed because some messages were not sent to the message queue */
public static final String FAILED_REASON_MESSAGE_NOT_SENT =
@@ -84,7 +84,8 @@ public final class DvrContract {
"FAILED_REASON_CONNECTION_FAILED";
/**
- * The recording failed because a required recording resource was not able to be allocated.
+ * The recording failed because a required recording resource was not able to be
+ * allocated.
*/
public static final String FAILED_REASON_RESOURCE_BUSY = "FAILED_REASON_RESOURCE_BUSY";
diff --git a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
index 1dcda8e0..ebf133db 100644
--- a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
+++ b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
@@ -26,18 +26,12 @@ import android.database.sqlite.SQLiteStatement;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
-
-import com.android.tv.common.dagger.annotations.ApplicationContext;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/** A data class for one recorded contents. */
-@Singleton
public class DvrDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DvrDatabaseHelper";
private static final boolean DEBUG = false;
@@ -244,9 +238,8 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
return "DELETE FROM " + tableName + " WHERE " + BaseColumns._ID + "=?";
}
- @Inject
- public DvrDatabaseHelper(@ApplicationContext Context context) {
- super(context, DB_NAME, null, DATABASE_VERSION);
+ public DvrDatabaseHelper(Context context) {
+ super(context.getApplicationContext(), DB_NAME, null, DATABASE_VERSION);
}
@Override
@@ -273,12 +266,8 @@ public class DvrDatabaseHelper extends SQLiteOpenHelper {
return;
}
if (oldVersion < 18) {
- db.execSQL(
- "ALTER TABLE "
- + Schedules.TABLE_NAME
- + " ADD COLUMN "
- + Schedules.COLUMN_FAILED_REASON
- + " TEXT DEFAULT null;");
+ db.execSQL("ALTER TABLE " + Schedules.TABLE_NAME + " ADD COLUMN "
+ + Schedules.COLUMN_FAILED_REASON + " TEXT DEFAULT null;");
}
}
diff --git a/src/com/android/tv/dvr/provider/DvrDbFuture.java b/src/com/android/tv/dvr/provider/DvrDbFuture.java
index cbc2c07d..ae8c480b 100644
--- a/src/com/android/tv/dvr/provider/DvrDbFuture.java
+++ b/src/com/android/tv/dvr/provider/DvrDbFuture.java
@@ -16,23 +16,21 @@
package com.android.tv.dvr.provider;
+import android.content.Context;
import android.database.Cursor;
import android.support.annotation.Nullable;
import android.util.Log;
-
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
import com.android.tv.util.MainThreadExecutor;
-
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
@@ -40,24 +38,29 @@ import java.util.concurrent.Executors;
/** {@link DvrDbFuture} that defaults to executing on its own single threaded Executor Service. */
public abstract class DvrDbFuture<ParamsT, ResultT> {
private static final NamedThreadFactory THREAD_FACTORY =
- new NamedThreadFactory(DvrDbFuture.class.getSimpleName());
+ new NamedThreadFactory(DvrDbFuture.class.getSimpleName());
private static final ListeningExecutorService DB_EXECUTOR =
- MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(THREAD_FACTORY));
+ MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(THREAD_FACTORY));
- final DvrDatabaseHelper mDbHelper;
+ private static DvrDatabaseHelper sDbHelper;
private ListenableFuture<ResultT> mFuture;
- private DvrDbFuture(DvrDatabaseHelper mDbHelper) {
- this.mDbHelper = mDbHelper;
+ final Context mContext;
+
+ private DvrDbFuture(Context context) {
+ mContext = context;
}
- /** Execute the task on the {@link #DB_EXECUTOR} thread and return Future */
+ /** Execute the task on the {@link #DB_EXECUTOR} thread and return Future*/
@SafeVarargs
public final ListenableFuture<ResultT> executeOnDbThread(
- FutureCallback<ResultT> callback, ParamsT... params) {
- mFuture = DB_EXECUTOR.submit(() -> dbHelperInBackground(params));
- Futures.addCallback(mFuture, callback, MainThreadExecutor.getInstance());
- return mFuture;
+ FutureCallback<ResultT> callback, ParamsT... params) {
+ if (sDbHelper == null) {
+ sDbHelper = new DvrDatabaseHelper(mContext.getApplicationContext());
+ }
+ mFuture = DB_EXECUTOR.submit(() -> dbHelperInBackground(params));
+ Futures.addCallback(mFuture, callback, MainThreadExecutor.getInstance());
+ return mFuture;
}
/** Executes in the background after initializing DbHelper} */
@@ -69,48 +72,52 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
/** Inserts schedules. */
- public static class AddScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public AddScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class AddScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public AddScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.insertSchedules(params);
+ sDbHelper.insertSchedules(params);
return null;
}
}
/** Update schedules. */
- public static class UpdateScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public UpdateScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class UpdateScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public UpdateScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.updateSchedules(params);
+ sDbHelper.updateSchedules(params);
return null;
}
}
/** Delete schedules. */
- public static class DeleteScheduleFuture extends DvrDbFuture<ScheduledRecording, Void> {
- public DeleteScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DeleteScheduleFuture
+ extends DvrDbFuture<ScheduledRecording, Void> {
+ public DeleteScheduleFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(ScheduledRecording... params) {
- mDbHelper.deleteSchedules(params);
+ sDbHelper.deleteSchedules(params);
return null;
}
}
/** Returns all {@link ScheduledRecording}s. */
- public static class DvrQueryScheduleFuture extends DvrDbFuture<Void, List<ScheduledRecording>> {
- public DvrQueryScheduleFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DvrQueryScheduleFuture
+ extends DvrDbFuture<Void, List<ScheduledRecording>> {
+ public DvrQueryScheduleFuture(Context context) {
+ super(context);
}
@Override
@@ -120,7 +127,7 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
return null;
}
List<ScheduledRecording> scheduledRecordings = new ArrayList<>();
- try (Cursor c = mDbHelper.query(Schedules.TABLE_NAME, ScheduledRecording.PROJECTION)) {
+ try (Cursor c = sDbHelper.query(Schedules.TABLE_NAME, ScheduledRecording.PROJECTION)) {
while (c.moveToNext() && !isCancelled()) {
scheduledRecordings.add(ScheduledRecording.fromCursor(c));
}
@@ -130,40 +137,43 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
/** Inserts series recordings. */
- public static class AddSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public AddSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class AddSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public AddSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.insertSeriesRecordings(params);
+ sDbHelper.insertSeriesRecordings(params);
return null;
}
}
/** Update series recordings. */
- public static class UpdateSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public UpdateSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class UpdateSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public UpdateSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.updateSeriesRecordings(params);
+ sDbHelper.updateSeriesRecordings(params);
return null;
}
}
/** Delete series recordings. */
- public static class DeleteSeriesRecordingFuture extends DvrDbFuture<SeriesRecording, Void> {
- public DeleteSeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public static class DeleteSeriesRecordingFuture
+ extends DvrDbFuture<SeriesRecording, Void> {
+ public DeleteSeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
protected final Void dbHelperInBackground(SeriesRecording... params) {
- mDbHelper.deleteSeriesRecordings(params);
+ sDbHelper.deleteSeriesRecordings(params);
return null;
}
}
@@ -173,8 +183,8 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
extends DvrDbFuture<Void, List<SeriesRecording>> {
private static final String TAG = "DvrQuerySeriesRecording";
- public DvrQuerySeriesRecordingFuture(DvrDatabaseHelper dbHelper) {
- super(dbHelper);
+ public DvrQuerySeriesRecordingFuture(Context context) {
+ super(context);
}
@Override
@@ -185,7 +195,7 @@ public abstract class DvrDbFuture<ParamsT, ResultT> {
}
List<SeriesRecording> scheduledRecordings = new ArrayList<>();
try (Cursor c =
- mDbHelper.query(SeriesRecordings.TABLE_NAME, SeriesRecording.PROJECTION)) {
+ sDbHelper.query(SeriesRecordings.TABLE_NAME, SeriesRecording.PROJECTION)) {
while (c.moveToNext() && !isCancelled()) {
scheduledRecordings.add(SeriesRecording.fromCursor(c));
}
diff --git a/src/com/android/tv/dvr/provider/DvrDbSync.java b/src/com/android/tv/dvr/provider/DvrDbSync.java
index c2eae771..7658ca45 100644
--- a/src/com/android/tv/dvr/provider/DvrDbSync.java
+++ b/src/com/android/tv/dvr/provider/DvrDbSync.java
@@ -29,19 +29,17 @@ import android.os.Looper;
import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.WritableDvrDataManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.util.AsyncDbTask.AsyncQueryProgramTask;
import com.android.tv.util.TvUriMatcher;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -51,7 +49,6 @@ import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
/**
* A class to synchronizes DVR DB with TvProvider.
@@ -68,11 +65,9 @@ public class DvrDbSync {
private static final String TAG = "DvrDbSync";
private static final boolean DEBUG = false;
- private static final long RECORD_MARGIN_MS = TimeUnit.SECONDS.toMillis(10);
-
private final Context mContext;
private final DvrManager mDvrManager;
- private final WritableDvrDataManager mDataManager;
+ private final DvrDataManagerImpl mDataManager;
private final ChannelDataManager mChannelDataManager;
private final Executor mDbExecutor;
private final Queue<Long> mProgramIdQueue = new LinkedList<>();
@@ -143,7 +138,7 @@ public class DvrDbSync {
}
};
- public DvrDbSync(Context context, WritableDvrDataManager dataManager) {
+ public DvrDbSync(Context context, DvrDataManagerImpl dataManager) {
this(
context,
dataManager,
@@ -156,7 +151,7 @@ public class DvrDbSync {
@VisibleForTesting
DvrDbSync(
Context context,
- WritableDvrDataManager dataManager,
+ DvrDataManagerImpl dataManager,
ChannelDataManager channelDataManager,
DvrManager dvrManager,
SeriesRecordingScheduler seriesRecordingScheduler,
@@ -330,15 +325,10 @@ public class DvrDbSync {
// Old program belongs to a series but the new one doesn't.
seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
}
- // Change start time only when the recording is not started yet and if it is not
- // within marginal time of current time. Marginal check is needed to prevent the
- // update of start time if recording is just triggered or about to get triggered.
- boolean marginalToCurrentTime = RECORD_MARGIN_MS >
- Math.abs(System.currentTimeMillis() - schedule.getStartTimeMs());
+ // Change start time only when the recording is not started yet.
boolean needToChangeStartTime =
schedule.getState() != ScheduledRecording.STATE_RECORDING_IN_PROGRESS
- && program.getStartTimeUtcMillis() != schedule.getStartTimeMs()
- && !marginalToCurrentTime;
+ && program.getStartTimeUtcMillis() != schedule.getStartTimeMs();
if (needToChangeStartTime) {
builder.setStartTimeMs(program.getStartTimeUtcMillis());
needUpdate = true;
diff --git a/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
index a66e5b02..02e197f1 100644
--- a/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
+++ b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
@@ -25,19 +25,16 @@ import android.net.Uri;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.PermissionUtils;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.AsyncDbTask.AsyncProgramQueryTask;
import com.android.tv.util.AsyncDbTask.CursorFilter;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -50,11 +47,11 @@ import java.util.Set;
public abstract class EpisodicProgramLoadTask {
private static final String TAG = "EpisodicProgramLoadTask";
- private static final int PROGRAM_ID_INDEX = ProgramImpl.getColumnIndex(Programs._ID);
+ private static final int PROGRAM_ID_INDEX = Program.getColumnIndex(Programs._ID);
private static final int START_TIME_INDEX =
- ProgramImpl.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
+ Program.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
private static final int RECORDING_PROHIBITED_INDEX =
- ProgramImpl.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
+ Program.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
private static final String PARAM_START_TIME = "start_time";
private static final String PARAM_END_TIME = "end_time";
@@ -292,7 +289,7 @@ public abstract class EpisodicProgramLoadTask {
&& mDisallowedProgramIds.contains(c.getLong(PROGRAM_ID_INDEX))) {
return false;
}
- Program program = ProgramImpl.fromCursor(c);
+ Program program = Program.fromCursor(c);
for (SeriesRecording seriesRecording : mSeriesRecordings) {
boolean programMatches;
if (mIgnoreChannelOption) {
diff --git a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
index 92b4e06a..696038cf 100644
--- a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
+++ b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
@@ -27,12 +27,11 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.LongSparseArray;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.CollectionUtils;
import com.android.tv.common.util.SharedPreferencesUtils;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
@@ -44,9 +43,6 @@ import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesInfo;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
-
-import dagger.Lazy;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -58,6 +54,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import javax.inject.Provider;
/**
* Creates the {@link com.android.tv.dvr.data.ScheduledRecording}s for the {@link
@@ -532,9 +529,10 @@ public class SeriesRecordingScheduler {
private class FetchSeriesInfoTask extends AsyncTask<Void, Void, SeriesInfo> {
private final SeriesRecording mSeriesRecording;
- private final Lazy<EpgReader> mEpgReaderProvider;
+ private final Provider<EpgReader> mEpgReaderProvider;
- FetchSeriesInfoTask(SeriesRecording seriesRecording, Lazy<EpgReader> epgReaderProvider) {
+ FetchSeriesInfoTask(
+ SeriesRecording seriesRecording, Provider<EpgReader> epgReaderProvider) {
mSeriesRecording = seriesRecording;
mEpgReaderProvider = epgReaderProvider;
}
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
index 1f4faf31..5e3caa9c 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
@@ -22,16 +22,13 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.RecordedProgram;
-
import java.util.List;
/**
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
index 56ffc884..a6bbe137 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
@@ -22,17 +22,14 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
-
import java.util.List;
/**
diff --git a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
index b24281ad..6be35cb2 100644
--- a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
@@ -18,9 +18,9 @@ package com.android.tv.dvr.ui;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
diff --git a/src/com/android/tv/dvr/ui/DvrConflictFragment.java b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
index 5e0a96bb..649cc89a 100644
--- a/src/com/android/tv/dvr/ui/DvrConflictFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
@@ -21,25 +21,22 @@ import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.recorder.ConflictChecker;
import com.android.tv.dvr.recorder.ConflictChecker.OnUpcomingConflictChangeListener;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java b/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
index 81fc3ed5..611962d0 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
index fda4cdee..a900cc70 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
@@ -20,9 +20,9 @@ import android.app.Activity;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
index e8f501e9..e6b54f67 100644
--- a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
@@ -20,15 +20,13 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import androidx.leanback.app.GuidedStepFragment;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelWatchConflictFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
@@ -38,7 +36,7 @@ import com.android.tv.ui.DetailsActivity;
public class DvrHalfSizedDialogFragment extends HalfSizedDialogFragment {
/** Key for input ID. Type: String. */
public static final String KEY_INPUT_ID = "DvrHalfSizedDialogFragment.input_id";
- /** Key for the program. Type: {@link ProgramImpl}. */
+ /** Key for the program. Type: {@link com.android.tv.data.Program}. */
public static final String KEY_PROGRAM = "DvrHalfSizedDialogFragment.program";
/** Key for the channel ID. Type: long. */
public static final String KEY_CHANNEL_ID = "DvrHalfSizedDialogFragment.channel_id";
diff --git a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
index 01631b99..6fba4d98 100644
--- a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
diff --git a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
index 3237acd7..02b2da1d 100644
--- a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
@@ -21,8 +21,8 @@ import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.util.Log;
import com.android.tv.R;
import com.android.tv.ui.DetailsActivity;
diff --git a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
index ae41f501..5bb97e90 100644
--- a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
@@ -22,9 +22,9 @@ import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
diff --git a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
index 7131f626..72603d03 100644
--- a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
@@ -22,21 +22,18 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
-
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
-
import java.util.Collections;
import java.util.List;
@@ -55,7 +52,7 @@ public class DvrScheduleFragment extends DvrGuidedStepFragment {
private static final int ACTION_RECORD_EPISODE = 1;
private static final int ACTION_RECORD_SERIES = 2;
- private ProgramImpl mProgram;
+ private Program mProgram;
private boolean mAddCurrentProgramToSeries;
@Override
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
index 730237c4..a237f1d2 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
@@ -20,13 +20,15 @@ import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.util.Log;
import android.widget.Toast;
+
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrManager;
+
import java.util.ArrayList;
import java.util.List;
@@ -68,7 +70,7 @@ public class DvrSeriesDeletionActivity extends Activity {
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
deleteSelectedIds(true);
} else {
- // NOTE: If TV app ever supports both embedded and separate DVR inputs
+ // NOTE: If Live TV ever supports both embedded and separate DVR inputs
// then we should try to do the delete regardless.
Log.i(
TAG,
@@ -91,14 +93,14 @@ public class DvrSeriesDeletionActivity extends Activity {
dvrManager.removeRecordedPrograms(mIdsToDelete, deleteFiles);
}
Toast.makeText(
- this,
- getResources()
- .getQuantityString(
- R.plurals.dvr_msg_episodes_deleted,
- mIdsToDelete.size(),
- mIdsToDelete.size(),
- recordingSize),
- Toast.LENGTH_LONG)
+ this,
+ getResources()
+ .getQuantityString(
+ R.plurals.dvr_msg_episodes_deleted,
+ mIdsToDelete.size(),
+ mIdsToDelete.size(),
+ recordingSize),
+ Toast.LENGTH_LONG)
.show();
finish();
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
index 10ef226b..ff213231 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
@@ -19,10 +19,10 @@ package com.android.tv.dvr.ui;
import android.content.Context;
import android.media.tv.TvInputManager;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.text.TextUtils;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
index d72099ba..9acb5b5e 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledDialogActivity.java
@@ -18,7 +18,7 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
public class DvrSeriesScheduledDialogActivity extends Activity {
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
index 7d369904..c6e26850 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
@@ -20,26 +20,22 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
-
import java.util.List;
public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
/**
* The key for program list which will be passed to {@link DvrSeriesSchedulesFragment}. Type:
- * List<{@link ProgramImpl}>
+ * List<{@link Program}>
*/
public static final String SERIES_SCHEDULED_KEY_PROGRAMS = "series_scheduled_key_programs";
@@ -50,7 +46,6 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
private SeriesRecording mSeriesRecording;
private boolean mShowViewScheduleOption;
private List<Program> mPrograms;
- private String mSeriesRecordingTitle;
private int mSchedulesAddedCount = 0;
private boolean mHasConflict = false;
@@ -80,7 +75,6 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
getActivity().finish();
return;
}
- mSeriesRecordingTitle = mSeriesRecording.getTitle();
mPrograms = (List<Program>) BigArguments.getArgument(SERIES_SCHEDULED_KEY_PROGRAMS);
BigArguments.reset();
mSchedulesAddedCount =
@@ -168,7 +162,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_no_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle);
+ mSeriesRecording.getTitle());
} else {
// mInThisSeriesConflictCount equals 0 and mOutThisSeriesConflictCount equals 0 means
// mHasConflict is false. So we don't need to check that case.
@@ -178,7 +172,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_this_and_other_series_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mInThisSeriesConflictCount + mOutThisSeriesConflictCount);
} else if (mInThisSeriesConflictCount != 0) {
return getResources()
@@ -186,7 +180,7 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_recording_scheduled_only_this_series_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mInThisSeriesConflictCount);
} else {
if (mOutThisSeriesConflictCount == 1) {
@@ -195,14 +189,14 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
R.plurals.dvr_series_scheduled_only_other_series_one_conflict,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle);
+ mSeriesRecording.getTitle());
} else {
return getResources()
.getQuantityString(
R.plurals.dvr_series_scheduled_only_other_series_many_conflicts,
mSchedulesAddedCount,
mSchedulesAddedCount,
- mSeriesRecordingTitle,
+ mSeriesRecording.getTitle(),
mOutThisSeriesConflictCount);
}
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
index eb3ca283..1a51cf46 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
@@ -19,13 +19,10 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-
-import androidx.leanback.app.GuidedStepFragment;
-
+import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.ProgramImpl;
/** Activity to show details view in DVR. */
public class DvrSeriesSettingsActivity extends Activity {
@@ -43,7 +40,7 @@ public class DvrSeriesSettingsActivity extends Activity {
public static final String IS_WINDOW_TRANSLUCENT = "windows_translucent";
/**
* Name of the program list. The list contains the programs which belong to the series. Type:
- * List<{@link ProgramImpl}>
+ * List<{@link com.android.tv.data.Program}>
*/
public static final String PROGRAM_LIST = "program_list";
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
index 7fc201c5..eadb3b9e 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
@@ -21,19 +21,17 @@ import android.app.FragmentManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.util.LongSparseArray;
-
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -41,7 +39,6 @@ import com.android.tv.dvr.data.SeasonEpisodeNumber;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.data.SeriesRecording.ChannelOption;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -72,7 +69,6 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
private Program mCurrentProgram;
private String mFragmentTitle;
- private String mSeriesRecordingTitle;
private String mProrityActionTitle;
private String mProrityActionHighestText;
private String mProrityActionLowestText;
@@ -96,7 +92,6 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
getActivity().finish();
return;
}
- mSeriesRecordingTitle = mSeriesRecording.getTitle();
mShowViewScheduleOptionInDialog =
getArguments()
.getBoolean(DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG);
@@ -166,8 +161,9 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String breadcrumb = mSeriesRecording.getTitle();
String title = mFragmentTitle;
- return new Guidance(title, null, mSeriesRecordingTitle, null);
+ return new Guidance(title, null, breadcrumb, null);
}
@Override
diff --git a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
index 1475a8c3..1ab4c500 100644
--- a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
@@ -23,17 +23,13 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.data.ScheduledRecording;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -48,7 +44,7 @@ import java.util.List;
public class DvrStopRecordingFragment extends DvrGuidedStepFragment {
/** The action ID for the stop action. */
public static final int ACTION_STOP = 1;
- /** Key for the program. Type: {@link ProgramImpl}. */
+ /** Key for the program. Type: {@link com.android.tv.data.Program}. */
public static final String KEY_REASON = "DvrStopRecordingFragment.type";
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
index 4a8ce04e..15abf902 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
@@ -18,7 +18,7 @@ package com.android.tv.dvr.ui;
import android.app.DialogFragment;
import android.os.Bundle;
-import androidx.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
index 0b8f5df0..99211fdb 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrUiHelper.java b/src/com/android/tv/dvr/ui/DvrUiHelper.java
index 657abfa2..a121cf99 100644
--- a/src/com/android/tv/dvr/ui/DvrUiHelper.java
+++ b/src/com/android/tv/dvr/ui/DvrUiHelper.java
@@ -33,7 +33,6 @@ import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
-import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.widget.ImageView;
@@ -45,9 +44,9 @@ import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.recording.RecordingStorageStatusManager;
import com.android.tv.common.util.CommonUtils;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.RecordedProgram;
@@ -76,7 +75,6 @@ import com.android.tv.ui.DetailsActivity;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
-import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -124,7 +122,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
args.putBoolean(
DvrScheduleFragment.KEY_ADD_CURRENT_PROGRAM_TO_SERIES, addCurrentProgramToSeries);
showDialogFragment(activity, new DvrScheduleDialogFragment(), args, true, true);
@@ -146,7 +144,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrProgramConflictDialogFragment(), args, false, true);
}
@@ -229,7 +227,7 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrAlreadyScheduledDialogFragment(), args, false, true);
}
@@ -239,18 +237,14 @@ public class DvrUiHelper {
return;
}
Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program.toParcelable());
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
showDialogFragment(activity, new DvrAlreadyRecordedDialogFragment(), args, false, true);
}
/** Shows program information dialog. */
public static void showWriteStoragePermissionRationaleDialog(Activity activity) {
- showDialogFragment(
- activity,
- new DvrWriteStoragePermissionRationaleDialogFragment(),
- new Bundle(),
- false,
- false);
+ showDialogFragment(activity, new DvrWriteStoragePermissionRationaleDialogFragment(),
+ new Bundle(), false, false);
}
/**
@@ -465,7 +459,7 @@ public class DvrUiHelper {
boolean removeEmptySeriesSchedule,
boolean isWindowTranslucent,
boolean showViewScheduleOptionInDialog,
- @Nullable Program currentProgram) {
+ Program currentProgram) {
SeriesRecording series =
TvSingletons.getSingletons(context)
.getDvrDataManager()
@@ -487,15 +481,13 @@ public class DvrUiHelper {
new EpisodicProgramLoadTask(context, series) {
@Override
protected void onPostExecute(List<Program> loadedPrograms) {
- if (sProgressDialog != null) {
- sProgressDialog.dismiss();
- sProgressDialog = null;
- }
+ sProgressDialog.dismiss();
+ sProgressDialog = null;
startSeriesSettingsActivityInternal(
context,
seriesRecordingId,
loadedPrograms == null
- ? ImmutableList.of()
+ ? Collections.EMPTY_LIST
: loadedPrograms,
removeEmptySeriesSchedule,
isWindowTranslucent,
@@ -532,7 +524,7 @@ public class DvrUiHelper {
boolean removeEmptySeriesSchedule,
boolean isWindowTranslucent,
boolean showViewScheduleOptionInDialog,
- @Nullable Program currentProgram) {
+ Program currentProgram) {
SoftPreconditions.checkState(
programs != null, TAG, "Start series settings activity but programs is null");
Intent intent = new Intent(context, DvrSeriesSettingsActivity.class);
@@ -545,9 +537,7 @@ public class DvrUiHelper {
intent.putExtra(
DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG,
showViewScheduleOptionInDialog);
- if (currentProgram != null) {
- intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram.toParcelable());
- }
+ intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram);
context.startActivity(intent);
}
@@ -692,18 +682,16 @@ public class DvrUiHelper {
}
SpannableStringBuilder builder;
if (TextUtils.isEmpty(seasonNumber) || seasonNumber.equals("0")) {
- Spanned temp =
+ builder =
TextUtils.isEmpty(episodeNumber)
- ? SpannableStringBuilder.valueOf(title)
- : Html.fromHtml(
- context.getString(
- R.string.program_title_with_episode_number_no_season,
- title,
- episodeNumber));
- builder = SpannableStringBuilder.valueOf(temp);
+ ? new SpannableStringBuilder(title)
+ : new SpannableStringBuilder(Html.fromHtml(context.getString(
+ R.string.program_title_with_episode_number_no_season,
+ title,
+ episodeNumber)));
} else {
builder =
- SpannableStringBuilder.valueOf(
+ new SpannableStringBuilder(
Html.fromHtml(
context.getString(
R.string.program_title_with_episode_number,
diff --git a/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java b/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
index 25f7f38b..c93f5831 100644
--- a/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
@@ -19,8 +19,8 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
-import androidx.leanback.widget.GuidanceStylist;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
index 7a26d5ed..1eb8080a 100644
--- a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
+++ b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.support.annotation.VisibleForTesting;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.PresenterSelector;
import com.android.tv.common.SoftPreconditions;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
index c0a57c0f..0172f76f 100644
--- a/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
diff --git a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
index a06705c6..41ace9a4 100644
--- a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
+++ b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
@@ -17,10 +17,10 @@
package com.android.tv.dvr.ui.browse;
import android.graphics.drawable.Drawable;
-import androidx.leanback.R;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.R;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
index 88ef112f..8c311d68 100644
--- a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
@@ -19,13 +19,12 @@ package com.android.tv.dvr.ui.browse;
import android.content.Context;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
-
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
+import com.android.tv.common.flags.has.HasConcurrentDvrPlaybackFlags;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -34,10 +33,7 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
import com.android.tv.dvr.ui.DvrUiHelper;
-
-import dagger.android.AndroidInjection;
-
-import javax.inject.Inject;
+import com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
/** {@link RecordingDetailsFragment} for current recording in DVR. */
public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
@@ -47,7 +43,8 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
private DvrDataManager mDvrDataManger;
private RecordedProgram mRecordedProgram;
- @Inject DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private boolean mPaused;
private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
new DvrDataManager.ScheduledRecordingListener() {
@@ -79,10 +76,12 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
@Override
public void onAttach(Context context) {
- AndroidInjection.inject(this);
super.onAttach(context);
mDvrDataManger = TvSingletons.getSingletons(context).getDvrDataManager();
mDvrDataManger.addScheduledRecordingListener(mScheduledRecordingListener);
+ mDvrWatchedPositionManager =
+ TvSingletons.getSingletons(getActivity()).getDvrWatchedPositionManager();
+ mConcurrentDvrPlaybackFlags = HasConcurrentDvrPlaybackFlags.fromContext(context);
}
@Override
@@ -116,7 +115,9 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
res.getString(R.string.dvr_detail_stop_recording),
null,
res.getDrawable(R.drawable.lb_ic_stop)));
- if (mRecordedProgram != null && mRecordedProgram.isPartial()) {
+ if (mConcurrentDvrPlaybackFlags.enabled()
+ && mRecordedProgram != null
+ && mRecordedProgram.isPartial()) {
if (mDvrWatchedPositionManager.getWatchedStatus(mRecordedProgram)
== DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
adapter.set(
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContent.java b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
index b5e05264..e179743c 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContent.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
@@ -20,11 +20,10 @@ import android.content.Context;
import android.media.tv.TvContract;
import android.support.annotation.Nullable;
import android.text.TextUtils;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
@@ -127,10 +126,9 @@ public class DetailsContent {
}
private static String getErrorMessage(Context context, ScheduledRecording recording) {
- int reason =
- recording.getFailedReason() == null
- ? ScheduledRecording.FAILED_REASON_OTHER
- : recording.getFailedReason();
+ int reason = recording.getFailedReason() == null
+ ? ScheduledRecording.FAILED_REASON_OTHER
+ : recording.getFailedReason();
switch (reason) {
case ScheduledRecording.FAILED_REASON_PROGRAM_ENDED_BEFORE_RECORDING_STARTED:
return context.getString(R.string.dvr_recording_failed_not_started);
@@ -138,7 +136,8 @@ public class DetailsContent {
return context.getString(R.string.dvr_recording_failed_resource_busy);
case ScheduledRecording.FAILED_REASON_INPUT_UNAVAILABLE:
return context.getString(
- R.string.dvr_recording_failed_input_unavailable, recording.getInputId());
+ R.string.dvr_recording_failed_input_unavailable,
+ recording.getInputId());
case ScheduledRecording.FAILED_REASON_INPUT_DVR_UNSUPPORTED:
return context.getString(R.string.dvr_recording_failed_input_dvr_unsupported);
case ScheduledRecording.FAILED_REASON_INSUFFICIENT_SPACE:
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
index fafc70cf..6b5fd1fd 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
@@ -24,7 +24,7 @@ import android.app.Activity;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
-import androidx.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Presenter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -40,10 +40,10 @@ import com.android.tv.util.Utils;
/**
* An {@link Presenter} for rendering a detailed description of an DVR item. Typically this
* Presenter will be used in a {@link
- * androidx.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
- * originated from {@link androidx.leanback.widget.AbstractDetailsDescriptionPresenter}.
+ * android.support.v17.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
+ * originated from {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
* The latter class are re-used to provide a customized version of {@link
- * androidx.leanback.widget.DetailsOverviewRow}.
+ * android.support.v17.leanback.widget.DetailsOverviewRow}.
*/
public class DetailsContentPresenter extends Presenter {
/** The ViewHolder for the {@link DetailsContentPresenter}. */
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
index 8a4c7854..4e41daee 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
+++ b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
@@ -21,7 +21,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import androidx.leanback.app.BackgroundManager;
+import android.support.v17.leanback.app.BackgroundManager;
/** The Background Helper. */
public class DetailsViewBackgroundHelper {
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
index 7262b4a0..5743ea5c 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
@@ -22,13 +22,13 @@ import android.media.tv.TvInputManager;
import android.os.Bundle;
import com.android.tv.R;
import com.android.tv.Starter;
-import com.android.tv.perf.StartupMeasureFactory;
+import com.android.tv.perf.PerformanceMonitorManagerFactory;
/** {@link android.app.Activity} for DVR UI. */
public class DvrBrowseActivity extends Activity {
{
- StartupMeasureFactory.create().onActivityInit();
+ PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
}
private DvrBrowseFragment mFragment;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
index 786942e0..17ba1939 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
@@ -21,14 +21,13 @@ import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.text.TextUtils;
-import androidx.leanback.app.BrowseFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.TitleViewAdapter;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.TitleViewAdapter;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
@@ -476,7 +475,7 @@ public class DvrBrowseFragment extends BrowseFragment
mRecentAdapter.add(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
SeriesRecording seriesRecording = null;
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
if (latestProgram == null
@@ -500,7 +499,7 @@ public class DvrBrowseFragment extends BrowseFragment
private void handleRecordedProgramRemoved(RecordedProgram recordedProgram) {
mRecentAdapter.remove(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram =
mSeriesId2LatestProgram.get(recordedProgram.getSeriesId());
@@ -521,7 +520,7 @@ public class DvrBrowseFragment extends BrowseFragment
mRecentAdapter.change(recordedProgram);
String seriesId = recordedProgram.getSeriesId();
SeriesRecording seriesRecording = null;
- if (!TextUtils.isEmpty(seriesId)) {
+ if (seriesId != null) {
seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
if (latestProgram == null
@@ -664,7 +663,7 @@ public class DvrBrowseFragment extends BrowseFragment
}
}
if (getSelectedPosition() >= mRowsAdapter.size()) {
- setSelectedPosition(mRowsAdapter.size() - 1);
+ setSelectedPosition(mRecentAdapter.size() - 1);
}
}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
index a38180a5..f90981f0 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
@@ -25,15 +25,15 @@ import android.media.tv.TvContentRating;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.text.TextUtils;
import android.widget.Toast;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
index ebdee32f..4298d86a 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
@@ -19,7 +19,7 @@ package com.android.tv.dvr.ui.browse;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.CallSuper;
-import androidx.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Presenter;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
index 625f8f76..a2d1cb28 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.browse;
import android.content.Context;
-import androidx.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ListRowPresenter;
import android.view.ViewGroup;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
index 5f58af8e..bf963547 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
@@ -19,9 +19,9 @@ package com.android.tv.dvr.ui.browse;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
import android.os.Bundle;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.util.PermissionUtils;
@@ -32,7 +32,7 @@ import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.ui.DetailsActivity;
-/** {@link androidx.leanback.app.DetailsFragment} for recorded program in DVR. */
+/** {@link android.support.v17.leanback.app.DetailsFragment} for recorded program in DVR. */
public class RecordedProgramDetailsFragment extends DvrDetailsFragment
implements DvrDataManager.RecordedProgramListener {
private static final int ACTION_RESUME_PLAYING = 1;
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
index ac7c5745..c83ceaf0 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
@@ -23,16 +23,14 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
-import android.text.Layout;
+import android.support.v17.leanback.widget.BaseCardView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.leanback.widget.BaseCardView;
import com.android.tv.R;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.ui.ViewUtils;
@@ -44,7 +42,7 @@ import com.android.tv.util.images.ImageLoader;
*/
public class RecordingCardView extends BaseCardView {
// This value should be the same with
- // androidx.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
+ // android.support.v17.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
private static final int ANIMATION_DURATION = 150;
private final ImageView mImageView;
private final int mImageWidth;
@@ -64,7 +62,6 @@ public class RecordingCardView extends BaseCardView {
private final boolean mExpandTitleWhenFocused;
private boolean mExpanded;
private String mDetailBackgroundImageUri;
- private Layout mTitleViewLayout;
public RecordingCardView(Context context) {
this(context, false);
@@ -123,14 +120,6 @@ public class RecordingCardView extends BaseCardView {
* value));
}
});
- getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- getViewTreeObserver().removeOnGlobalLayoutListener(this);
- mTitleViewLayout = mFoldedTitleView.getLayout();
- }
- });
mExpandTitleWhenFocused = expandTitleWhenFocused;
}
@@ -165,8 +154,7 @@ public class RecordingCardView extends BaseCardView {
* @param withAnimation {@code true} to expand/fold with animation.
*/
public void expandTitle(boolean expand, boolean withAnimation) {
- if (expand != mExpanded && mTitleViewLayout != null
- && mTitleViewLayout.getEllipsisCount(0) > 0) {
+ if (expand != mExpanded && mFoldedTitleView.getLayout().getEllipsisCount(0) > 0) {
if (withAnimation) {
if (expand) {
mExpandTitleAnimator.start();
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
index e85f983f..243681c6 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.browse;
import android.os.Bundle;
-import androidx.leanback.app.DetailsFragment;
+import android.support.v17.leanback.app.DetailsFragment;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.ui.DetailsActivity;
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
index 7ef8e59f..f08bb12b 100644
--- a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
@@ -18,9 +18,9 @@ package com.android.tv.dvr.ui.browse;
import android.content.res.Resources;
import android.os.Bundle;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
index 1c020091..9104ef10 100644
--- a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
@@ -21,21 +21,21 @@ import android.graphics.drawable.Drawable;
import android.media.tv.TvInputManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.text.TextUtils;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
import com.android.tv.R;
import com.android.tv.TvSingletons;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.data.RecordedProgram;
diff --git a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
index 293e1d94..77a63508 100644
--- a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
@@ -17,8 +17,8 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
index 1d93c8cb..0ca05fac 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
@@ -17,24 +17,23 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.DateHeaderRowPresenter;
-import com.android.tv.common.flags.UiFlags;
/** A fragment to show the DVR history. */
public class DvrHistoryFragment extends DetailsFragment
implements DvrDataManager.ScheduledRecordingListener,
- DvrDataManager.RecordedProgramListener {
+ DvrDataManager.RecordedProgramListener {
private DvrHistoryRowAdapter mRowsAdapter;
private TextView mEmptyInfoScreenView;
@@ -49,17 +48,11 @@ public class DvrHistoryFragment extends DetailsFragment
presenterSelector.addClassPresenter(
ScheduleRow.class, new ScheduleRowPresenter(getContext()));
TvSingletons singletons = TvSingletons.getSingletons(getContext());
- UiFlags uiFlags = singletons.getUiFlags();
- mDvrDataManager = singletons.getDvrDataManager();
- mRowsAdapter =
- new DvrHistoryRowAdapter(
- getContext(),
- presenterSelector,
- singletons.getClock(),
- mDvrDataManager,
- uiFlags);
+ mRowsAdapter = new DvrHistoryRowAdapter(
+ getContext(), presenterSelector, singletons.getClock());
setAdapter(mRowsAdapter);
mRowsAdapter.start();
+ mDvrDataManager = singletons.getDvrDataManager();
mDvrDataManager.addScheduledRecordingListener(this);
mDvrDataManager.addRecordedProgramListener(this);
mEmptyInfoScreenView = (TextView) getActivity().findViewById(R.id.empty_info_screen);
@@ -142,6 +135,7 @@ public class DvrHistoryFragment extends DetailsFragment
hideEmptyMessage();
}
}
+
}
@Override
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
index a10367fb..156d1a7e 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
@@ -20,19 +20,20 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import android.util.Log;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
+import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.Clock;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.ScheduledProgramReaper;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow;
import com.android.tv.util.Utils;
-import com.android.tv.common.flags.UiFlags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -47,8 +48,8 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private static final boolean DEBUG = false;
private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
+ private static final int MAX_HISTORY_DAYS = ScheduledProgramReaper.DAYS;
- private final long mMaxHistoryDays;
private final Context mContext;
private final Clock mClock;
private final DvrDataManager mDvrDataManager;
@@ -56,16 +57,11 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private final Map<Long, ScheduledRecording> mRecordedProgramScheduleMap = new HashMap<>();
public DvrHistoryRowAdapter(
- Context context,
- ClassPresenterSelector classPresenterSelector,
- Clock clock,
- DvrDataManager dvrDataManager,
- UiFlags uiFlags) {
+ Context context, ClassPresenterSelector classPresenterSelector, Clock clock) {
super(classPresenterSelector);
mContext = context;
mClock = clock;
- mDvrDataManager = dvrDataManager;
- mMaxHistoryDays = uiFlags.maxHistoryDays();
+ mDvrDataManager = TvSingletons.getSingletons(mContext).getDvrDataManager();
mTitles.add(mContext.getString(R.string.dvr_date_today));
mTitles.add(mContext.getString(R.string.dvr_date_yesterday));
}
@@ -82,9 +78,9 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
List<RecordedProgram> recordedProgramList = mDvrDataManager.getRecordedPrograms();
recordingList.addAll(
- recordedProgramsToScheduledRecordings(recordedProgramList, mMaxHistoryDays));
- recordingList.sort(
- ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
+ recordedProgramsToScheduledRecordings(recordedProgramList, MAX_HISTORY_DAYS));
+ recordingList
+ .sort(ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
long deadLine = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
for (int i = 0; i < recordingList.size(); ) {
ArrayList<ScheduledRecording> section = new ArrayList<>();
@@ -132,7 +128,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
}
private List<ScheduledRecording> recordedProgramsToScheduledRecordings(
- List<RecordedProgram> programs, long maxDays) {
+ List<RecordedProgram> programs, int maxDays) {
List<ScheduledRecording> result = new ArrayList<>();
for (RecordedProgram recordedProgram : programs) {
ScheduledRecording scheduledRecording =
@@ -146,12 +142,12 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
@Nullable
private ScheduledRecording recordedProgramsToScheduledRecordings(
- RecordedProgram program, long maxDays) {
+ RecordedProgram program, int maxDays) {
long firstMillisecondToday = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
- if (maxDays != 0
- && maxDays
- < Utils.computeDateDifference(
- program.getStartTimeUtcMillis(), firstMillisecondToday)) {
+ if (maxDays
+ < Utils.computeDateDifference(
+ program.getStartTimeUtcMillis(),
+ firstMillisecondToday)) {
return null;
}
ScheduledRecording scheduledRecording = ScheduledRecording.builder(program).build();
@@ -179,7 +175,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
return;
}
ScheduledRecording schedule =
- recordedProgramsToScheduledRecordings(program, mMaxHistoryDays);
+ recordedProgramsToScheduledRecordings(program, MAX_HISTORY_DAYS);
if (schedule == null) {
return;
}
@@ -252,10 +248,8 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
for (; index < size(); index++) {
if (get(index) instanceof ScheduleRow) {
ScheduleRow scheduleRow = (ScheduleRow) get(index);
- if (ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
- .reversed()
- .compare(scheduleRow.getSchedule(), recording)
- > 0) {
+ if (ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed()
+ .compare(scheduleRow.getSchedule(), recording) > 0) {
break;
}
pre = index;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
index d0884f99..82b85630 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
@@ -20,15 +20,13 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.IntDef;
-
import com.android.tv.R;
import com.android.tv.Starter;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.dvr.ui.BigArguments;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
index 43a3579a..d97b61f4 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
@@ -17,7 +17,7 @@
package com.android.tv.dvr.ui.list;
import android.os.Bundle;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import com.android.tv.R;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.DateHeaderRowPresenter;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
index 50bc04c7..d376e358 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
@@ -25,24 +25,20 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.transition.Fade;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
import com.android.tv.dvr.ui.BigArguments;
-
import java.util.Collections;
import java.util.List;
@@ -57,7 +53,7 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
"series_schedules_key_series_recording";
/**
* The key for programs which belong to the series recording whose scheduled recording list will
- * be displayed. Type: List<{@link ProgramImpl}>
+ * be displayed. Type: List<{@link Program}>
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_PROGRAMS =
"series_schedules_key_series_programs";
diff --git a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
index ccb497fb..d5808412 100644
--- a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
+++ b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
@@ -17,8 +17,7 @@
package com.android.tv.dvr.ui.list;
import android.content.Context;
-
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.ScheduledRecording.Builder;
import com.android.tv.dvr.ui.DvrUiHelper;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
index de259f5a..ef4a4337 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
@@ -22,8 +22,8 @@ import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Log;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
index ff296f49..11680a0d 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
@@ -24,7 +24,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.IntDef;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
index 5c687cde..bbddc07f 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
@@ -16,9 +16,8 @@
package com.android.tv.dvr.ui.list;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.data.SeriesRecording;
-
import java.util.List;
/** A base class for the rows for schedules' header. */
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
index 2550eebc..28a44bf3 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
@@ -19,7 +19,7 @@ package com.android.tv.dvr.ui.list;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
index 2c377549..9a9c94ea 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
@@ -20,22 +20,19 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.media.tv.TvInputInfo;
import android.os.Build;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.util.ArrayMap;
import android.util.Log;
-
-import androidx.leanback.widget.ClassPresenterSelector;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
index 4aa1200e..f24ad2c0 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
@@ -16,6 +16,7 @@
package com.android.tv.dvr.ui.playback;
+import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.content.res.Configuration;
@@ -27,12 +28,9 @@ import com.android.tv.Starter;
import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.util.Utils;
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerActivity;
/** Activity to play a {@link RecordedProgram}. */
-public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedListener {
+public class DvrPlaybackActivity extends Activity implements OnPinCheckedListener {
private static final String TAG = "DvrPlaybackActivity";
private static final boolean DEBUG = false;
@@ -41,7 +39,6 @@ public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedL
@Override
public void onCreate(Bundle savedInstanceState) {
- AndroidInjection.inject(this);
Starter.start(this);
if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
@@ -95,16 +92,4 @@ public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedL
void setOnPinCheckListener(OnPinCheckedListener listener) {
mOnPinCheckedListener = listener;
}
-
- /**
- * Exports {@link DvrPlaybackActivity} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract DvrPlaybackActivity contributesDvrPlaybackActivity();
-
- @ContributesAndroidInjector
- abstract DvrPlaybackOverlayFragment contributesDvrPlaybackOverlayFragment();
- }
}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
index 35c5d4e4..791d26bb 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
@@ -26,15 +26,15 @@ import android.media.session.PlaybackState;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.media.PlaybackControlGlue;
-import androidx.leanback.widget.AbstractDetailsDescriptionPresenter;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.PlaybackControlsRow;
-import androidx.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
-import androidx.leanback.widget.PlaybackControlsRow.MultiAction;
-import androidx.leanback.widget.PlaybackControlsRowPresenter;
-import androidx.leanback.widget.RowPresenter;
+import android.support.v17.leanback.media.PlaybackControlGlue;
+import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
index 0c96cac8..1059e852 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
@@ -26,25 +26,24 @@ import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
+import android.support.v17.leanback.app.PlaybackFragment;
+import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SinglePresenterSelector;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
-import androidx.leanback.app.PlaybackFragment;
-import androidx.leanback.app.PlaybackFragmentGlueHost;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.BaseOnItemViewClickedListener;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.RowPresenter;
-import androidx.leanback.widget.SinglePresenterSelector;
import com.android.tv.R;
-import com.android.tv.audio.AudioManagerHelper;
-import com.android.tv.common.buildtype.HasBuildType.BuildType;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.TvSingletons;
+import com.android.tv.data.BaseProgram;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
@@ -56,11 +55,8 @@ import com.android.tv.ui.AppLayerTvView;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvTrackInfoUtils;
import com.android.tv.util.Utils;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.List;
-import javax.inject.Inject;
public class DvrPlaybackOverlayFragment extends PlaybackFragment {
// TODO: Handles audio focus. Deals with block and ratings.
@@ -79,7 +75,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
private ArrayObjectAdapter mRowsAdapter;
private SortedArrayAdapter<BaseProgram> mRelatedRecordingsRowAdapter;
private DvrPlaybackCardPresenter mRelatedRecordingCardPresenter;
- private AudioManagerHelper mAudioManagerHelper;
+ private DvrDataManager mDvrDataManager;
private AppLayerTvView mTvView;
private View mBlockScreenView;
private ListRow mRelatedRecordingsRow;
@@ -101,24 +97,9 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
}
};
- @Inject DvrDataManager mDvrDataManager;
- @Inject LegacyFlags mLegacyFlags;
- @Inject BuildType buildType;
-
- @Override
- public void onAttach(Context context) {
- if (DEBUG) {
- Log.d(TAG, "onAttach");
- }
- AndroidInjection.inject(this);
- super.onAttach(context);
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
- if (DEBUG) {
- Log.d(TAG, "onCreate");
- }
+ if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
mVerticalPaddingBase =
getActivity()
@@ -134,6 +115,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
.getResources()
.getDimensionPixelOffset(
R.dimen.dvr_playback_overlay_padding_top_no_secondary_row);
+ mDvrDataManager = TvSingletons.getSingletons(getActivity()).getDvrDataManager();
if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
mDvrDataManager.addRecordedProgramLoadFinishedListener(
new DvrDataManager.OnRecordedProgramLoadFinishedListener() {
@@ -171,8 +153,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTvView = getActivity().findViewById(R.id.dvr_tv_view);
- mTvView.setUseSecureSurface(
- buildType != BuildType.ENG && !mLegacyFlags.enableDeveloperFeatures());
mBlockScreenView = getActivity().findViewById(R.id.block_screen);
mDvrPlayer = new DvrPlayer(mTvView, getActivity());
mMediaSessionHelper =
@@ -260,16 +240,13 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
setFadingEnabled(false);
long programId =
((RecordedProgram) itemViewHolder.view.getTag()).getId();
- if (DEBUG) {
- Log.d(TAG, "Play Related Recording:" + programId);
- }
+ if (DEBUG) Log.d(TAG, "Play Related Recording:" + programId);
Intent intent = new Intent(getContext(), DvrPlaybackActivity.class);
intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, programId);
getContext().startActivity(intent);
}
}
});
- mAudioManagerHelper = new AudioManagerHelper(getActivity(), mDvrPlayer.getView());
if (mProgram != null) {
setUpRows();
preparePlayback(getActivity().getIntent());
@@ -278,9 +255,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
@Override
public void onPause() {
- if (DEBUG) {
- Log.d(TAG, "onPause");
- }
+ if (DEBUG) Log.d(TAG, "onPause");
super.onPause();
if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING
|| mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_REWINDING) {
@@ -295,12 +270,9 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
@Override
public void onDestroy() {
- if (DEBUG) {
- Log.d(TAG, "onDestroy");
- }
+ if (DEBUG) Log.d(TAG, "onDestroy");
mPlaybackControlHelper.unregisterCallback();
mMediaSessionHelper.release();
- mAudioManagerHelper.abandonAudioFocus();
mRelatedRecordingCardPresenter.unbindAllViewHolders();
mDvrPlayer.release();
super.onDestroy();
@@ -444,7 +416,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
private void preparePlayback(Intent intent) {
mMediaSessionHelper.setupPlayback(mProgram, getSeekTimeFromIntent(intent));
mPlaybackControlHelper.updateSecondaryRow(false, false);
- mAudioManagerHelper.requestAudioFocus();
getActivity().getMediaController().getTransportControls().prepare();
updateRelatedRecordingsRow();
}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
index 95858e3c..b4481df8 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
@@ -19,8 +19,8 @@ package com.android.tv.dvr.ui.playback;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
import android.text.TextUtils;
import android.transition.Transition;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
index 6cfa2e20..d14646b8 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
@@ -326,11 +326,6 @@ public class DvrPlayer {
return mProgram;
}
- /** Returns the DVR tv view. */
- public DvrTvView getView() {
- return mTvView;
- }
-
/** Returns the currrent playback posistion in msecs. */
public long getPlaybackPosition() {
return mTimeShiftCurrentPositionMs;
@@ -521,17 +516,13 @@ public class DvrPlayer {
for (TvTrackInfo trackInfo : trackInfos) {
if (trackInfo.getId().equals(trackId)) {
float videoAspectRatio;
- float videoPixelAspectRatio =
- trackInfo.getVideoPixelAspectRatio();
int videoWidth = trackInfo.getVideoWidth();
int videoHeight = trackInfo.getVideoHeight();
if (videoWidth > 0 && videoHeight > 0) {
videoAspectRatio =
- (float) trackInfo.getVideoWidth()
+ trackInfo.getVideoPixelAspectRatio()
+ * trackInfo.getVideoWidth()
/ trackInfo.getVideoHeight();
- videoAspectRatio *=
- videoPixelAspectRatio > 0 ?
- videoPixelAspectRatio : 1;
} else {
// Aspect ratio is unknown. Pass the message to
// listeners.
diff --git a/src/com/android/tv/features/TvFeatures.java b/src/com/android/tv/features/TvFeatures.java
index a18d9c89..208d53f6 100644
--- a/src/com/android/tv/features/TvFeatures.java
+++ b/src/com/android/tv/features/TvFeatures.java
@@ -27,11 +27,14 @@ import static com.android.tv.common.feature.FeatureUtils.or;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
-
+import android.support.annotation.VisibleForTesting;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.ExperimentFeature;
import com.android.tv.common.feature.Feature;
import com.android.tv.common.feature.FeatureUtils;
import com.android.tv.common.feature.FlagFeature;
+import com.android.tv.common.feature.PropertyFeature;
import com.android.tv.common.feature.Sdk;
import com.android.tv.common.feature.TestableFeature;
import com.android.tv.common.flags.has.HasUiFlags;
@@ -39,7 +42,7 @@ import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.common.util.PermissionUtils;
/**
- * List of {@link Feature} for the TV app.
+ * List of {@link Feature} for the Live TV App.
*
* <p>Remove the {@code Feature} once it is launched.
*/
@@ -48,6 +51,16 @@ public final class TvFeatures extends CommonFeatures {
/** When enabled store network affiliation information to TV provider */
public static final Feature STORE_NETWORK_AFFILIATION = ENG_ONLY_FEATURE;
+ /** When enabled use system setting for turning on analytics. */
+ public static final Feature ANALYTICS_OPT_IN =
+ ExperimentFeature.from(Experiments.ENABLE_ANALYTICS_VIA_CHECKBOX);
+ /**
+ * Analytics that include sensitive information such as channel or program identifiers.
+ *
+ * <p>See <a href="http://b/22062676">b/22062676</a>
+ */
+ public static final Feature ANALYTICS_V2 = and(ON, ANALYTICS_OPT_IN);
+
private static final Feature TV_PROVIDER_ALLOWS_INSERT_TO_PROGRAM_TABLE =
or(Sdk.AT_LEAST_O, PartnerFeatures.TVPROVIDER_ALLOWS_SYSTEM_INSERTS_TO_PROGRAM_TABLE);
@@ -74,7 +87,7 @@ public final class TvFeatures extends CommonFeatures {
or(
FlagFeature.from(
context -> HasSingletons.get(HasUiFlags.class, context),
- input -> input.getUiFlags().unhideLauncher()),
+ input -> input.getUiFlags().uhideLauncher()),
// If LC app runs as non-system app, we unhide the app.
not(PermissionUtils::hasAccessAllEpg));
@@ -101,5 +114,8 @@ public final class TvFeatures extends CommonFeatures {
/** Use input blacklist to disable partner's tuner input. */
public static final Feature USE_PARTNER_INPUT_BLACKLIST = ON;
+ @VisibleForTesting
+ public static final Feature TEST_FEATURE = PropertyFeature.create("test_feature", false);
+
private TvFeatures() {}
}
diff --git a/src/com/android/tv/guide/GenreListAdapter.java b/src/com/android/tv/guide/GenreListAdapter.java
index 995b053c..b4baf421 100644
--- a/src/com/android/tv/guide/GenreListAdapter.java
+++ b/src/com/android/tv/guide/GenreListAdapter.java
@@ -18,7 +18,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.support.annotation.MainThread;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/ProgramGrid.java b/src/com/android/tv/guide/ProgramGrid.java
index 96e161cd..caafb045 100644
--- a/src/com/android/tv/guide/ProgramGrid.java
+++ b/src/com/android/tv/guide/ProgramGrid.java
@@ -19,7 +19,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
@@ -256,19 +256,8 @@ public class ProgramGrid extends VerticalGridView {
scrollToPosition(getAdapter().getItemCount() - 1);
return null;
} else if (getSelectedPosition() == getAdapter().getItemCount() - 1) {
- int itemCount = getLayoutManager().getItemCount();
- int childCount = getChildCount();
- // b/129466363 For an item which overalps with previous layout GridLayoutManager
- // will scroll to first child of current layout, instead of going to previous one.
- // smoothscrollToPosition will invalidate all layouts and scroll to position 0.
- // This condition checks for an item which overlaps with the first layout
- if (itemCount > 2 * (childCount + 1) || itemCount <= childCount) {
- scrollToPosition(0);
- return null;
- } else {
- smoothScrollToPosition(0);
- return getChildAt(0);
- }
+ scrollToPosition(0);
+ return null;
}
return focused;
}
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index 8ae61e8a..bc1b11b6 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -32,7 +32,10 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.OnChildSelectedListener;
+import android.support.v17.leanback.widget.SearchOrbView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;
@@ -41,11 +44,6 @@ import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-
-import androidx.leanback.widget.OnChildSelectedListener;
-import androidx.leanback.widget.SearchOrbView;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.ChannelTuner;
import com.android.tv.MainActivity;
import com.android.tv.R;
@@ -67,9 +65,7 @@ import com.android.tv.ui.ViewUtils;
import com.android.tv.ui.hideable.AutoHideScheduler;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
-import com.android.tv.common.flags.UiFlags;
-
+import com.android.tv.common.flags.BackendKnobsFlags;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -116,7 +112,6 @@ public class ProgramGuide
private final int mAnimationDuration;
private final int mDetailPadding;
private final SearchOrbView mSearchOrb;
- private final UiFlags mUiFlags;
private int mCurrentTimeIndicatorWidth;
private final View mContainer;
@@ -190,14 +185,15 @@ public class ProgramGuide
mActivity = activity;
TvSingletons singletons = TvSingletons.getSingletons(mActivity);
mPerformanceMonitor = singletons.getPerformanceMonitor();
- mUiFlags = singletons.getUiFlags();
+ BackendKnobsFlags backendKnobsFlags = singletons.getBackendKnobs();
mProgramManager =
new ProgramManager(
tvInputManagerHelper,
channelDataManager,
programDataManager,
dvrDataManager,
- dvrScheduleManager);
+ dvrScheduleManager,
+ backendKnobsFlags);
mChannelTuner = channelTuner;
mTracker = tracker;
mPreShowRunnable = preShowRunnable;
@@ -265,7 +261,7 @@ public class ProgramGuide
}
});
mSidePanelGridView.setOnChildSelectedListener(
- new androidx.leanback.widget.OnChildSelectedListener() {
+ new android.support.v17.leanback.widget.OnChildSelectedListener() {
@Override
public void onChildSelected(ViewGroup viewGroup, View view, int i, long l) {
mSearchOrb.animate().alpha(i == 0 ? 1.0f : 0.0f);
@@ -286,8 +282,7 @@ public class ProgramGuide
res.getInteger(R.integer.max_recycled_view_pool_epg_header_row_item));
mTimelineRow.setAdapter(mTimeListAdapter);
- ProgramTableAdapter programTableAdapter =
- new ProgramTableAdapter(mActivity, this, mUiFlags);
+ ProgramTableAdapter programTableAdapter = new ProgramTableAdapter(mActivity, this);
programTableAdapter.registerAdapterDataObserver(
new RecyclerView.AdapterDataObserver() {
@Override
diff --git a/src/com/android/tv/guide/ProgramItemView.java b/src/com/android/tv/guide/ProgramItemView.java
index 5ec293f7..a46beab7 100644
--- a/src/com/android/tv/guide/ProgramItemView.java
+++ b/src/com/android/tv/guide/ProgramItemView.java
@@ -23,7 +23,6 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
-import android.os.Build;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -35,7 +34,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
@@ -43,22 +41,17 @@ import com.android.tv.analytics.Tracker;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.Clock;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.guide.ProgramManager.TableEntry;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
-
-import dagger.android.HasAndroidInjector;
-
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-
public class ProgramItemView extends TextView {
private static final String TAG = "ProgramItemView";
@@ -80,8 +73,8 @@ public class ProgramItemView extends TextView {
private static TextAppearanceSpan sGrayedOutEpisodeTitleStyle;
private final DvrManager mDvrManager;
- @Inject Clock mClock;
- @Inject ChannelDataManager mChannelDataManager;
+ private final Clock mClock;
+ private final ChannelDataManager mChannelDataManager;
private ProgramGuide mProgramGuide;
private TableEntry mTableEntry;
private int mMaxWidthForRipple;
@@ -209,11 +202,12 @@ public class ProgramItemView extends TextView {
public ProgramItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- ((HasAndroidInjector) context).androidInjector().inject(this);
setOnClickListener(ON_CLICKED);
setOnFocusChangeListener(ON_FOCUS_CHANGED);
TvSingletons singletons = TvSingletons.getSingletons(getContext());
mDvrManager = singletons.getDvrManager();
+ mChannelDataManager = singletons.getChannelDataManager();
+ mClock = singletons.getClock();
}
private void initIfNeeded() {
@@ -536,9 +530,6 @@ public class ProgramItemView extends TextView {
}
private static int getStateCount(StateListDrawable stateListDrawable) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return stateListDrawable.getStateCount();
- }
try {
Object stateCount =
StateListDrawable.class
@@ -555,9 +546,6 @@ public class ProgramItemView extends TextView {
}
private static Drawable getStateDrawable(StateListDrawable stateListDrawable, int index) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return stateListDrawable.getStateDrawable(index);
- }
try {
Object drawable =
StateListDrawable.class
diff --git a/src/com/android/tv/guide/ProgramListAdapter.java b/src/com/android/tv/guide/ProgramListAdapter.java
index 68ae43ee..397bacfb 100644
--- a/src/com/android/tv/guide/ProgramListAdapter.java
+++ b/src/com/android/tv/guide/ProgramListAdapter.java
@@ -17,7 +17,7 @@
package com.android.tv.guide;
import android.content.res.Resources;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/ProgramManager.java b/src/com/android/tv/guide/ProgramManager.java
index 516a4d9c..3a5a4a02 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -21,20 +21,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
-
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.GenreItems;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.data.ProgramImpl;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrScheduleManager.OnConflictStateChangeListener;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
+import com.android.tv.common.flags.BackendKnobsFlags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -62,6 +60,7 @@ public class ProgramManager {
private final ProgramDataManager mProgramDataManager;
private final DvrDataManager mDvrDataManager; // Only set if DVR is enabled
private final DvrScheduleManager mDvrScheduleManager;
+ private final BackendKnobsFlags mBackendKnobsFlags;
private long mStartUtcMillis;
private long mEndUtcMillis;
@@ -125,8 +124,16 @@ public class ProgramManager {
}
@Override
- public void onChannelUpdated() {
- updateTableEntriesWithoutNotification(false);
+ public void onSingleChannelUpdated(long channelId) {
+ boolean parentalControlsEnabled =
+ mTvInputManagerHelper
+ .getParentalControlSettings()
+ .isParentalControlsEnabled();
+ // Inline the updating of the mChannelIdEntriesMap here so we can only call
+ // getParentalControlSettings once.
+ List<TableEntry> entries =
+ createProgramEntries(channelId, parentalControlsEnabled);
+ mChannelIdEntriesMap.put(channelId, entries);
notifyTableEntriesUpdated();
}
};
@@ -208,12 +215,14 @@ public class ProgramManager {
ChannelDataManager channelDataManager,
ProgramDataManager programDataManager,
@Nullable DvrDataManager dvrDataManager,
- @Nullable DvrScheduleManager dvrScheduleManager) {
+ @Nullable DvrScheduleManager dvrScheduleManager,
+ BackendKnobsFlags backendKnobsFlags) {
mTvInputManagerHelper = tvInputManagerHelper;
mChannelDataManager = channelDataManager;
mProgramDataManager = programDataManager;
mDvrDataManager = dvrDataManager;
mDvrScheduleManager = dvrScheduleManager;
+ mBackendKnobsFlags = backendKnobsFlags;
}
void programGuideVisibilityChanged(boolean visible) {
@@ -242,6 +251,7 @@ public class ProgramManager {
mDvrScheduleManager.removeOnConflictStateChangeListener(
mOnConflictStateChangeListener);
}
+ mChannelIdEntriesMap.clear();
}
}
@@ -416,12 +426,14 @@ public class ProgramManager {
}
/**
- * Returns an entry as {@link ProgramImpl} for a given {@code channelId} and {@code index} of
- * entries within the currently managed time range. Returned {@link ProgramImpl} can be a dummy
- * one (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
+ * Returns an entry as {@link Program} for a given {@code channelId} and {@code index} of
+ * entries within the currently managed time range. Returned {@link Program} can be a dummy one
+ * (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
*/
TableEntry getTableEntry(long channelId, int index) {
- mProgramDataManager.prefetchChannel(channelId, index);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ mProgramDataManager.prefetchChannel(channelId);
+ }
return mChannelIdEntriesMap.get(channelId).get(index);
}
@@ -695,7 +707,7 @@ public class ProgramManager {
/**
* Entry for program guide table. An "entry" can be either an actual program or a gap between
* programs. This is needed for {@link ProgramListAdapter} because {@link
- * androidx.leanback.widget.HorizontalGridView} ignores margins between items.
+ * android.support.v17.leanback.widget.HorizontalGridView} ignores margins between items.
*/
static class TableEntry {
/** Channel ID which this entry is included. */
@@ -725,7 +737,7 @@ public class ProgramManager {
private TableEntry(
long channelId,
- ProgramImpl program,
+ Program program,
long entryStartUtcMillis,
long entryEndUtcMillis,
boolean isBlocked) {
@@ -747,7 +759,7 @@ public class ProgramManager {
mIsBlocked = isBlocked;
}
- /** A stable id useful for {@link androidx.recyclerview.widget.RecyclerView.Adapter}. */
+ /** A stable id useful for {@link android.support.v7.widget.RecyclerView.Adapter}. */
long getId() {
// using a negative entryEndUtcMillis keeps it from conflicting with program Id
return program != null ? program.getId() : -entryEndUtcMillis;
diff --git a/src/com/android/tv/guide/ProgramRow.java b/src/com/android/tv/guide/ProgramRow.java
index 6f8f31c1..3317c15f 100644
--- a/src/com/android/tv/guide/ProgramRow.java
+++ b/src/com/android/tv/guide/ProgramRow.java
@@ -18,7 +18,7 @@ package com.android.tv.guide;
import android.content.Context;
import android.graphics.Rect;
-import androidx.recyclerview.widget.LinearLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
diff --git a/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java b/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
index a6a4624b..5e498be4 100644
--- a/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
+++ b/src/com/android/tv/guide/ProgramRowAccessibilityDelegate.java
@@ -17,8 +17,8 @@
package com.android.tv.guide;
import android.os.Bundle;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerViewAccessibilityDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
diff --git a/src/com/android/tv/guide/ProgramTableAdapter.java b/src/com/android/tv/guide/ProgramTableAdapter.java
index aed8b900..7576bf50 100644
--- a/src/com/android/tv/guide/ProgramTableAdapter.java
+++ b/src/com/android/tv/guide/ProgramTableAdapter.java
@@ -28,8 +28,8 @@ import android.media.tv.TvInputInfo;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.RecycledViewPool;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.RecycledViewPool;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
@@ -47,14 +47,13 @@ import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeL
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
+import com.android.tv.data.Program;
+import com.android.tv.data.Program.CriticScore;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-import com.android.tv.data.api.Program.CriticScore;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
@@ -68,8 +67,6 @@ import com.android.tv.util.images.ImageLoader;
import com.android.tv.util.images.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.images.ImageLoader.LoadTvInputLogoTask;
-import com.android.tv.common.flags.UiFlags;
-
import java.util.ArrayList;
import java.util.List;
@@ -112,11 +109,10 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
private final String mRecordingInProgressText;
private final int mDvrPaddingStartWithTrack;
private final int mDvrPaddingStartWithOutTrack;
- private final UiFlags mUiFlags;
private RecyclerView mRecyclerView;
- ProgramTableAdapter(Context context, ProgramGuide programGuide, UiFlags uiFlags) {
+ ProgramTableAdapter(Context context, ProgramGuide programGuide) {
mContext = context;
mAccessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -130,7 +126,6 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
}
mProgramGuide = programGuide;
mProgramManager = programGuide.getProgramManager();
- mUiFlags = uiFlags;
Resources res = context.getResources();
mChannelLogoWidth =
@@ -661,35 +656,6 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
mDvrIndicator.setVisibility(View.GONE);
}
- if (mUiFlags.enableCriticRatings()) {
- // display critic scores if any exist
- List<CriticScore> criticScores = program.getCriticScores();
- if (criticScores != null) {
- // inflate more critic score views if required
- if (criticScores.size() > mCriticScoreViews.size()) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- LinearLayout layout =
- (LinearLayout)
- inflater.inflate(
- R.layout.program_guide_critic_score_layout,
- null);
- mCriticScoreViews.add(layout);
- }
- // fill critic score views and add to layout
- for (int i = 0; i < criticScores.size(); i++) {
- View criticScoreView = mCriticScoreViews.get(i);
- ViewParent previousParentView = criticScoreView.getParent();
- if (previousParentView != null
- && previousParentView instanceof ViewGroup) {
- ((ViewGroup) previousParentView).removeView(criticScoreView);
- }
- updateCriticScoreView(
- this, program.getId(), criticScores.get(i), criticScoreView);
- mCriticScoresLayout.addView(mCriticScoreViews.get(i));
- }
- }
- }
-
if (blockedRating == null) {
mBlockView.setVisibility(View.GONE);
updateTextView(mDescriptionView, program.getDescription());
diff --git a/src/com/android/tv/guide/TimeListAdapter.java b/src/com/android/tv/guide/TimeListAdapter.java
index 62fec69a..9c10c952 100644
--- a/src/com/android/tv/guide/TimeListAdapter.java
+++ b/src/com/android/tv/guide/TimeListAdapter.java
@@ -17,7 +17,7 @@
package com.android.tv.guide;
import android.content.res.Resources;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/guide/TimelineGridView.java b/src/com/android/tv/guide/TimelineGridView.java
index 2d257878..c4922b75 100644
--- a/src/com/android/tv/guide/TimelineGridView.java
+++ b/src/com/android/tv/guide/TimelineGridView.java
@@ -17,8 +17,8 @@
package com.android.tv.guide;
import android.content.Context;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
diff --git a/src/com/android/tv/menu/ActionCardView.java b/src/com/android/tv/menu/ActionCardView.java
index 0e789c67..3ecd5f5c 100644
--- a/src/com/android/tv/menu/ActionCardView.java
+++ b/src/com/android/tv/menu/ActionCardView.java
@@ -19,7 +19,6 @@ package com.android.tv.menu;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -94,13 +93,6 @@ public class ActionCardView extends RelativeLayout implements ItemListRowView.Ca
}
}
- /** Request focus and accessibility focus on card view. */
- @Override
- public boolean requestFocusWithAccessibility() {
- return requestFocus() &&
- performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
-
@Override
public void onRecycled() {}
}
diff --git a/src/com/android/tv/menu/AppLinkCardView.java b/src/com/android/tv/menu/AppLinkCardView.java
index 49d32fed..fd93c314 100644
--- a/src/com/android/tv/menu/AppLinkCardView.java
+++ b/src/com/android/tv/menu/AppLinkCardView.java
@@ -26,13 +26,13 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
-import androidx.palette.graphics.Palette;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.data.api.Channel;
diff --git a/src/com/android/tv/menu/BaseCardView.java b/src/com/android/tv/menu/BaseCardView.java
index ed78cb73..3a94ebbf 100644
--- a/src/com/android/tv/menu/BaseCardView.java
+++ b/src/com/android/tv/menu/BaseCardView.java
@@ -27,7 +27,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
@@ -136,13 +135,6 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
}
}
- /** Request focus and accessibility focus on card view. */
- @Override
- public boolean requestFocusWithAccessibility() {
- return requestFocus() &&
- performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
-
/** Sets text of this card view. */
public void setText(int resId) {
if (mTextResId != resId) {
diff --git a/src/com/android/tv/menu/ChannelCardView.java b/src/com/android/tv/menu/ChannelCardView.java
index 7fe5e491..76056ee4 100644
--- a/src/com/android/tv/menu/ChannelCardView.java
+++ b/src/com/android/tv/menu/ChannelCardView.java
@@ -26,14 +26,12 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.images.ImageLoader;
-
import java.util.Objects;
/** A view to render channel card. */
diff --git a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
index 3a502304..9cecb9c0 100644
--- a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
+++ b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
@@ -23,15 +23,13 @@ import android.os.Message;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.util.Log;
-
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.util.List;
/** A poster image prefetcher to show the program poster art in the Channels row faster. */
diff --git a/src/com/android/tv/menu/ChannelsRow.java b/src/com/android/tv/menu/ChannelsRow.java
index dbfc7820..7d03bf2b 100644
--- a/src/com/android/tv/menu/ChannelsRow.java
+++ b/src/com/android/tv/menu/ChannelsRow.java
@@ -73,7 +73,6 @@ public class ChannelsRow extends ItemListRow {
mTvRecommendation = null;
}
mChannelsPosterPrefetcher.cancel();
- mChannelsAdapter.release();
}
/** Handle the update event of the recent channel. */
diff --git a/src/com/android/tv/menu/ChannelsRowAdapter.java b/src/com/android/tv/menu/ChannelsRowAdapter.java
index e6b61037..4a9e4765 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -47,7 +47,6 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
private final int mMaxCount;
private final int mMinCount;
private final ChannelChanger mChannelChanger;
- private final AccessibilityManager mAccessibilityManager;
private boolean mShowChannelUpDown;
@@ -67,9 +66,10 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
mMaxCount = maxCount;
setHasStableIds(true);
mChannelChanger = (ChannelChanger) (context);
- mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
- mShowChannelUpDown = mAccessibilityManager.isEnabled();
- mAccessibilityManager.addAccessibilityStateChangeListener(this);
+ AccessibilityManager accessibilityManager =
+ context.getSystemService(AccessibilityManager.class);
+ mShowChannelUpDown = accessibilityManager.isEnabled();
+ accessibilityManager.addAccessibilityStateChangeListener(this);
}
@Override
@@ -316,10 +316,4 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
mShowChannelUpDown = enabled;
update();
}
-
- @Override
- public void release() {
- mAccessibilityManager.removeAccessibilityStateChangeListener(this);
- super.release();
- }
}
diff --git a/src/com/android/tv/menu/ItemListRowView.java b/src/com/android/tv/menu/ItemListRowView.java
index cc6d23c3..7042324d 100644
--- a/src/com/android/tv/menu/ItemListRowView.java
+++ b/src/com/android/tv/menu/ItemListRowView.java
@@ -17,9 +17,9 @@
package com.android.tv.menu;
import android.content.Context;
-import androidx.leanback.widget.HorizontalGridView;
-import androidx.leanback.widget.OnChildSelectedListener;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.HorizontalGridView;
+import android.support.v17.leanback.widget.OnChildSelectedListener;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
@@ -44,8 +44,6 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
void onSelected();
void onDeselected();
-
- boolean requestFocusWithAccessibility();
}
private HorizontalGridView mListView;
@@ -116,13 +114,6 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
}
}
- @Override
- protected void requestChildFocus() {
- if (mSelectedCard != null) {
- mSelectedCard.requestFocusWithAccessibility();
- }
- }
-
public abstract static class ItemListAdapter<T>
extends RecyclerView.Adapter<ItemListAdapter.MyViewHolder> {
private final MainActivity mMainActivity;
diff --git a/src/com/android/tv/menu/Menu.java b/src/com/android/tv/menu/Menu.java
index 0687441e..6bdbf87b 100644
--- a/src/com/android/tv/menu/Menu.java
+++ b/src/com/android/tv/menu/Menu.java
@@ -23,7 +23,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
-import androidx.leanback.widget.HorizontalGridView;
+import android.support.v17.leanback.widget.HorizontalGridView;
import android.util.Log;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import com.android.tv.ChannelTuner;
diff --git a/src/com/android/tv/menu/MenuLayoutManager.java b/src/com/android/tv/menu/MenuLayoutManager.java
index 8f95db77..a600f704 100644
--- a/src/com/android/tv/menu/MenuLayoutManager.java
+++ b/src/com/android/tv/menu/MenuLayoutManager.java
@@ -25,15 +25,15 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.support.annotation.UiThread;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v4.view.animation.FastOutLinearInInterpolator;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
+import android.support.v4.view.animation.LinearOutSlowInInterpolator;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.Property;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.TextView;
-import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
-import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
-import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.util.Utils;
diff --git a/src/com/android/tv/menu/MenuRow.java b/src/com/android/tv/menu/MenuRow.java
index 0945a0c5..8dc12bad 100644
--- a/src/com/android/tv/menu/MenuRow.java
+++ b/src/com/android/tv/menu/MenuRow.java
@@ -31,8 +31,6 @@ public abstract class MenuRow {
private MenuRowView mMenuRowView;
- private boolean mIsReselected = false;
-
// TODO: Check if the heightResId is really necessary.
public MenuRow(Context context, Menu menu, int titleResId, int heightResId) {
this(context, menu, context.getString(titleResId), heightResId);
@@ -102,19 +100,4 @@ public abstract class MenuRow {
public boolean hideTitleWhenSelected() {
return false;
}
-
- /**
- * Sets if menu row is reselected.
- *
- * @param isReselected {@code true} if row is reselected;
- * else {@code false}.
- */
- public void setIsReselected(boolean isReselected) {
- mIsReselected = isReselected;
- }
-
- /** Returns true if row is reselected. */
- public boolean isReselected() {
- return mIsReselected;
- }
}
diff --git a/src/com/android/tv/menu/MenuRowFactory.java b/src/com/android/tv/menu/MenuRowFactory.java
index a3837a10..048d725d 100644
--- a/src/com/android/tv/menu/MenuRowFactory.java
+++ b/src/com/android/tv/menu/MenuRowFactory.java
@@ -24,7 +24,6 @@ import com.android.tv.R;
import com.android.tv.common.customization.CustomAction;
import com.android.tv.common.customization.CustomizationManager;
import com.android.tv.ui.TunableTvView;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.List;
/** A factory class to create menu rows. */
@@ -32,15 +31,12 @@ public class MenuRowFactory {
private final MainActivity mMainActivity;
private final TunableTvView mTvView;
private final CustomizationManager mCustomizationManager;
- private final LegacyFlags mLegacyFlags;
/** A constructor. */
- public MenuRowFactory(
- MainActivity mainActivity, TunableTvView tvView, LegacyFlags mLegacyFlags) {
+ public MenuRowFactory(MainActivity mainActivity, TunableTvView tvView) {
mMainActivity = mainActivity;
mTvView = tvView;
mCustomizationManager = new CustomizationManager(mainActivity);
- this.mLegacyFlags = mLegacyFlags;
mCustomizationManager.initialize();
}
@@ -64,8 +60,7 @@ public class MenuRowFactory {
return new TvOptionsRow(
mMainActivity,
menu,
- mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW),
- mLegacyFlags);
+ mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW));
}
return null;
}
@@ -75,17 +70,13 @@ public class MenuRowFactory {
/** The ID of the row. */
public static final String ID = TvOptionsRow.class.getName();
- private TvOptionsRow(
- Context context,
- Menu menu,
- List<CustomAction> customActions,
- LegacyFlags legacyFlags) {
+ private TvOptionsRow(Context context, Menu menu, List<CustomAction> customActions) {
super(
context,
menu,
R.string.menu_title_options,
R.dimen.action_card_height,
- new TvOptionsRowAdapter(context, customActions, legacyFlags));
+ new TvOptionsRowAdapter(context, customActions));
}
}
diff --git a/src/com/android/tv/menu/MenuRowView.java b/src/com/android/tv/menu/MenuRowView.java
index e09a4ef0..a064f352 100644
--- a/src/com/android/tv/menu/MenuRowView.java
+++ b/src/com/android/tv/menu/MenuRowView.java
@@ -25,7 +25,6 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
@@ -90,18 +89,6 @@ public abstract class MenuRowView extends LinearLayout {
float textSizeDeselected =
res.getDimensionPixelSize(R.dimen.menu_row_title_text_size_deselected);
mTitleViewScaleSelected = textSizeSelected / textSizeDeselected;
- this.setAccessibilityDelegate(
- new AccessibilityDelegate() {
- @Override
- public void sendAccessibilityEvent(View host, int eventType) {
- super.sendAccessibilityEvent(host, eventType);
- if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED &&
- !mRow.isReselected()) {
- requestChildFocus();
- }
- }
- }
- );
}
@Override
@@ -190,9 +177,6 @@ public abstract class MenuRowView extends LinearLayout {
mLastFocusView = v;
}
- /** Subclasses should implement this to request focus on child. */
- protected abstract void requestChildFocus();
-
/**
* Called when the focus of a child view is changed. The inherited class should override this
* method instead of calling {@link
diff --git a/src/com/android/tv/menu/MenuView.java b/src/com/android/tv/menu/MenuView.java
index add4a774..f5fec000 100644
--- a/src/com/android/tv/menu/MenuView.java
+++ b/src/com/android/tv/menu/MenuView.java
@@ -250,40 +250,39 @@ public class MenuView extends FrameLayout implements IMenuView {
// The bounds of the views move and overlap with each other during the animation. In this
// situation, the framework can't perform the correct focus navigation. So the menu view
// should search by itself.
- if (direction == View.FOCUS_UP || direction == View.FOCUS_DOWN) {
- return getUpDownFocus(focused, direction);
- }
- return super.focusSearch(focused, direction);
- }
-
- private View getUpDownFocus(View focused, int direction) {
- View newView = super.focusSearch(focused, direction);
- MenuRowView oldfocusedParent = getParentMenuRowView(focused);
- MenuRowView newFocusedParent = getParentMenuRowView(newView);
- int selectedPosition = mLayoutManager.getSelectedPosition();
- int start, delta;
if (direction == View.FOCUS_UP) {
- start = selectedPosition - 1;
- delta = -1;
- } else {
- start = selectedPosition + 1;
- delta = 1;
- }
- if (newFocusedParent != oldfocusedParent) {
- // The focus leaves from the current menu row view.
- int count = mMenuRowViews.size();
- int i = start;
- while (i < count && i >= 0) {
- MenuRowView view = mMenuRowViews.get(i);
- if (view.getVisibility() == View.VISIBLE) {
- mMenuRows.get(i).setIsReselected(false);
- return view;
+ View newView = super.focusSearch(focused, direction);
+ MenuRowView oldfocusedParent = getParentMenuRowView(focused);
+ MenuRowView newFocusedParent = getParentMenuRowView(newView);
+ int selectedPosition = mLayoutManager.getSelectedPosition();
+ if (newFocusedParent != oldfocusedParent) {
+ // The focus leaves from the current menu row view.
+ for (int i = selectedPosition - 1; i >= 0; --i) {
+ MenuRowView view = mMenuRowViews.get(i);
+ if (view.getVisibility() == View.VISIBLE) {
+ return view;
+ }
+ }
+ }
+ return newView;
+ } else if (direction == View.FOCUS_DOWN) {
+ View newView = super.focusSearch(focused, direction);
+ MenuRowView oldfocusedParent = getParentMenuRowView(focused);
+ MenuRowView newFocusedParent = getParentMenuRowView(newView);
+ int selectedPosition = mLayoutManager.getSelectedPosition();
+ if (newFocusedParent != oldfocusedParent) {
+ // The focus leaves from the current menu row view.
+ int count = mMenuRowViews.size();
+ for (int i = selectedPosition + 1; i < count; ++i) {
+ MenuRowView view = mMenuRowViews.get(i);
+ if (view.getVisibility() == View.VISIBLE) {
+ return view;
+ }
}
- i += delta;
}
+ return newView;
}
- mMenuRows.get(selectedPosition).setIsReselected(true);
- return newView;
+ return super.focusSearch(focused, direction);
}
private MenuRowView getParentMenuRowView(View view) {
diff --git a/src/com/android/tv/menu/PlayControlsButton.java b/src/com/android/tv/menu/PlayControlsButton.java
index 1b85d632..ac3292a3 100644
--- a/src/com/android/tv/menu/PlayControlsButton.java
+++ b/src/com/android/tv/menu/PlayControlsButton.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -147,11 +146,4 @@ public class PlayControlsButton extends FrameLayout {
mIcon.setAlpha(enabled ? ALPHA_ENABLED : ALPHA_DISABLED);
mLabel.setEnabled(enabled);
}
-
- /** Request focus and accessibility focus to the button */
- public boolean requestFocusWithAccessibility() {
- return mButton.requestFocus() &&
- mButton.performAccessibilityAction(
- AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
- }
}
diff --git a/src/com/android/tv/menu/PlayControlsRowView.java b/src/com/android/tv/menu/PlayControlsRowView.java
index 5dde3be0..0ce74ae1 100644
--- a/src/com/android/tv/menu/PlayControlsRowView.java
+++ b/src/com/android/tv/menu/PlayControlsRowView.java
@@ -24,7 +24,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TimeShiftManager;
@@ -32,8 +31,8 @@ import com.android.tv.TimeShiftManager.TimeShiftActionId;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
@@ -488,11 +487,6 @@ public class PlayControlsRowView extends MenuRowView {
}
}
- @Override
- protected void requestChildFocus() {
- mPlayPauseButton.requestFocusWithAccessibility();
- }
-
/** Updates the view contents. It is called from the PlayControlsRow. */
public void update() {
updateAll(false);
diff --git a/src/com/android/tv/menu/TvOptionsRowAdapter.java b/src/com/android/tv/menu/TvOptionsRowAdapter.java
index 418560a8..fe52b25e 100644
--- a/src/com/android/tv/menu/TvOptionsRowAdapter.java
+++ b/src/com/android/tv/menu/TvOptionsRowAdapter.java
@@ -19,8 +19,8 @@ package com.android.tv.menu;
import android.content.Context;
import android.media.tv.TvTrackInfo;
import com.android.tv.TvOptionsManager;
-import com.android.tv.common.BuildConfig;
import com.android.tv.common.customization.CustomAction;
+import com.android.tv.common.util.CommonUtils;
import com.android.tv.data.DisplayMode;
import com.android.tv.features.TvFeatures;
import com.android.tv.ui.TvViewUiManager;
@@ -28,7 +28,6 @@ import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.List;
@@ -36,12 +35,8 @@ import java.util.List;
* An adapter of options.
*/
public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
- private final LegacyFlags mLegacyFlags;
-
- public TvOptionsRowAdapter(
- Context context, List<CustomAction> customActions, LegacyFlags mLegacyFlags) {
+ public TvOptionsRowAdapter(Context context, List<CustomAction> customActions) {
super(context, customActions);
- this.mLegacyFlags = mLegacyFlags;
}
@Override
@@ -54,7 +49,7 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
}
actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
actionList.add(MenuAction.MORE_CHANNELS_ACTION);
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
actionList.add(MenuAction.DEV_ACTION);
}
actionList.add(MenuAction.SETTINGS_ACTION);
diff --git a/src/com/android/tv/modules/TvApplicationModule.java b/src/com/android/tv/modules/TvApplicationModule.java
index 99753d1e..45383ae1 100644
--- a/src/com/android/tv/modules/TvApplicationModule.java
+++ b/src/com/android/tv/modules/TvApplicationModule.java
@@ -16,101 +16,43 @@
package com.android.tv.modules;
import android.content.Context;
-
import com.android.tv.MainActivity;
-import com.android.tv.SetupPassthroughActivity;
import com.android.tv.TvApplication;
-import com.android.tv.common.buildtype.BuildTypeModule;
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.common.dagger.ApplicationModule;
import com.android.tv.common.dagger.annotations.ApplicationContext;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ChannelDataManagerFactory;
-import com.android.tv.data.epg.EpgFetchService;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.data.epg.EpgFetcherImpl;
-import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrDataManagerImpl;
-import com.android.tv.dvr.WritableDvrDataManager;
-import com.android.tv.dvr.ui.playback.DvrPlaybackActivity;
import com.android.tv.onboarding.OnboardingActivity;
-import com.android.tv.onboarding.SetupSourcesFragment;
-import com.android.tv.setup.SystemSetupActivity;
-import com.android.tv.ui.DetailsActivity;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TvInputManagerHelper;
-
-import dagger.Binds;
import dagger.Module;
import dagger.Provides;
-import dagger.android.ContributesAndroidInjector;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-
import javax.inject.Singleton;
/** Dagger module for {@link TvApplication}. */
@Module(
includes = {
ApplicationModule.class,
- BuildTypeModule.class,
- DetailsActivity.Module.class,
- DvrPlaybackActivity.Module.class,
- MainActivity.Module.class,
- OnboardingActivity.Module.class,
- SetupPassthroughActivity.Module.class,
- SetupSourcesFragment.ContentFragment.Module.class,
- SystemSetupActivity.Module.class,
TvSingletonsModule.class,
+ MainActivity.Module.class,
+ OnboardingActivity.Module.class
})
-public abstract class TvApplicationModule {
+public class TvApplicationModule {
private static final NamedThreadFactory THREAD_FACTORY = new NamedThreadFactory("tv-app-db");
@Provides
@AsyncDbTask.DbExecutor
@Singleton
- static Executor providesDbExecutor() {
+ Executor providesDbExecutor() {
return Executors.newSingleThreadExecutor(THREAD_FACTORY);
}
@Provides
@Singleton
- static TvInputManagerHelper providesTvInputManagerHelper(
- @ApplicationContext Context context, LegacyFlags legacyFlags) {
- TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context, legacyFlags);
+ TvInputManagerHelper providesTvInputManagerHelper(@ApplicationContext Context context) {
+ TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context);
tvInputManagerHelper.start();
- // Since this is injected as a Lazy in the application start is delayed.
return tvInputManagerHelper;
}
-
- @Provides
- @Singleton
- static ChannelDataManager providesChannelDataManager(ChannelDataManagerFactory factory) {
- ChannelDataManager channelDataManager = factory.create();
- channelDataManager.start();
- // Since this is injected as a Lazy in the application start is delayed.
- return channelDataManager;
- }
-
- @Binds
- @Singleton
- abstract DvrDataManager providesDvrDataManager(DvrDataManagerImpl impl);
-
- @Binds
- @Singleton
- abstract WritableDvrDataManager providesWritableDvrDataManager(DvrDataManagerImpl impl);
-
- @Binds
- @Singleton
- abstract EpgFetcher epgFetcher(EpgFetcherImpl impl);
-
- @ContributesAndroidInjector
- abstract PinDialogFragment contributesPinDialogFragment();
-
- @ContributesAndroidInjector
- abstract EpgFetchService contributesEpgFetchService();
}
diff --git a/src/com/android/tv/modules/TvSingletonsModule.java b/src/com/android/tv/modules/TvSingletonsModule.java
index f8d10fde..f998c08b 100644
--- a/src/com/android/tv/modules/TvSingletonsModule.java
+++ b/src/com/android/tv/modules/TvSingletonsModule.java
@@ -16,9 +16,8 @@
package com.android.tv.modules;
import com.android.tv.TvSingletons;
+import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-
import dagger.Module;
import dagger.Provides;
@@ -37,8 +36,8 @@ public class TvSingletonsModule {
}
@Provides
- DvrWatchedPositionManager providesDvrWatchedPositionManager() {
- return mTvSingletons.getDvrWatchedPositionManager();
+ ChannelDataManager providesChannelDataManager() {
+ return mTvSingletons.getChannelDataManager();
}
@Provides
diff --git a/src/com/android/tv/onboarding/OnboardingActivity.java b/src/com/android/tv/onboarding/OnboardingActivity.java
index 1739e5a0..776ae664 100644
--- a/src/com/android/tv/onboarding/OnboardingActivity.java
+++ b/src/com/android/tv/onboarding/OnboardingActivity.java
@@ -88,7 +88,7 @@ public class OnboardingActivity extends SetupActivity {
TvSingletons singletons = TvSingletons.getSingletons(this);
mInputManager = singletons.getTvInputManagerHelper();
if (PermissionUtils.hasAccessAllEpg(this) || PermissionUtils.hasReadTvListings(this)) {
- // Make the channels of the new inputs which have been setup outside TV app
+ // Make the channels of the new inputs which have been setup outside Live TV
// browsable.
if (mChannelDataManager.isDbLoadFinished()) {
mSetupUtils.markNewChannelsBrowsable();
@@ -187,7 +187,7 @@ public class OnboardingActivity extends SetupActivity {
}
// Even though other app can handle the intent, the setup launched by
// Live
- // channels should go through TV app SetupPassthroughActivity.
+ // channels should go through Live channels SetupPassthroughActivity.
intent.setComponent(
new ComponentName(this, SetupPassthroughActivity.class));
try {
diff --git a/src/com/android/tv/onboarding/SetupSourcesFragment.java b/src/com/android/tv/onboarding/SetupSourcesFragment.java
index b54d1bc9..3566c9c3 100644
--- a/src/com/android/tv/onboarding/SetupSourcesFragment.java
+++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java
@@ -16,44 +16,33 @@
package com.android.tv.onboarding;
-import android.app.Activity;
+import android.content.Context;
import android.graphics.Typeface;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager.TvInputCallback;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-
-import androidx.leanback.widget.GuidanceStylist.Guidance;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.TvInputNewComparator;
-import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
import com.android.tv.ui.GuidedActionsStylistWithDivider;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-
-import com.google.common.base.Optional;
-
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import javax.inject.Inject;
-
/** A fragment for channel source info/setup. */
public class SetupSourcesFragment extends SetupMultiPaneFragment {
/** The action category for the actions which is fired from this fragment. */
@@ -117,10 +106,9 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
private static final int PENDING_ACTION_INPUT_CHANGED = 1;
private static final int PENDING_ACTION_CHANNEL_CHANGED = 2;
- @Inject TvInputManagerHelper mInputManager;
- @Inject ChannelDataManager mChannelDataManager;
- @Inject SetupUtils mSetupUtils;
- @Inject Optional<BuiltInTunerManager> mBuiltInTunerManagerOptional;
+ private TvInputManagerHelper mInputManager;
+ private ChannelDataManager mChannelDataManager;
+ private SetupUtils mSetupUtils;
private List<TvInputInfo> mInputs;
private int mKnownInputStartIndex;
private int mDoneInputStartIndex;
@@ -199,38 +187,37 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mParentFragment = (SetupSourcesFragment) getParentFragment();
- }
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
+ Context context = getActivity();
+ TvSingletons singletons = TvSingletons.getSingletons(context);
+ mInputManager = singletons.getTvInputManagerHelper();
+ mChannelDataManager = singletons.getChannelDataManager();
+ mSetupUtils = singletons.getSetupUtils();
buildInputs();
mInputManager.addCallback(mInputCallback);
mChannelDataManager.addListener(mChannelDataManagerListener);
+ super.onCreate(savedInstanceState);
mParentFragment = (SetupSourcesFragment) getParentFragment();
- if (mBuiltInTunerManagerOptional.isPresent()) {
- mBuiltInTunerManagerOptional
+ if (singletons.getBuiltInTunerManager().isPresent()) {
+ singletons
+ .getBuiltInTunerManager()
.get()
.getTunerInputController()
- .executeNetworkTunerDiscoveryAsyncTask(activity);
+ .executeNetworkTunerDiscoveryAsyncTask(getContext());
}
}
@Override
- public void onDetach() {
+ public void onDestroy() {
+ super.onDestroy();
mChannelDataManager.removeListener(mChannelDataManagerListener);
mInputManager.removeCallback(mInputCallback);
- super.onDetach();
}
@NonNull
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
String title = getString(R.string.setup_sources_text);
- String description = getString(R.string.setup_sources_description2);
+ String description = getString(R.string.setup_sources_description);
return new Guidance(title, description, null, null);
}
@@ -417,13 +404,5 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
setAccessibilityDelegate(vh, action);
}
}
- /**
- * Exports {@link ContentFragment} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract ContentFragment contributesContentFragment();
- }
}
}
diff --git a/src/com/android/tv/onboarding/WelcomeFragment.java b/src/com/android/tv/onboarding/WelcomeFragment.java
index 667da058..8c119a8a 100644
--- a/src/com/android/tv/onboarding/WelcomeFragment.java
+++ b/src/com/android/tv/onboarding/WelcomeFragment.java
@@ -25,7 +25,7 @@ import android.animation.AnimatorSet;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import androidx.leanback.app.OnboardingFragment;
+import android.support.v17.leanback.app.OnboardingFragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
@@ -621,9 +621,9 @@ public class WelcomeFragment extends OnboardingFragment {
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
setLogoResourceId(R.drawable.splash_logo);
- mTitleView = view.findViewById(androidx.leanback.R.id.title);
- mPagingIndicator = view.findViewById(androidx.leanback.R.id.page_indicator);
- mStartButton = view.findViewById(androidx.leanback.R.id.button_start);
+ mTitleView = view.findViewById(android.support.v17.leanback.R.id.title);
+ mPagingIndicator = view.findViewById(android.support.v17.leanback.R.id.page_indicator);
+ mStartButton = view.findViewById(android.support.v17.leanback.R.id.button_start);
mStartButton.setAccessibilityDelegate(
new AccessibilityDelegate() {
diff --git a/src/com/android/tv/parental/ContentRatingsManager.java b/src/com/android/tv/parental/ContentRatingsManager.java
index 174039ba..32a1325b 100644
--- a/src/com/android/tv/parental/ContentRatingsManager.java
+++ b/src/com/android/tv/parental/ContentRatingsManager.java
@@ -22,7 +22,6 @@ import android.media.tv.TvContentRatingSystemInfo;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.android.tv.R;
-import com.android.tv.common.util.PermissionUtils;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import com.android.tv.util.TvInputManagerHelper;
@@ -43,14 +42,13 @@ public class ContentRatingsManager {
public void update() {
mContentRatingSystems.clear();
- if (PermissionUtils.hasReadContetnRatingSystem(mContext)) {
- ContentRatingsParser parser = new ContentRatingsParser(mContext);
- List<TvContentRatingSystemInfo> infos = mTvInputManager.getTvContentRatingSystemList();
- for (TvContentRatingSystemInfo info : infos) {
- List<ContentRatingSystem> list = parser.parse(info);
- if (list != null) {
- mContentRatingSystems.addAll(list);
- }
+ ContentRatingsParser parser = new ContentRatingsParser(mContext);
+
+ List<TvContentRatingSystemInfo> infos = mTvInputManager.getTvContentRatingSystemList();
+ for (TvContentRatingSystemInfo info : infos) {
+ List<ContentRatingSystem> list = parser.parse(info);
+ if (list != null) {
+ mContentRatingSystems.addAll(list);
}
}
}
diff --git a/src/com/android/tv/parental/ParentalControlSettings.java b/src/com/android/tv/parental/ParentalControlSettings.java
index 9990ae35..b41b160e 100644
--- a/src/com/android/tv/parental/ParentalControlSettings.java
+++ b/src/com/android/tv/parental/ParentalControlSettings.java
@@ -19,12 +19,12 @@ package com.android.tv.parental;
import android.content.Context;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvSettings.ContentRatingLevel;
import com.google.common.collect.ImmutableList;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.HashSet;
import java.util.Set;
@@ -40,16 +40,14 @@ public class ParentalControlSettings {
private final Context mContext;
private final TvInputManager mTvInputManager;
- private final LegacyFlags mLegacyFlags;
// mRatings is expected to be synchronized with mTvInputManager.getBlockedRatings().
private Set<TvContentRating> mRatings;
private Set<TvContentRating> mCustomRatings;
- public ParentalControlSettings(Context context, LegacyFlags legacyFlags) {
+ public ParentalControlSettings(Context context) {
mContext = context;
mTvInputManager = (TvInputManager) mContext.getSystemService(Context.TV_INPUT_SERVICE);
- mLegacyFlags = legacyFlags;
}
public boolean isParentalControlsEnabled() {
@@ -132,7 +130,7 @@ public class ParentalControlSettings {
} else {
mRatings = ContentRatingLevelPolicy.getRatingsForLevel(this, manager, level);
if (level != TvSettings.CONTENT_RATING_LEVEL_NONE
- && mLegacyFlags.enableUnratedContentSettings()) {
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
// UNRATED contents should be blocked unless the rating level is none or custom
mRatings.add(TvContentRating.UNRATED);
}
diff --git a/src/com/android/tv/perf/PerformanceMonitor.java b/src/com/android/tv/perf/PerformanceMonitor.java
index 30197c74..b1ae759d 100644
--- a/src/com/android/tv/perf/PerformanceMonitor.java
+++ b/src/com/android/tv/perf/PerformanceMonitor.java
@@ -96,14 +96,4 @@ public interface PerformanceMonitor {
* @return true if the activity is available to start
*/
boolean startPerformanceMonitorEventDebugActivity(Context context);
-
- /**
- * Initialize crash monitoring for an app by wrapping the default {@link
- * Thread.UncaughtExceptionHandler} with a handler that can report crashes to the performance
- * montitor and then delegate the handling of the UncaughtException to the original default
- * {@link Thread.UncaughtExceptionHandler}.
- *
- * <p>Note: This will override the current {@link Thread.UncaughtExceptionHandler}.
- */
- void startCrashMonitor();
}
diff --git a/src/com/android/tv/perf/PerformanceMonitorManager.java b/src/com/android/tv/perf/PerformanceMonitorManager.java
new file mode 100644
index 00000000..db6667d1
--- /dev/null
+++ b/src/com/android/tv/perf/PerformanceMonitorManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.perf;
+
+import android.app.Application;
+
+/** Manages the initialization of Performance Monitoring. */
+public interface PerformanceMonitorManager {
+
+ /**
+ * Initializes the {@link com.android.tv.perf.PerformanceMonitor}.
+ *
+ * <p>This should only be called once.
+ */
+ PerformanceMonitor initialize(Application app);
+
+ /**
+ * Returns a lightweight object to help measure both cold and warm startup latency.
+ *
+ * <p>This method is idempotent and lightweight. It can be called multiple times and does not
+ * need to be cached.
+ */
+ StartupMeasure getStartupMeasure();
+}
diff --git a/src/com/android/tv/perf/StartupMeasureFactory.java b/src/com/android/tv/perf/PerformanceMonitorManagerFactory.java
index a99c88af..fe3ea14b 100644
--- a/src/com/android/tv/perf/StartupMeasureFactory.java
+++ b/src/com/android/tv/perf/PerformanceMonitorManagerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,33 +11,25 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.tv.perf;
-
-import com.android.tv.perf.stub.StubStartupMeasure;
-
-import com.google.common.base.Supplier;
-import java.lang.Override;
+import com.android.tv.perf.stub.StubPerformanceMonitorManager;
import javax.inject.Inject;
-/** Factory for {@link StartupMeasure}.
- *
- * <p>Hardcoded to {@link StubStartupMeasure}.
- */
-public final class StartupMeasureFactory implements Supplier<StartupMeasure> {
- private static final StartupMeasureFactory INSTANCE = new StartupMeasureFactory();
+public final class PerformanceMonitorManagerFactory {
+ private static final PerformanceMonitorManagerFactory INSTANCE =
+ new PerformanceMonitorManagerFactory();
@Inject
- public StartupMeasureFactory() {}
+ public PerformanceMonitorManagerFactory() {}
- public static StartupMeasure create() {
+ public static PerformanceMonitorManager create() {
return INSTANCE.get();
}
- @Override
- public StartupMeasure get() {
- return new StubStartupMeasure();
+ public PerformanceMonitorManager get() {
+ return new StubPerformanceMonitorManager();
}
}
diff --git a/src/com/android/tv/perf/StartupMeasure.java b/src/com/android/tv/perf/StartupMeasure.java
index c7fa50fe..5cf183ca 100644
--- a/src/com/android/tv/perf/StartupMeasure.java
+++ b/src/com/android/tv/perf/StartupMeasure.java
@@ -19,16 +19,8 @@ import android.app.Activity;
import android.app.Application;
/**
- * Measures App startup.
- *
- * <p>This interface is lightweight to help measure both cold and warm startup latency.
- * Implementations must not throw any Exception.
- *
- * <p>Because this class needs to be used in static initialization blocks, it can not be injected
- * via dagger.
- *
- * <p>Creating implementations of this interface must be idempotent and lightweight. It does not
- * need to be cached.
+ * Measures App startup. This interface is lightweight to help measure both cold and warm startup
+ * latency. Implementations must not throw any Exception.
*/
public interface StartupMeasure {
diff --git a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
index ac3dc250..80c2f6c5 100644
--- a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
+++ b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
@@ -56,6 +56,7 @@ public final class StubPerformanceMonitor implements PerformanceMonitor {
return false;
}
- @Override
- public void startCrashMonitor() {}
+ public static TimerEvent startBootstrapTimer() {
+ return new TimerEvent() {};
+ }
}
diff --git a/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java b/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
new file mode 100644
index 00000000..0c268155
--- /dev/null
+++ b/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.perf.stub;
+
+import android.app.Application;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.PerformanceMonitorManager;
+import com.android.tv.perf.StartupMeasure;
+
+/** Manages a stub implementation of Performance Monitoring. */
+public class StubPerformanceMonitorManager implements PerformanceMonitorManager {
+
+ @Override
+ public PerformanceMonitor initialize(Application app) {
+ return new StubPerformanceMonitor();
+ }
+
+ @Override
+ public StartupMeasure getStartupMeasure() {
+ return new StubStartupMeasure();
+ }
+}
diff --git a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
index 5fa7606d..3fb66245 100644
--- a/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
+++ b/src/com/android/tv/receiver/AudioCapabilitiesReceiver.java
@@ -42,7 +42,7 @@ public final class AudioCapabilitiesReceiver {
// AC3 capabilities stat is sent to Google Analytics just once in order to avoid
// duplicated stat reports since it doesn't change over time in most cases.
// Increase this revision when we should force the stat to be sent again.
- // TODO: Consider using custom metrics.
+ // TODO: Consier using custom metrics.
private static final int REPORT_REVISION = 1;
private final Context mContext;
diff --git a/src/com/android/tv/receiver/PackageIntentsReceiver.java b/src/com/android/tv/receiver/PackageIntentsReceiver.java
index 7ff67b50..5bc6d724 100644
--- a/src/com/android/tv/receiver/PackageIntentsReceiver.java
+++ b/src/com/android/tv/receiver/PackageIntentsReceiver.java
@@ -23,7 +23,9 @@ import android.net.Uri;
import android.util.Log;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
+import com.android.tv.features.TvFeatures;
import com.android.tv.util.Partner;
+import com.google.android.tv.partner.support.EpgContract;
/** A class for handling the broadcast intents from PackageManager. */
public class PackageIntentsReceiver extends BroadcastReceiver {
diff --git a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
index 61ebb2d0..2590a337 100644
--- a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
+++ b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
@@ -27,18 +27,15 @@ import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
-
import androidx.tvprovider.media.tv.TvContractCompat;
-
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.PreviewProgramContent;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.Utils;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
diff --git a/src/com/android/tv/recommendation/ChannelRecord.java b/src/com/android/tv/recommendation/ChannelRecord.java
index f047aac6..c7a7cb37 100644
--- a/src/com/android/tv/recommendation/ChannelRecord.java
+++ b/src/com/android/tv/recommendation/ChannelRecord.java
@@ -19,12 +19,10 @@ package com.android.tv.recommendation;
import android.content.Context;
import android.support.annotation.GuardedBy;
import android.support.annotation.VisibleForTesting;
-
import com.android.tv.TvSingletons;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.util.ArrayDeque;
import java.util.Deque;
diff --git a/src/com/android/tv/recommendation/NotificationService.java b/src/com/android/tv/recommendation/NotificationService.java
index 1652bd77..f40a0862 100644
--- a/src/com/android/tv/recommendation/NotificationService.java
+++ b/src/com/android/tv/recommendation/NotificationService.java
@@ -40,21 +40,19 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseLongArray;
import android.view.View;
-
import com.android.tv.MainActivityWrapper.OnCurrentChannelChangeListener;
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.WeakHandler;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.BitmapUtils;
import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
import com.android.tv.util.images.ImageLoader;
-
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/tv/recommendation/RecommendationDataManager.java b/src/com/android/tv/recommendation/RecommendationDataManager.java
index e254ba58..fc20031c 100644
--- a/src/com/android/tv/recommendation/RecommendationDataManager.java
+++ b/src/com/android/tv/recommendation/RecommendationDataManager.java
@@ -34,17 +34,14 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.util.TvUriMatcher;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -235,9 +232,6 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
@MainThread
private void stop() {
- if (mWatchedHistoryManager != null) {
- mWatchedHistoryManager.setListener(null);
- }
for (int what = MSG_FIRST; what <= MSG_LAST; ++what) {
mHandler.removeMessages(what);
}
@@ -365,7 +359,7 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
WatchedHistoryManager.WatchedRecord watchedRecord) {
long endTime = watchedRecord.watchedStartTime + watchedRecord.duration;
Program program =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setChannelId(watchedRecord.channelId)
.setTitle("")
.setStartTimeUtcMillis(watchedRecord.watchedStartTime)
@@ -417,7 +411,7 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
}
Program program =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setChannelId(cursor.getLong(mIndexWatchChannelId))
.setTitle(cursor.getString(mIndexProgramTitle))
.setStartTimeUtcMillis(cursor.getLong(mIndexProgramStartTime))
diff --git a/src/com/android/tv/recommendation/Recommender.java b/src/com/android/tv/recommendation/Recommender.java
index a8535a49..f350799f 100644
--- a/src/com/android/tv/recommendation/Recommender.java
+++ b/src/com/android/tv/recommendation/Recommender.java
@@ -20,9 +20,7 @@ import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Pair;
-
import com.android.tv.data.api.Channel;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -129,7 +127,7 @@ public class Recommender implements RecommendationDataManager.Listener {
}
}
if (!mIncludeRecommendedOnly || maxScore != Evaluator.NOT_RECOMMENDED) {
- records.add(Pair.create(cr.getChannel(), maxScore));
+ records.add(new Pair<>(cr.getChannel(), maxScore));
}
}
if (size > records.size()) {
diff --git a/src/com/android/tv/recommendation/RoutineWatchEvaluator.java b/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
index b3952c01..9240682a 100644
--- a/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
+++ b/src/com/android/tv/recommendation/RoutineWatchEvaluator.java
@@ -19,9 +19,7 @@ package com.android.tv.recommendation;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
-
-import com.android.tv.data.api.Program;
-
+import com.android.tv.data.Program;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Calendar;
diff --git a/src/com/android/tv/recommendation/WatchedProgram.java b/src/com/android/tv/recommendation/WatchedProgram.java
index 0da9c620..239de1f2 100644
--- a/src/com/android/tv/recommendation/WatchedProgram.java
+++ b/src/com/android/tv/recommendation/WatchedProgram.java
@@ -16,7 +16,7 @@
package com.android.tv.recommendation;
-import com.android.tv.data.api.Program;
+import com.android.tv.data.Program;
public final class WatchedProgram {
private final Program mProgram;
diff --git a/src/com/android/tv/search/DataManagerSearch.java b/src/com/android/tv/search/DataManagerSearch.java
index 1a0ada3a..a649c0ac 100644
--- a/src/com/android/tv/search/DataManagerSearch.java
+++ b/src/com/android/tv/search/DataManagerSearch.java
@@ -26,18 +26,15 @@ import android.os.SystemClock;
import android.support.annotation.MainThread;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.TvSingletons;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.search.LocalSearchProvider.SearchResult;
import com.android.tv.util.MainThreadExecutor;
import com.android.tv.util.Utils;
-
import com.google.common.collect.ImmutableList;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
diff --git a/src/com/android/tv/search/LocalSearchProvider.java b/src/com/android/tv/search/LocalSearchProvider.java
index 86999560..5652c986 100644
--- a/src/com/android/tv/search/LocalSearchProvider.java
+++ b/src/com/android/tv/search/LocalSearchProvider.java
@@ -17,6 +17,7 @@
package com.android.tv.search;
import android.app.SearchManager;
+import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
@@ -27,30 +28,21 @@ import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
-
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.dagger.init.SafePreDaggerInitializer;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.PermissionUtils;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.util.TvUriMatcher;
-
import com.google.auto.value.AutoValue;
-
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerContentProvider;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import javax.inject.Inject;
-
-/** Content provider for local search */
-public class LocalSearchProvider extends DaggerContentProvider {
+public class LocalSearchProvider extends ContentProvider {
private static final String TAG = "LocalSearchProvider";
private static final boolean DEBUG = false;
@@ -87,18 +79,14 @@ public class LocalSearchProvider extends DaggerContentProvider {
private static final String NO_LIVE_CONTENTS = "0";
private static final String LIVE_CONTENTS = "1";
- @Inject PerformanceMonitor mPerformanceMonitor;
+ private PerformanceMonitor mPerformanceMonitor;
/** Used only for testing */
private SearchInterface mSearchInterface;
@Override
public boolean onCreate() {
- SafePreDaggerInitializer.init(getContext());
- if (!super.onCreate()) {
- Log.e(TAG, "LocalSearchProvider.onCreate() failed.");
- return false;
- }
+ mPerformanceMonitor = TvSingletons.getSingletons(getContext()).getPerformanceMonitor();
return true;
}
@@ -233,13 +221,6 @@ public class LocalSearchProvider extends DaggerContentProvider {
throw new UnsupportedOperationException();
}
- /** Module for {@link LocalSearchProvider} */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract LocalSearchProvider contributesLocalSearchProviderInjector();
- }
-
/** A placeholder to a search result. */
@AutoValue
public abstract static class SearchResult {
@@ -254,8 +235,6 @@ public class LocalSearchProvider extends DaggerContentProvider {
.setProgressPercentage(0);
}
- public abstract Builder toBuilder();
-
@AutoValue.Builder
abstract static class Builder {
abstract Builder setChannelId(long value);
diff --git a/src/com/android/tv/search/ProgramGuideSearchFragment.java b/src/com/android/tv/search/ProgramGuideSearchFragment.java
index fa2e4516..6c94bd33 100644
--- a/src/com/android/tv/search/ProgramGuideSearchFragment.java
+++ b/src/com/android/tv/search/ProgramGuideSearchFragment.java
@@ -21,18 +21,18 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.leanback.app.SearchFragment;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.HeaderItem;
-import androidx.leanback.widget.ImageCardView;
-import androidx.leanback.widget.ListRow;
-import androidx.leanback.widget.ListRowPresenter;
-import androidx.leanback.widget.ObjectAdapter;
-import androidx.leanback.widget.OnItemViewClickedListener;
-import androidx.leanback.widget.Presenter;
-import androidx.leanback.widget.Row;
-import androidx.leanback.widget.RowPresenter;
-import androidx.leanback.widget.SearchBar;
+import android.support.v17.leanback.app.SearchFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ObjectAdapter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SearchBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/search/TvProviderSearch.java b/src/com/android/tv/search/TvProviderSearch.java
index c46938a9..8a1f51f9 100644
--- a/src/com/android/tv/search/TvProviderSearch.java
+++ b/src/com/android/tv/search/TvProviderSearch.java
@@ -308,7 +308,7 @@ public class TvProviderSearch implements SearchInterface {
if (c != null && c.moveToNext() && !isRatingBlocked(c.getString(2))) {
String channelName = result.getTitle();
String channelNumber = result.getChannelNumber();
- SearchResult.Builder builder = result.toBuilder();
+ SearchResult.Builder builder = SearchResult.builder();
long startUtcMillis = c.getLong(5);
long endUtcMillis = c.getLong(6);
builder.setTitle(c.getString(0));
diff --git a/src/com/android/tv/setup/SystemSetupActivity.java b/src/com/android/tv/setup/SystemSetupActivity.java
index 999b157a..b2160b3a 100644
--- a/src/com/android/tv/setup/SystemSetupActivity.java
+++ b/src/com/android/tv/setup/SystemSetupActivity.java
@@ -24,9 +24,9 @@ import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.widget.Toast;
-
import com.android.tv.R;
import com.android.tv.SetupPassthroughActivity;
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.ui.setup.SetupActivity;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
@@ -36,11 +36,6 @@ import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-import dagger.android.AndroidInjection;
-import dagger.android.ContributesAndroidInjector;
-
-import javax.inject.Inject;
-
/** A activity to start input sources setup fragment for initial setup flow. */
public class SystemSetupActivity extends SetupActivity {
private static final String SYSTEM_SETUP =
@@ -48,17 +43,18 @@ public class SystemSetupActivity extends SetupActivity {
private static final int SHOW_RIPPLE_DURATION_MS = 266;
private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
- @Inject TvInputManagerHelper mInputManager;
+ private TvInputManagerHelper mInputManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
- AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (!SYSTEM_SETUP.equals(intent.getAction())) {
finish();
return;
}
+ TvSingletons singletons = TvSingletons.getSingletons(this);
+ mInputManager = singletons.getTvInputManagerHelper();
}
@Override
@@ -96,7 +92,7 @@ public class SystemSetupActivity extends SetupActivity {
}
// Even though other app can handle the intent, the setup launched by
// Live
- // channels should go through TV app SetupPassthroughActivity.
+ // channels should go through Live channels SetupPassthroughActivity.
intent.setComponent(
new ComponentName(this, SetupPassthroughActivity.class));
try {
@@ -128,13 +124,4 @@ public class SystemSetupActivity extends SetupActivity {
}
return false;
}
-
- /**
- * Exports {@link SystemSetupActivity} for Dagger codegen to create the appropriate injector.
- */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract SystemSetupActivity contributeSystemSetupActivity();
- }
}
diff --git a/src/com/android/tv/ui/AppLayerTvView.java b/src/com/android/tv/ui/AppLayerTvView.java
index 4c54fb3c..e2b64a1e 100644
--- a/src/com/android/tv/ui/AppLayerTvView.java
+++ b/src/com/android/tv/ui/AppLayerTvView.java
@@ -21,6 +21,7 @@ import android.util.AttributeSet;
import android.view.SurfaceView;
import android.view.View;
import com.android.tv.common.compat.TvViewCompat;
+import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
/**
@@ -28,14 +29,9 @@ import com.android.tv.common.util.Debug;
*
* <p>Once an app starts using additional window like SubPanel and it gets window focus, the {@link
* android.media.tv.TvView#setMain()} does not work because its implementation assumes that the app
- * uses only application layer.
- *
- * <p>TODO: remove this class once the TvView.setMain() is revisited.
+ * uses only application layer. TODO: remove this class once the TvView.setMain() is revisited.
*/
public class AppLayerTvView extends TvViewCompat {
-
- boolean mUseSecureSurface = true;
-
public AppLayerTvView(Context context) {
super(context);
}
@@ -48,11 +44,6 @@ public class AppLayerTvView extends TvViewCompat {
super(context, attrs, defStyleAttr);
}
- /** Set the security of children {@link SurfaceView}s to {@code secure} */
- public void setUseSecureSurface(boolean secure) {
- mUseSecureSurface = secure;
- }
-
@Override
public boolean hasWindowFocus() {
return true;
@@ -62,7 +53,7 @@ public class AppLayerTvView extends TvViewCompat {
public void onViewAdded(View child) {
if (child instanceof SurfaceView) {
// Note: See b/29118070 for detail.
- ((SurfaceView) child).setSecure(mUseSecureSurface);
+ ((SurfaceView) child).setSecure(!CommonUtils.isDeveloper());
}
super.onViewAdded(child);
}
diff --git a/src/com/android/tv/ui/ChannelBannerView.java b/src/com/android/tv/ui/ChannelBannerView.java
index f0781214..00ac7e32 100644
--- a/src/com/android/tv/ui/ChannelBannerView.java
+++ b/src/com/android/tv/ui/ChannelBannerView.java
@@ -46,15 +46,13 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.singletons.HasSingletons;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.parental.ContentRatingsManager;
@@ -66,9 +64,7 @@ import com.android.tv.util.images.ImageCache;
import com.android.tv.util.images.ImageLoader;
import com.android.tv.util.images.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.images.ImageLoader.LoadTvInputLogoTask;
-
import com.google.common.collect.ImmutableList;
-
import javax.inject.Provider;
/** A view to render channel banner. */
@@ -122,7 +118,6 @@ public class ChannelBannerView extends FrameLayout
private final TvInputManagerHelper mTvInputManagerHelper;
// TvOverlayManager is always created after ChannelBannerView
private final Provider<TvOverlayManager> mTvOverlayManager;
- private final AccessibilityManager mAccessibilityManager;
private View mChannelView;
@@ -270,12 +265,12 @@ public class ChannelBannerView extends FrameLayout
mContentRatingsManager = mTvInputManagerHelper.getContentRatingsManager();
mNoProgram =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle(context.getString(R.string.channel_banner_no_title))
.setDescription(EMPTY_STRING)
.build();
mLockedChannelProgram =
- new ProgramImpl.Builder()
+ new Program.Builder()
.setTitle(context.getString(R.string.channel_banner_locked_channel_title))
.setDescription(EMPTY_STRING)
.build();
@@ -283,7 +278,8 @@ public class ChannelBannerView extends FrameLayout
sClosedCaptionMark = context.getString(R.string.closed_caption);
}
mAutoHideScheduler = new AutoHideScheduler(context, this::hide);
- mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ context.getSystemService(AccessibilityManager.class)
+ .addAccessibilityStateChangeListener(mAutoHideScheduler);
}
@Override
@@ -323,18 +319,6 @@ public class ChannelBannerView extends FrameLayout
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mAccessibilityManager.addAccessibilityStateChangeListener(mAutoHideScheduler);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- mAccessibilityManager.removeAccessibilityStateChangeListener(mAutoHideScheduler);
- super.onDetachedFromWindow();
- }
-
- @Override
public void onEnterAction(boolean fromEmptyScene) {
resetAnimationEffects();
if (fromEmptyScene) {
@@ -564,7 +548,7 @@ public class ChannelBannerView extends FrameLayout
return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
@Override
public void onBitmapLoaded(ChannelBannerView view, @Nullable Bitmap logo) {
- if (!channel.equals(view.mCurrentChannel)) {
+ if (channel.equals(view.mCurrentChannel)) {
// The logo is obsolete.
return;
}
@@ -751,23 +735,15 @@ public class ChannelBannerView extends FrameLayout
} else {
ImmutableList<TvContentRating> ratings =
(program == null) ? null : program.getContentRatings();
- int ratingsViewIndex = 0;
- if (ratings != null) {
- for (int i = 0; i < ratings.size(); i++) {
- if (ratingsViewIndex < DISPLAYED_CONTENT_RATINGS_COUNT
- && !TextUtils.isEmpty(
- mContentRatingsManager.getDisplayNameForRating(
- ratings.get(i)))) {
- mContentRatingsTextViews[ratingsViewIndex].setText(
- mContentRatingsManager.getDisplayNameForRating(ratings.get(i)));
- mContentRatingsTextViews[ratingsViewIndex].setVisibility(View.VISIBLE);
- ratingsViewIndex++;
- }
+ for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
+ if (ratings == null || ratings.size() <= i) {
+ mContentRatingsTextViews[i].setVisibility(View.GONE);
+ } else {
+ mContentRatingsTextViews[i].setText(
+ mContentRatingsManager.getDisplayNameForRating(ratings.get(i)));
+ mContentRatingsTextViews[i].setVisibility(View.VISIBLE);
}
}
- while (ratingsViewIndex < DISPLAYED_CONTENT_RATINGS_COUNT) {
- mContentRatingsTextViews[ratingsViewIndex++].setVisibility(View.GONE);
- }
}
}
diff --git a/src/com/android/tv/ui/DetailsActivity.java b/src/com/android/tv/ui/DetailsActivity.java
index 92c13f57..80c0f64b 100644
--- a/src/com/android/tv/ui/DetailsActivity.java
+++ b/src/com/android/tv/ui/DetailsActivity.java
@@ -16,11 +16,12 @@
package com.android.tv.ui;
+import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
-import androidx.leanback.app.DetailsFragment;
+import android.support.v17.leanback.app.DetailsFragment;
import android.transition.Transition;
import android.transition.Transition.TransitionListener;
import android.util.Log;
@@ -34,12 +35,9 @@ import com.android.tv.dvr.ui.browse.CurrentRecordingDetailsFragment;
import com.android.tv.dvr.ui.browse.RecordedProgramDetailsFragment;
import com.android.tv.dvr.ui.browse.ScheduledRecordingDetailsFragment;
import com.android.tv.dvr.ui.browse.SeriesRecordingDetailsFragment;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.DaggerActivity;
/** Activity to show details view. */
-public class DetailsActivity extends DaggerActivity
- implements PinDialogFragment.OnPinCheckedListener {
+public class DetailsActivity extends Activity implements PinDialogFragment.OnPinCheckedListener {
private static final String TAG = "DetailsActivity";
private static final long INVALID_RECORD_ID = -1;
@@ -208,15 +206,4 @@ public class DetailsActivity extends DaggerActivity
}
finish();
}
-
- /** Exports {@link DaggerActivity} for Dagger codegen to create the appropriate injector. */
- @dagger.Module
- public abstract static class Module {
- @ContributesAndroidInjector
- abstract DetailsActivity contributesDetailsActivityInjector();
-
- @ContributesAndroidInjector
- abstract CurrentRecordingDetailsFragment
- contributesCurrentRecordingDetailsFragmentInjector();
- }
}
diff --git a/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java b/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
index 3aba5d1d..9685b04b 100644
--- a/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
+++ b/src/com/android/tv/ui/GuidedActionsStylistWithDivider.java
@@ -17,9 +17,9 @@
package com.android.tv.ui;
import android.content.Context;
-import androidx.leanback.app.GuidedStepFragment;
-import androidx.leanback.widget.GuidedAction;
-import androidx.leanback.widget.GuidedActionsStylist;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
import com.android.tv.R;
/** Extended stylist class used for {@link GuidedStepFragment} with divider support. */
diff --git a/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java b/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
index 703dc242..9b916afe 100644
--- a/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
+++ b/src/com/android/tv/ui/OnRepeatedKeyInterceptListener.java
@@ -17,7 +17,7 @@ package com.android.tv.ui;
import android.os.Message;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
diff --git a/src/com/android/tv/ui/ProgramDetailsFragment.java b/src/com/android/tv/ui/ProgramDetailsFragment.java
index bfcebd7d..88a7b2ca 100644
--- a/src/com/android/tv/ui/ProgramDetailsFragment.java
+++ b/src/com/android/tv/ui/ProgramDetailsFragment.java
@@ -23,23 +23,21 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.text.TextUtils;
-
-import androidx.leanback.app.DetailsFragment;
-import androidx.leanback.widget.Action;
-import androidx.leanback.widget.ArrayObjectAdapter;
-import androidx.leanback.widget.ClassPresenterSelector;
-import androidx.leanback.widget.DetailsOverviewRow;
-import androidx.leanback.widget.DetailsOverviewRowPresenter;
-import androidx.leanback.widget.OnActionClickedListener;
-import androidx.leanback.widget.PresenterSelector;
-import androidx.leanback.widget.SparseArrayObjectAdapter;
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
@@ -66,7 +64,7 @@ public class ProgramDetailsFragment extends DetailsFragment
protected DetailsViewBackgroundHelper mBackgroundHelper;
private ArrayObjectAdapter mRowsAdapter;
private DetailsOverviewRow mDetailsOverview;
- private ProgramImpl mProgram;
+ private Program mProgram;
private String mInputId;
private ScheduledRecording mScheduledRecording;
private DvrManager mDvrManager;
@@ -139,7 +137,7 @@ public class ProgramDetailsFragment extends DetailsFragment
* the detail activity and fragment will be ended.
*/
private boolean onLoadDetails(Bundle args) {
- ProgramImpl program = args.getParcelable(DetailsActivity.PROGRAM);
+ Program program = args.getParcelable(DetailsActivity.PROGRAM);
long channelId = args.getLong(DetailsActivity.CHANNEL_ID);
String inputId = args.getString(DetailsActivity.INPUT_ID);
if (program != null && channelId != Channel.INVALID_ID && !TextUtils.isEmpty(inputId)) {
diff --git a/src/com/android/tv/ui/SelectInputView.java b/src/com/android/tv/ui/SelectInputView.java
index a0cfad32..f4949f08 100644
--- a/src/com/android/tv/ui/SelectInputView.java
+++ b/src/com/android/tv/ui/SelectInputView.java
@@ -22,8 +22,8 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
import android.support.annotation.NonNull;
-import androidx.leanback.widget.VerticalGridView;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index a736e79d..5ac6bd83 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -54,13 +54,11 @@ import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
-import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.compat.TvInputConstantCompat;
import com.android.tv.common.compat.TvViewCompat.TvInputCallbackCompat;
@@ -69,11 +67,11 @@ import com.android.tv.common.util.CommonUtils;
import com.android.tv.common.util.Debug;
import com.android.tv.common.util.DurationTimer;
import com.android.tv.common.util.PermissionUtils;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.features.TvFeatures;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
@@ -83,9 +81,6 @@ import com.android.tv.util.NetworkUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -290,12 +285,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
if (mVideoWidth <= 0 || mVideoHeight <= 0) {
mVideoDisplayAspectRatio = 0.0f;
} else {
- float videoPixelAspectRatio =
+ float VideoPixelAspectRatio =
track.getVideoPixelAspectRatio();
- mVideoDisplayAspectRatio = (float) mVideoWidth
- / mVideoHeight;
- mVideoDisplayAspectRatio *= videoPixelAspectRatio > 0 ?
- videoPixelAspectRatio : 1;
+ mVideoDisplayAspectRatio =
+ VideoPixelAspectRatio
+ * mVideoWidth
+ / mVideoHeight;
}
} else if (type == TvTrackInfo.TYPE_AUDIO) {
mAudioChannelCount = track.getAudioChannelCount();
@@ -322,7 +317,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
Debug.getTimer(Debug.TAG_START_UP_TIMER)
.log(
- "Start up of TV app ends,"
+ "Start up of Live TV ends,"
+ " TunableTvView.onVideoAvailable resets timer");
Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
Debug.removeTimer(Debug.TAG_START_UP_TIMER);
@@ -478,12 +473,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void initialize(
- ProgramDataManager programDataManager,
- TvInputManagerHelper tvInputManagerHelper,
- LegacyFlags mLegacyFlags) {
+ ProgramDataManager programDataManager, TvInputManagerHelper tvInputManagerHelper) {
mTvView = findViewById(R.id.tv_view);
- mTvView.setUseSecureSurface(!BuildConfig.ENG && !mLegacyFlags.enableDeveloperFeatures());
-
mProgramDataManager = programDataManager;
mInputManagerHelper = tvInputManagerHelper;
mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
@@ -562,9 +553,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void setMain() {
- if (PermissionUtils.hasChangeHdmiCecActiveSource(getContext())) {
- mTvView.setMain();
- }
+ mTvView.setMain();
}
public void setWatchedHistoryManager(WatchedHistoryManager watchedHistoryManager) {
@@ -664,22 +653,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
// To reduce the IPCs, unregister the callback here and register it when necessary.
mTvView.setTimeShiftPositionCallback(null);
setTimeShiftAvailable(false);
+ if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
+ // When the input is changed, TvView recreates its SurfaceView internally.
+ // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
+ getSurfaceView().getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
+ }
mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
if (mTvViewSession != null) {
mTvViewSession.tune(channel, params, listener);
} else {
mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params);
}
- if (needSurfaceSizeUpdate && mFixedSurfaceWidth > 0 && mFixedSurfaceHeight > 0) {
- // When the input is changed, TvView recreates its SurfaceView internally.
- // So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
- SurfaceView surfaceView = getSurfaceView();
- if (surfaceView != null) {
- surfaceView.getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
- } else {
- Log.w(TAG, "Failed to set fixed size for surface view: Null surface view");
- }
- }
updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(this, true);
diff --git a/src/com/android/tv/ui/TvOverlayManager.java b/src/com/android/tv/ui/TvOverlayManager.java
index 0ab7c685..b2854a1f 100644
--- a/src/com/android/tv/ui/TvOverlayManager.java
+++ b/src/com/android/tv/ui/TvOverlayManager.java
@@ -33,7 +33,6 @@ import android.view.Gravity;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-
import com.android.tv.ChannelTuner;
import com.android.tv.MainActivity;
import com.android.tv.MainActivity.KeyHandlerResultType;
@@ -48,7 +47,6 @@ import com.android.tv.common.ui.setup.OnActionClickListener;
import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ProgramDataManager;
import com.android.tv.dialog.DvrHistoryDialogFragment;
import com.android.tv.dialog.FullscreenDialogFragment;
import com.android.tv.dialog.HalfSizedDialogFragment;
@@ -70,12 +68,6 @@ import com.android.tv.ui.TvTransitionManager.SceneType;
import com.android.tv.ui.sidepanel.SideFragmentManager;
import com.android.tv.ui.sidepanel.parentalcontrols.RatingsFragment;
import com.android.tv.util.TvInputManagerHelper;
-
-import com.google.auto.factory.AutoFactory;
-import com.google.auto.factory.Provided;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -87,7 +79,6 @@ import java.util.Set;
/** A class responsible for the life cycle and event handling of the pop-ups over TV view. */
@UiThread
-@AutoFactory
public class TvOverlayManager implements AccessibilityStateChangeListener {
private static final String TAG = "TvOverlayManager";
private static final boolean DEBUG = false;
@@ -225,7 +216,6 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
private final List<Runnable> mPendingActions = new ArrayList<>();
private final Queue<PendingDialogAction> mPendingDialogActionQueue = new LinkedList<>();
- private final LegacyFlags mLegacyFlags;
private OnBackStackChangedListener mOnBackStackChangedListener;
@@ -239,17 +229,12 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
InputBannerView inputBannerView,
SelectInputView selectInputView,
ViewGroup sceneContainer,
- ProgramGuideSearchFragment searchFragment,
- @Provided LegacyFlags legacyFlags,
- @Provided ChannelDataManager channelDataManager,
- @Provided TvInputManagerHelper tvInputManager,
- @Provided ProgramDataManager programDataManager) {
+ ProgramGuideSearchFragment searchFragment) {
mMainActivity = mainActivity;
mChannelTuner = channelTuner;
TvSingletons singletons = TvSingletons.getSingletons(mainActivity);
- mLegacyFlags = legacyFlags;
- mChannelDataManager = channelDataManager;
- mInputManager = tvInputManager;
+ mChannelDataManager = singletons.getChannelDataManager();
+ mInputManager = singletons.getTvInputManagerHelper();
mTvView = tvView;
mChannelBannerView = channelBannerView;
mKeypadChannelSwitchView = keypadChannelSwitchView;
@@ -286,7 +271,7 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
tvView,
optionsManager,
menuView,
- new MenuRowFactory(mainActivity, tvView, this.mLegacyFlags),
+ new MenuRowFactory(mainActivity, tvView),
new Menu.OnMenuVisibilityChangeListener() {
@Override
public void onMenuVisibilityChange(boolean visible) {
@@ -319,9 +304,9 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
new ProgramGuide(
mainActivity,
channelTuner,
- mInputManager,
+ singletons.getTvInputManagerHelper(),
mChannelDataManager,
- programDataManager,
+ singletons.getProgramDataManager(),
dvrDataManager,
singletons.getDvrScheduleManager(),
singletons.getTracker(),
diff --git a/src/com/android/tv/ui/ViewUtils.java b/src/com/android/tv/ui/ViewUtils.java
index 431b3113..f64a70b2 100644
--- a/src/com/android/tv/ui/ViewUtils.java
+++ b/src/com/android/tv/ui/ViewUtils.java
@@ -18,11 +18,9 @@ package com.android.tv.ui;
import android.animation.Animator;
import android.animation.ValueAnimator;
-import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -35,9 +33,6 @@ public class ViewUtils {
}
public static void setTransitionAlpha(View v, float alpha) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- v.setTransitionAlpha(alpha);
- }
Method method;
try {
method = View.class.getDeclaredMethod("setTransitionAlpha", Float.TYPE);
diff --git a/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java b/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
index de3ae751..2726839c 100644
--- a/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
+++ b/src/com/android/tv/ui/sidepanel/ChannelCheckItem.java
@@ -19,14 +19,13 @@ package com.android.tv.ui.sidepanel;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
-
import com.android.tv.R;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelDataManager.ChannelListener;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
+import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
public abstract class ChannelCheckItem extends CompoundButtonItem {
private final ChannelDataManager mChannelDataManager;
diff --git a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
index b62a57ee..62130b64 100644
--- a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
+++ b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.media.tv.TvContract.Channels;
import android.os.Bundle;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
index e43568c9..36ee5a2d 100644
--- a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
+++ b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
@@ -16,38 +16,29 @@
package com.android.tv.ui.sidepanel;
+import android.accounts.Account;
import android.app.Activity;
-
-import com.android.tv.MainActivity;
+import android.support.annotation.NonNull;
+import android.util.Log;
+import android.widget.Toast;
import com.android.tv.R;
-import com.android.tv.common.BuildConfig;
+import com.android.tv.TvSingletons;
import com.android.tv.common.CommonPreferences;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.common.util.CommonUtils;
+
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import dagger.android.AndroidInjection;
-import com.android.tv.common.flags.LegacyFlags;
-import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
/** Options for developers only */
public class DeveloperOptionFragment extends SideFragment {
+ private static final String TAG = "DeveloperOptionFragment";
private static final String TRACKER_LABEL = "debug options";
- @Inject Optional<AdditionalDeveloperItemsFactory> mAdditionalDeveloperItemsFactory;
- @Inject PerformanceMonitor mPerformanceMonitor;
- @Inject LegacyFlags mLegacyFlags;
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
- }
-
@Override
protected String getTitle() {
return getString(R.string.menu_developer_options);
@@ -59,15 +50,8 @@ public class DeveloperOptionFragment extends SideFragment {
}
@Override
- protected ImmutableList<Item> getItemList() {
- ImmutableList.Builder<Item> items = ImmutableList.builder();
- if (mAdditionalDeveloperItemsFactory.isPresent()) {
- items.addAll(
- mAdditionalDeveloperItemsFactory
- .get()
- .getAdditionalDevItems(getMainActivity()));
- items.add(new DividerItem());
- }
+ protected List<Item> getItemList() {
+ List<Item> items = new ArrayList<>();
if (CommonFeatures.DVR.isEnabled(getContext())) {
items.add(
new ActionItem(getString(R.string.dev_item_dvr_history)) {
@@ -77,7 +61,7 @@ public class DeveloperOptionFragment extends SideFragment {
}
});
}
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
items.add(
new ActionItem(getString(R.string.dev_item_watch_history)) {
@Override
@@ -103,21 +87,17 @@ public class DeveloperOptionFragment extends SideFragment {
CommonPreferences.setStoreTsStream(getContext(), isChecked());
}
});
- if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
+ if (CommonUtils.isDeveloper()) {
items.add(
new ActionItem(getString(R.string.dev_item_show_performance_monitor_log)) {
@Override
protected void onSelected() {
- mPerformanceMonitor.startPerformanceMonitorEventDebugActivity(
- getContext());
+ TvSingletons.getSingletons(getContext())
+ .getPerformanceMonitor()
+ .startPerformanceMonitorEventDebugActivity(getContext());
}
});
}
- return items.build();
- }
-
- /** Factory to create additional items. */
- public interface AdditionalDeveloperItemsFactory {
- ImmutableList<Item> getAdditionalDevItems(MainActivity mainActivity);
+ return items;
}
}
diff --git a/src/com/android/tv/ui/sidepanel/SettingsFragment.java b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
index 1c03b6a9..aa71fb75 100644
--- a/src/com/android/tv/ui/sidepanel/SettingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
@@ -35,7 +35,7 @@ import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
-/** Shows TV app settings. */
+/** Shows Live TV settings. */
public class SettingsFragment extends SideFragment {
private static final String TRACKER_LABEL = "settings";
diff --git a/src/com/android/tv/ui/sidepanel/SideFragment.java b/src/com/android/tv/ui/sidepanel/SideFragment.java
index 703b1e43..590f1300 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragment.java
@@ -20,27 +20,24 @@ import android.app.Fragment;
import android.content.Context;
import android.graphics.drawable.RippleDrawable;
import android.os.Bundle;
-import androidx.recyclerview.widget.RecyclerView;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
-
-import androidx.leanback.widget.VerticalGridView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.analytics.HasTrackerLabel;
import com.android.tv.analytics.Tracker;
-import com.android.tv.common.dev.DeveloperPreferences;
import com.android.tv.common.util.DurationTimer;
+import com.android.tv.common.util.SystemProperties;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.util.ViewCache;
-
import java.util.List;
public abstract class SideFragment<T extends Item> extends Fragment implements HasTrackerLabel {
@@ -59,7 +56,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
new RecyclerView.RecycledViewPool();
private VerticalGridView mListView;
- private ItemAdapter<T> mAdapter;
+ private ItemAdapter mAdapter;
private SideFragmentListener mListener;
private ChannelDataManager mChannelDataManager;
private ProgramDataManager mProgramDataManager;
@@ -68,7 +65,6 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
private final int mHideKey;
private final int mDebugHideKey;
- private Context mContext;
public SideFragment() {
this(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.KEYCODE_UNKNOWN);
@@ -77,7 +73,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
/**
* @param hideKey the KeyCode used to hide the fragment
* @param debugHideKey the KeyCode used to hide the fragment if {@link
- * DeveloperPreferences#USE_DEBUG_KEYS}.
+ * SystemProperties#USE_DEBUG_KEYS}.
*/
public SideFragment(int hideKey, int debugHideKey) {
mHideKey = hideKey;
@@ -87,7 +83,6 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
@Override
public void onAttach(Context context) {
super.onAttach(context);
- mContext = context;
mChannelDataManager = getMainActivity().getChannelDataManager();
mProgramDataManager = getMainActivity().getProgramDataManager();
mTracker = TvSingletons.getSingletons(context).getTracker();
@@ -134,8 +129,7 @@ public abstract class SideFragment<T extends Item> extends Fragment implements H
}
public final boolean isHideKeyForThisPanel(int keyCode) {
- boolean debugKeysEnabled =
- DeveloperPreferences.USE_DEBUG_KEYS.getDefaultIfContextNull(mContext);
+ boolean debugKeysEnabled = SystemProperties.USE_DEBUG_KEYS.getValue();
return mHideKey != KeyEvent.KEYCODE_UNKNOWN
&& (mHideKey == keyCode || (debugKeysEnabled && mDebugHideKey == keyCode));
}
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
index 620b7017..b14bf78d 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
@@ -23,7 +23,7 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
-import androidx.leanback.widget.VerticalGridView;
+import android.support.v17.leanback.widget.VerticalGridView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
index 60f8425f..d1ae4423 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
@@ -16,7 +16,6 @@
package com.android.tv.ui.sidepanel.parentalcontrols;
-import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.tv.TvContentRating;
import android.os.Bundle;
@@ -25,9 +24,9 @@ import android.util.SparseIntArray;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.common.experiments.Experiments;
import com.android.tv.dialog.WebDialogFragment;
import com.android.tv.license.LicenseUtils;
import com.android.tv.parental.ContentRatingSystem;
@@ -40,28 +39,18 @@ import com.android.tv.ui.sidepanel.RadioButtonItem;
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvSettings.ContentRatingLevel;
-
import com.google.common.collect.ImmutableList;
-
-import dagger.android.AndroidInjection;
-
-import com.android.tv.common.flags.LegacyFlags;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import javax.inject.Inject;
-
public class RatingsFragment extends SideFragment {
private static final SparseIntArray sLevelResourceIdMap;
private static final SparseIntArray sDescriptionResourceIdMap;
private static final String TRACKER_LABEL = "Ratings";
private int mItemsSize;
- @Inject LegacyFlags mLegacyFlags;
-
static {
sLevelResourceIdMap = new SparseIntArray(5);
sLevelResourceIdMap.put(TvSettings.CONTENT_RATING_LEVEL_NONE, R.string.option_rating_none);
@@ -112,7 +101,8 @@ public class RatingsFragment extends SideFragment {
protected List<Item> getItemList() {
List<Item> items = new ArrayList<>();
- if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
items.add(mBlockUnratedItem);
items.add(new DividerItem());
}
@@ -168,13 +158,7 @@ public class RatingsFragment extends SideFragment {
super.onCreate(savedInstanceState);
mParentalControlSettings = getMainActivity().getParentalControlSettings();
mParentalControlSettings.loadRatings();
- }
-
- @Override
- public void onAttach(Activity activity) {
- AndroidInjection.inject(this);
- super.onAttach(activity);
- if (mLegacyFlags.enableUnratedContentSettings()) {
+ if (Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
mBlockUnratedItem =
new CheckBoxItem(
getResources().getString(R.string.option_block_unrated_programs)) {
@@ -195,8 +179,6 @@ public class RatingsFragment extends SideFragment {
}
}
};
- } else {
- mBlockUnratedItem = null;
}
}
@@ -253,7 +235,8 @@ public class RatingsFragment extends SideFragment {
super.onSelected();
mParentalControlSettings.setContentRatingLevel(
getMainActivity().getContentRatingsManager(), mRatingLevel);
- if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
// set checked if UNRATED is blocked, and set unchecked otherwise.
mBlockUnratedItem.setChecked(
mParentalControlSettings.isRatingBlocked(
diff --git a/src/com/android/tv/util/AsyncDbTask.java b/src/com/android/tv/util/AsyncDbTask.java
index 2e9a1ea8..b3523952 100644
--- a/src/com/android/tv/util/AsyncDbTask.java
+++ b/src/com/android/tv/util/AsyncDbTask.java
@@ -28,23 +28,18 @@ import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.TvSingletons;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.ChannelImpl;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
import com.android.tv.dvr.data.RecordedProgram;
-
import com.google.common.base.Predicate;
-
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
-
import javax.inject.Qualifier;
/**
@@ -128,7 +123,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
return null;
}
if (Utils.isProgramsUri(mUri)
- && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
+ && TvProviderUtils.checkSeriesIdColumn(context, Programs.CONTENT_URI)) {
mProjection =
TvProviderUtils.addExtraColumnsToProjection(
mProjection, TvProviderUtils.EXTRA_PROGRAM_COLUMN_SERIES_ID);
@@ -328,19 +323,10 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
}
- /**
- * Gets an {@link List} of {@link ProgramImpl}s from {@link TvContract.Programs#CONTENT_URI}.
- */
+ /** Gets an {@link List} of {@link Program}s from {@link TvContract.Programs#CONTENT_URI}. */
public abstract static class AsyncProgramQueryTask extends AsyncQueryListTask<Program> {
public AsyncProgramQueryTask(Executor executor, Context context) {
- super(
- executor,
- context,
- Programs.CONTENT_URI,
- ProgramImpl.PROJECTION,
- null,
- null,
- null);
+ super(executor, context, Programs.CONTENT_URI, Program.PROJECTION, null, null, null);
}
public AsyncProgramQueryTask(
@@ -355,7 +341,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
executor,
context,
uri,
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
selection,
selectionArgs,
sortOrder,
@@ -364,7 +350,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
@Override
protected final Program fromCursor(Cursor c) {
- return ProgramImpl.fromCursor(c);
+ return Program.fromCursor(c);
}
}
@@ -390,7 +376,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
/**
- * Gets an {@link List} of {@link ProgramImpl}s for a given channel and period {@link
+ * Gets an {@link List} of {@link Program}s for a given channel and period {@link
* TvContract#buildProgramsUriForChannel(long, long, long)}. If the {@code period} is {@code
* null}, then all the programs is queried.
*/
@@ -424,7 +410,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
}
}
- /** Gets a single {@link ProgramImpl} from {@link TvContract.Programs#CONTENT_URI}. */
+ /** Gets a single {@link Program} from {@link TvContract.Programs#CONTENT_URI}. */
public static class AsyncQueryProgramTask extends AsyncQueryItemTask<Program> {
public AsyncQueryProgramTask(Executor executor, Context context, long programId) {
@@ -432,7 +418,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
executor,
context,
TvContract.buildProgramUri(programId),
- ProgramImpl.PROJECTION,
+ Program.PROJECTION,
null,
null,
null);
@@ -440,7 +426,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
@Override
protected Program fromCursor(Cursor c) {
- return ProgramImpl.fromCursor(c);
+ return Program.fromCursor(c);
}
}
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 4fae2f00..3b72e091 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -27,9 +27,7 @@ public final class OnboardingUtils {
private static final String PREF_KEY_ONBOARDING_VERSION_CODE = "pref_onbaording_versionCode";
private static final int ONBOARDING_VERSION = 1;
- // Replace as needed
- private static final String MERCHANT_COLLECTION_URL_STRING =
- "https://play.google.com/store/apps/collection/promotion_3001bf9_ATV_livechannels";
+ private static final String MERCHANT_COLLECTION_URL_STRING = getMerchantCollectionUrl();
/** Intent to show merchant collection in online store. */
public static final Intent ONLINE_STORE_INTENT =
@@ -71,5 +69,10 @@ public final class OnboardingUtils {
.apply();
}
+ /** Returns merchant collection URL. */
+ private static String getMerchantCollectionUrl() {
+ return "TODO: add a merchant collection url";
+ }
+
private OnboardingUtils() {}
}
diff --git a/src/com/android/tv/util/SetupUtils.java b/src/com/android/tv/util/SetupUtils.java
index 52b3e3e8..a9b67fa8 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -307,7 +307,8 @@ public class SetupUtils {
}
/**
- * Called when TV app is launched. Once it is called, {@link #isFirstTune} will return false.
+ * Called when Live channels app is launched. Once it is called, {@link #isFirstTune} will
+ * return false.
*/
public void onTuned() {
if (!mIsFirstTune) {
diff --git a/src/com/android/tv/util/SqlParams.java b/src/com/android/tv/util/SqlParams.java
new file mode 100644
index 00000000..fa557ba2
--- /dev/null
+++ b/src/com/android/tv/util/SqlParams.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.tv.util;
+
+import android.database.DatabaseUtils;
+import android.support.annotation.Nullable;
+import java.util.Arrays;
+
+/** Convenience class for SQL operations. */
+public class SqlParams {
+ private String mTables;
+ private @Nullable String mSelection;
+ private @Nullable String[] mSelectionArgs;
+
+ public SqlParams(String tables, @Nullable String selection, @Nullable String... selectionArgs) {
+ setTables(tables);
+ setWhere(selection, selectionArgs);
+ }
+
+ public String getTables() {
+ return mTables;
+ }
+
+ public @Nullable String getSelection() {
+ return mSelection;
+ }
+
+ public @Nullable String[] getSelectionArgs() {
+ return mSelectionArgs;
+ }
+
+ public void setTables(String tables) {
+ mTables = tables;
+ }
+
+ public void setWhere(String selection, String... selectionArgs) {
+ mSelection = selection;
+ mSelectionArgs = selectionArgs;
+ }
+
+ public void appendWhere(String selection, String... selectionArgs) {
+ mSelection = DatabaseUtils.concatenateWhere(mSelection, selection);
+ if (selectionArgs != null) {
+ mSelectionArgs = DatabaseUtils.appendSelectionArgs(mSelectionArgs, selectionArgs);
+ }
+ }
+
+ public void appendWhereEquals(String name, String value) {
+ appendWhere(name + "=?", value);
+ }
+
+ @Override
+ public String toString() {
+ return "tables "
+ + getTables()
+ + " where "
+ + getSelection()
+ + " with "
+ + Arrays.toString(getSelectionArgs());
+ }
+}
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index 23c9b494..cb7d9854 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -46,8 +46,6 @@ import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.images.ImageCache;
import com.android.tv.util.images.ImageLoader;
-import com.google.common.collect.Ordering;
-import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -129,7 +127,6 @@ public class TvInputManagerHelper {
private static final String PERMISSION_ACCESS_ALL_EPG_DATA =
"com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA";
private static final String[] mPhysicalTunerBlackList = {
- "com.google.android.videos", // Play Movies
};
private static final String META_LABEL_SORT_KEY = "input_sort_key";
@@ -161,10 +158,6 @@ public class TvInputManagerHelper {
}
private static final String[] PARTNER_TUNER_INPUT_PREFIX_BLACKLIST = {
- /* Begin_AOSP_Comment_Out
- // Disabled partner's tuner input prefix list.
- "com.mediatek.tvinput/.dtv"
- End_AOSP_Comment_Out */
};
private static final String[] TESTABLE_INPUTS = {
@@ -299,8 +292,8 @@ public class TvInputManagerHelper {
private boolean mAllow3rdPartyInputs;
@Inject
- public TvInputManagerHelper(@ApplicationContext Context context, LegacyFlags legacyFlags) {
- this(context, createTvInputManagerWrapper(context), legacyFlags);
+ public TvInputManagerHelper(@ApplicationContext Context context) {
+ this(context, createTvInputManagerWrapper(context));
}
@Nullable
@@ -312,14 +305,12 @@ public class TvInputManagerHelper {
@VisibleForTesting
protected TvInputManagerHelper(
- Context context,
- @Nullable TvInputManagerInterface tvInputManager,
- LegacyFlags legacyFlags) {
+ Context context, @Nullable TvInputManagerInterface tvInputManager) {
mContext = context.getApplicationContext();
mPackageManager = context.getPackageManager();
mTvInputManager = tvInputManager;
mContentRatingsManager = new ContentRatingsManager(context, tvInputManager);
- mParentalControlSettings = new ParentalControlSettings(context, legacyFlags);
+ mParentalControlSettings = new ParentalControlSettings(context);
mTvInputInfoComparator = new InputComparatorInternal(this);
mContentObserver =
new ContentObserver(mHandler) {
@@ -357,6 +348,7 @@ public class TvInputManagerHelper {
updateAllow3rdPartyInputs();
mTvInputManager.registerCallback(mInternalCallback, mHandler);
initInputMaps();
+ mContentRatingsManager.update();
}
public void stop() {
@@ -454,12 +446,10 @@ public class TvInputManagerHelper {
}
/** Loads label of {@code info}. */
- @Nullable
public String loadLabel(TvInputInfo info) {
String label = mTvInputLabels.get(info.getId());
if (label == null) {
- CharSequence labelSequence = info.loadLabel(mContext);
- label = labelSequence == null ? null : labelSequence.toString();
+ label = info.loadLabel(mContext).toString();
mTvInputLabels.put(info.getId(), label);
}
return label;
@@ -713,8 +703,6 @@ public class TvInputManagerHelper {
@VisibleForTesting
static class InputComparatorInternal implements Comparator<TvInputInfo> {
private final TvInputManagerHelper mInputManager;
- private static final Ordering<Comparable> NULL_FIRST_STRING_ORDERING =
- Ordering.natural().nullsFirst();
public InputComparatorInternal(TvInputManagerHelper inputManager) {
mInputManager = inputManager;
@@ -725,8 +713,7 @@ public class TvInputManagerHelper {
if (mInputManager.isPartnerInput(lhs) != mInputManager.isPartnerInput(rhs)) {
return mInputManager.isPartnerInput(lhs) ? -1 : 1;
}
- return NULL_FIRST_STRING_ORDERING.compare(
- mInputManager.loadLabel(lhs), mInputManager.loadLabel(rhs));
+ return mInputManager.loadLabel(lhs).compareTo(mInputManager.loadLabel(rhs));
}
}
@@ -808,7 +795,7 @@ public class TvInputManagerHelper {
if (TextUtils.isEmpty(label)) {
label = mTvInputManagerHelper.loadLabel(input);
}
- return label == null ? "" : label;
+ return label;
}
private int getPriority(TvInputInfo info) {
diff --git a/src/com/android/tv/util/TvProviderUtils.java b/src/com/android/tv/util/TvProviderUtils.java
index d931dcd5..6b5aaecc 100644
--- a/src/com/android/tv/util/TvProviderUtils.java
+++ b/src/com/android/tv/util/TvProviderUtils.java
@@ -27,7 +27,7 @@ import android.support.annotation.StringDef;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.util.Log;
-import com.android.tv.data.api.BaseProgram;
+import com.android.tv.data.BaseProgram;
import com.android.tv.features.PartnerFeatures;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -67,9 +67,6 @@ public final class TvProviderUtils {
@WorkerThread
public static synchronized boolean checkSeriesIdColumn(Context context, Uri uri) {
boolean canCreateColumn = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O);
- canCreateColumn =
- (canCreateColumn
- || PartnerFeatures.TVPROVIDER_ALLOWS_COLUMN_CREATION.isEnabled(context));
if (!canCreateColumn) {
return false;
}
@@ -115,9 +112,6 @@ public final class TvProviderUtils {
@WorkerThread
public static synchronized boolean checkStateColumn(Context context, Uri uri) {
boolean canCreateColumn = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O);
- canCreateColumn =
- (canCreateColumn
- || PartnerFeatures.TVPROVIDER_ALLOWS_COLUMN_CREATION.isEnabled(context));
if (!canCreateColumn) {
return false;
}
@@ -150,8 +144,8 @@ public final class TvProviderUtils {
return TRUE.equals(sRecordedProgramHasStateColumn);
}
- public static String[] addExtraColumnsToProjection(
- String[] projection, @TvProviderExtraColumn String column) {
+ public static String[] addExtraColumnsToProjection(String[] projection,
+ @TvProviderExtraColumn String column) {
List<String> projectionList = new ArrayList<>(Arrays.asList(projection));
if (!projectionList.contains(column)) {
projectionList.add(column);
diff --git a/src/com/android/tv/util/TvTrackInfoUtils.java b/src/com/android/tv/util/TvTrackInfoUtils.java
index ae30df11..4ec96c62 100644
--- a/src/com/android/tv/util/TvTrackInfoUtils.java
+++ b/src/com/android/tv/util/TvTrackInfoUtils.java
@@ -17,16 +17,9 @@ package com.android.tv.util;
import android.content.Context;
import android.media.tv.TvTrackInfo;
-import android.os.Build;
-import android.os.LocaleList;
import android.text.TextUtils;
import android.util.Log;
-
import com.android.tv.R;
-
-import com.google.common.collect.Iterables;
-
-import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
@@ -45,19 +38,17 @@ public class TvTrackInfoUtils {
private static final int AUDIO_CHANNEL_SURROUND_8 = 8;
/**
- * Compares how closely two {@link android.media.tv.TvTrackInfo}s match {@code languages},
- * {@code channelCount} and {@code id} in that precedence. A listed sorted with this comparator
- * has the worst matches first.
+ * Compares how closely two {@link android.media.tv.TvTrackInfo}s match {@code language}, {@code
+ * channelCount} and {@code id} in that precedence.
*
* @param id The track id to match.
- * @param languages The prioritized list of languages. Languages earlier in the list are a
- * better match.
+ * @param language The language to match.
* @param channelCount The channel count to match.
* @return -1 if lhs is a worse match, 0 if lhs and rhs match equally and 1 if lhs is a better
* match.
*/
public static Comparator<TvTrackInfo> createComparator(
- final String id, final List<String> languages, final int channelCount) {
+ final String id, final String language, final int channelCount) {
return (TvTrackInfo lhs, TvTrackInfo rhs) -> {
if (Objects.equals(lhs, rhs)) {
return 0;
@@ -68,35 +59,26 @@ public class TvTrackInfoUtils {
if (rhs == null) {
return 1;
}
- // Find the first language that matches the lhs and rhs tracks. The earlier match is
- // better. If there is no match set the index to the size of the language list since
- // its the worst match.
- int lhsLangIndex =
- Iterables.indexOf(languages, s -> Utils.isEqualLanguage(lhs.getLanguage(), s));
- if (lhsLangIndex == -1) {
- lhsLangIndex = languages.size();
- }
- int rhsLangIndex =
- Iterables.indexOf(languages, s -> Utils.isEqualLanguage(rhs.getLanguage(), s));
- if (rhsLangIndex == -1) {
- rhsLangIndex = languages.size();
- }
- if (lhsLangIndex != rhsLangIndex) {
- // Return the track with lower index as best
- return Integer.compare(rhsLangIndex, lhsLangIndex);
- }
- boolean lhsCountMatch =
- lhs.getType() != TvTrackInfo.TYPE_AUDIO
- || lhs.getAudioChannelCount() == channelCount;
- boolean rhsCountMatch =
- rhs.getType() != TvTrackInfo.TYPE_AUDIO
- || rhs.getAudioChannelCount() == channelCount;
- if (lhsCountMatch && rhsCountMatch) {
- return Boolean.compare(lhs.getId().equals(id), rhs.getId().equals(id));
- } else if (lhsCountMatch || rhsCountMatch) {
- return Boolean.compare(lhsCountMatch, rhsCountMatch);
+ // Assumes {@code null} language matches to any language since it means user hasn't
+ // selected any track before or selected a track without language information.
+ boolean lhsLangMatch =
+ language == null || Utils.isEqualLanguage(lhs.getLanguage(), language);
+ boolean rhsLangMatch =
+ language == null || Utils.isEqualLanguage(rhs.getLanguage(), language);
+ if (lhsLangMatch && rhsLangMatch) {
+ boolean lhsCountMatch =
+ lhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || lhs.getAudioChannelCount() == channelCount;
+ boolean rhsCountMatch =
+ rhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || rhs.getAudioChannelCount() == channelCount;
+ if (lhsCountMatch && rhsCountMatch) {
+ return Boolean.compare(lhs.getId().equals(id), rhs.getId().equals(id));
+ } else {
+ return Boolean.compare(lhsCountMatch, rhsCountMatch);
+ }
} else {
- return Integer.compare(lhs.getAudioChannelCount(), rhs.getAudioChannelCount());
+ return Boolean.compare(lhsLangMatch, rhsLangMatch);
}
};
}
@@ -115,20 +97,7 @@ public class TvTrackInfoUtils {
if (tracks == null) {
return null;
}
- List<String> languages = new ArrayList<>();
- if (language == null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- LocaleList locales = LocaleList.getDefault();
- for (int i = 0; i < locales.size(); i++) {
- languages.add(locales.get(i).getLanguage());
- }
- } else {
- languages.add(Locale.getDefault().getLanguage());
- }
- } else {
- languages.add(language);
- }
- Comparator<TvTrackInfo> comparator = createComparator(id, languages, channelCount);
+ Comparator<TvTrackInfo> comparator = createComparator(id, language, channelCount);
TvTrackInfo best = null;
for (TvTrackInfo track : tracks) {
if (comparator.compare(track, best) > 0) {
@@ -159,7 +128,11 @@ public class TvTrackInfoUtils {
if (!TextUtils.isEmpty(track.getLanguage())) {
language = new Locale(track.getLanguage()).getDisplayName();
} else {
- Log.d(TAG, "No language information found for the audio track: " + toString(track));
+ Log.d(
+ TAG,
+ "No language information found for the audio track: "
+ + toString(track)
+ );
}
StringBuilder metadata = new StringBuilder();
@@ -234,31 +207,31 @@ public class TvTrackInfoUtils {
public static String toString(TvTrackInfo info) {
int trackType = info.getType();
return "TvTrackInfo{"
- + "type="
- + trackTypeToString(trackType)
- + ", id="
- + info.getId()
- + ", language="
- + info.getLanguage()
- + ", description="
- + info.getDescription()
- + (trackType == TvTrackInfo.TYPE_AUDIO
- ? (", audioChannelCount="
- + info.getAudioChannelCount()
- + ", audioSampleRate="
- + info.getAudioSampleRate())
- : "")
- + (trackType == TvTrackInfo.TYPE_VIDEO
- ? (", videoWidth="
- + info.getVideoWidth()
- + ", videoHeight="
- + info.getVideoHeight()
- + ", videoFrameRate="
- + info.getVideoFrameRate()
- + ", videoPixelAspectRatio="
- + info.getVideoPixelAspectRatio())
- : "")
- + "}";
+ + "type="
+ + trackTypeToString(trackType)
+ + ", id="
+ + info.getId()
+ + ", language="
+ + info.getLanguage()
+ + ", description="
+ + info.getDescription()
+ + (trackType == TvTrackInfo.TYPE_AUDIO
+ ?
+ (", audioChannelCount="
+ + info.getAudioChannelCount()
+ + ", audioSampleRate="
+ + info.getAudioSampleRate()) : "")
+ + (trackType == TvTrackInfo.TYPE_VIDEO
+ ?
+ (", videoWidth="
+ + info.getVideoWidth()
+ + ", videoHeight="
+ + info.getVideoHeight()
+ + ", videoFrameRate="
+ + info.getVideoFrameRate()
+ + ", videoPixelAspectRatio="
+ + info.getVideoPixelAspectRatio()) : "")
+ + "}";
}
private TvTrackInfoUtils() {}
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index c1f9e935..51173739 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -39,19 +39,17 @@ import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
-
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.BaseSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.util.Clock;
import com.android.tv.data.GenreItems;
-import com.android.tv.data.ProgramImpl;
+import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.api.Channel;
-import com.android.tv.data.api.Program;
-
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@@ -326,7 +324,7 @@ public class Utils {
TvContract.buildChannelUri(channelId), timeMs, timeMs);
ContentResolver resolver = context.getContentResolver();
- String[] projection = ProgramImpl.PROJECTION;
+ String[] projection = Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(context, TvContract.Programs.CONTENT_URI)) {
if (Utils.isProgramsUri(uri)) {
projection =
@@ -336,7 +334,7 @@ public class Utils {
}
try (Cursor cursor = resolver.query(uri, projection, null, null, null)) {
if (cursor != null && cursor.moveToNext()) {
- return ProgramImpl.fromCursor(cursor);
+ return Program.fromCursor(cursor);
}
}
return null;
@@ -605,7 +603,6 @@ public class Utils {
}
/** Returns the label for a given input. Returns the custom label, if any. */
- @Nullable
public static String loadLabel(Context context, TvInputInfo input) {
if (input == null) {
return null;
@@ -615,7 +612,7 @@ public class Utils {
CharSequence customLabel = inputManager.loadCustomLabel(input);
String label = (customLabel == null) ? null : customLabel.toString();
if (TextUtils.isEmpty(label)) {
- label = inputManager.loadLabel(input);
+ label = inputManager.loadLabel(input).toString();
}
return label;
}
@@ -717,6 +714,33 @@ public class Utils {
return context.createConfigurationContext(config).getText(resourceId);
}
+ /** Checks where there is any internal TV input. */
+ public static boolean hasInternalTvInputs(Context context, boolean tunerInputOnly) {
+ for (TvInputInfo input :
+ TvSingletons.getSingletons(context)
+ .getTvInputManagerHelper()
+ .getTvInputInfos(true, tunerInputOnly)) {
+ if (isInternalTvInput(context, input.getId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Returns the internal TV inputs. */
+ public static List<TvInputInfo> getInternalTvInputs(Context context, boolean tunerInputOnly) {
+ List<TvInputInfo> inputs = new ArrayList<>();
+ for (TvInputInfo input :
+ TvSingletons.getSingletons(context)
+ .getTvInputManagerHelper()
+ .getTvInputInfos(true, tunerInputOnly)) {
+ if (isInternalTvInput(context, input.getId())) {
+ inputs.add(input);
+ }
+ }
+ return inputs;
+ }
+
/** Checks whether the input is internal or not. */
public static boolean isInternalTvInput(Context context, String inputId) {
ComponentName unflattenInputId = ComponentName.unflattenFromString(inputId);
diff --git a/src/com/android/tv/util/account/AccountHelper.java b/src/com/android/tv/util/account/AccountHelper.java
index d54c2f56..e98b42ec 100644
--- a/src/com/android/tv/util/account/AccountHelper.java
+++ b/src/com/android/tv/util/account/AccountHelper.java
@@ -35,11 +35,4 @@ public interface AccountHelper {
/** Returns all eligible accounts . */
@Nullable
Account getFirstEligibleAccount();
-
- /**
- * Initialize the account helper.
- *
- * <p>This method is a no op if called more than once.
- */
- void init();
}
diff --git a/src/com/android/tv/util/account/AccountHelperImpl.java b/src/com/android/tv/util/account/AccountHelperImpl.java
index e97cc3f2..58fbd27e 100644
--- a/src/com/android/tv/util/account/AccountHelperImpl.java
+++ b/src/com/android/tv/util/account/AccountHelperImpl.java
@@ -21,12 +21,8 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import com.android.tv.common.dagger.annotations.ApplicationContext;
-import javax.inject.Inject;
-import javax.inject.Singleton;
/** Helper methods for getting and selecting a user account. */
-@Singleton
public class AccountHelperImpl implements com.android.tv.util.account.AccountHelper {
private static final String SELECTED_ACCOUNT = "android.tv.livechannels.selected_account";
@@ -35,8 +31,7 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
@Nullable private Account mSelectedAccount;
- @Inject
- public AccountHelperImpl(@ApplicationContext Context context) {
+ public AccountHelperImpl(Context context) {
mContext = context.getApplicationContext();
mDefaultPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
}
@@ -103,9 +98,4 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
PreferenceManager.getDefaultSharedPreferences(mContext);
defaultPreferences.edit().putString(SELECTED_ACCOUNT, account.name).commit();
}
-
- @Override
- public void init() {
- // do nothing.
- }
}
diff --git a/src/com/android/tv/util/images/ImageLoader.java b/src/com/android/tv/util/images/ImageLoader.java
index e026f26a..d2ad0eb1 100644
--- a/src/com/android/tv/util/images/ImageLoader.java
+++ b/src/com/android/tv/util/images/ImageLoader.java
@@ -29,13 +29,9 @@ import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.util.ArraySet;
import android.util.Log;
-
-import androidx.tvprovider.media.tv.TvContractCompat.PreviewPrograms;
-
import com.android.tv.R;
import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
-
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
@@ -168,8 +164,8 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
- Context context, String uriString, ImageLoaderCallback<T> callback) {
+ public static boolean loadBitmap(
+ Context context, String uriString, ImageLoaderCallback callback) {
return loadBitmap(context, uriString, Integer.MAX_VALUE, Integer.MAX_VALUE, callback);
}
@@ -182,12 +178,12 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
+ public static boolean loadBitmap(
Context context,
String uriString,
int maxWidth,
int maxHeight,
- ImageLoaderCallback<T> callback) {
+ ImageLoaderCallback callback) {
if (DEBUG) {
Log.d(TAG, "loadBitmap() " + uriString);
}
@@ -195,12 +191,12 @@ public final class ImageLoader {
context, uriString, maxWidth, maxHeight, callback, IMAGE_THREAD_POOL_EXECUTOR);
}
- private static <T> boolean doLoadBitmap(
+ private static boolean doLoadBitmap(
Context context,
String uriString,
int maxWidth,
int maxHeight,
- ImageLoaderCallback<T> callback,
+ ImageLoaderCallback callback,
Executor executor) {
// Check the cache before creating a Task. The cache will be checked again in doLoadBitmap
// but checking a cache is much cheaper than creating an new task.
@@ -226,8 +222,7 @@ public final class ImageLoader {
* @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public static <T> boolean loadBitmap(
- ImageLoaderCallback<T> callback, LoadBitmapTask<T> loadBitmapTask) {
+ public static boolean loadBitmap(ImageLoaderCallback callback, LoadBitmapTask loadBitmapTask) {
if (DEBUG) {
Log.d(TAG, "loadBitmap() " + loadBitmapTask);
}
@@ -236,8 +231,8 @@ public final class ImageLoader {
/** @return {@code true} if the load is complete and the callback is executed. */
@UiThread
- private static <T> boolean doLoadBitmap(
- ImageLoaderCallback<T> callback, Executor executor, LoadBitmapTask<T> loadBitmapTask) {
+ private static boolean doLoadBitmap(
+ ImageLoaderCallback callback, Executor executor, LoadBitmapTask loadBitmapTask) {
ScaledBitmapInfo bitmapInfo = loadBitmapTask.getFromCache();
boolean needToReload = loadBitmapTask.isReloadNeeded();
if (bitmapInfo != null && !needToReload) {
@@ -272,11 +267,11 @@ public final class ImageLoader {
*
* <p>Implement {@link #doGetBitmapInBackground} to do the actual loading.
*/
- public abstract static class LoadBitmapTask<T> extends AsyncTask<Void, Void, ScaledBitmapInfo> {
+ public abstract static class LoadBitmapTask extends AsyncTask<Void, Void, ScaledBitmapInfo> {
protected final Context mAppContext;
protected final int mMaxWidth;
protected final int mMaxHeight;
- private final Set<ImageLoaderCallback<T>> mCallbacks = new ArraySet<>();
+ private final Set<ImageLoaderCallback> mCallbacks = new ArraySet<>();
private final ImageCache mImageCache;
private final String mKey;
@@ -358,7 +353,7 @@ public final class ImageLoader {
public final void onPostExecute(ScaledBitmapInfo scaledBitmapInfo) {
if (DEBUG) Log.d(ImageLoader.TAG, "Bitmap is loaded " + mKey);
- for (ImageLoader.ImageLoaderCallback<T> callback : mCallbacks) {
+ for (ImageLoader.ImageLoaderCallback callback : mCallbacks) {
callback.onBitmapLoaded(scaledBitmapInfo == null ? null : scaledBitmapInfo.bitmap);
}
ImageLoader.sPendingListMap.remove(mKey);
@@ -381,7 +376,7 @@ public final class ImageLoader {
}
}
- private static final class LoadBitmapFromUriTask<T> extends LoadBitmapTask<T> {
+ private static final class LoadBitmapFromUriTask extends LoadBitmapTask {
private LoadBitmapFromUriTask(
Context context,
ImageCache imageCache,
@@ -400,7 +395,7 @@ public final class ImageLoader {
}
/** Loads and caches the logo for a given {@link TvInputInfo} */
- public static final class LoadTvInputLogoTask<T> extends LoadBitmapTask<T> {
+ public static final class LoadTvInputLogoTask extends LoadBitmapTask {
private final TvInputInfo mInfo;
public LoadTvInputLogoTask(Context context, ImageCache cache, TvInputInfo info) {
@@ -419,10 +414,9 @@ public final class ImageLoader {
@Override
public ScaledBitmapInfo doGetBitmapInBackground() {
Drawable drawable = mInfo.loadIcon(mAppContext);
- Bitmap bm =
- drawable instanceof BitmapDrawable
- ? ((BitmapDrawable) drawable).getBitmap()
- : BitmapUtils.drawableToBitmap(drawable);
+ Bitmap bm = drawable instanceof BitmapDrawable
+ ? ((BitmapDrawable) drawable).getBitmap()
+ : BitmapUtils.drawableToBitmap(drawable);
return bm == null
? null
: BitmapUtils.createScaledBitmapInfo(getKey(), bm, mMaxWidth, mMaxHeight);
@@ -434,46 +428,6 @@ public final class ImageLoader {
}
}
- /**
- * Calculates Aspect Ratio of Poster Art from Uri.
- *
- * <p><b>Note</b> the function will check the cache before loading the bitmap
- *
- * @return the Aspect Ratio of the Poster Art.
- */
- public static int getAspectRatioFromPosterArtUri(Context context, String uriString) {
- // Check the cache before loading the bitmap.
- ImageCache imageCache = ImageCache.getInstance();
- ScaledBitmapInfo bitmapInfo = imageCache.get(uriString);
- int bitmapWidth;
- int bitmapHeight;
- float bitmapAspectRatio;
- int aspectRatio;
- if (bitmapInfo == null) {
- bitmapInfo =
- BitmapUtils.decodeSampledBitmapFromUriString(
- context, uriString, Integer.MAX_VALUE, Integer.MAX_VALUE);
- }
- bitmapWidth = bitmapInfo.bitmap.getWidth();
- bitmapHeight = bitmapInfo.bitmap.getHeight();
- bitmapAspectRatio = (float) bitmapWidth / bitmapHeight;
- /* Assign nearest aspect ratio from the defined values in Preview Programs */
- if (bitmapAspectRatio > 0 && bitmapAspectRatio <= 0.6803) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_2_3;
- } else if (bitmapAspectRatio > 0.6803 && bitmapAspectRatio <= 0.8469) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_MOVIE_POSTER;
- } else if (bitmapAspectRatio > 0.8469 && bitmapAspectRatio <= 1.1667) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_1_1;
- } else if (bitmapAspectRatio > 1.1667 && bitmapAspectRatio <= 1.4167) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_4_3;
- } else if (bitmapAspectRatio > 1.4167 && bitmapAspectRatio <= 1.6389) {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_3_2;
- } else {
- aspectRatio = PreviewPrograms.ASPECT_RATIO_16_9;
- }
- return aspectRatio;
- }
-
private static synchronized Handler getMainHandler() {
if (sMainHandler == null) {
sMainHandler = new Handler(Looper.getMainLooper());