aboutsummaryrefslogtreecommitdiff
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/tv/LauncherActivity.java8
-rw-r--r--src/com/android/tv/MainActivity.java51
-rw-r--r--src/com/android/tv/SetupPassthroughActivity.java65
-rw-r--r--src/com/android/tv/TimeShiftManager.java6
-rw-r--r--src/com/android/tv/TvApplication.java96
-rw-r--r--src/com/android/tv/TvSingletons.java15
-rw-r--r--src/com/android/tv/app/LiveTvApplication.java50
-rw-r--r--src/com/android/tv/app/LiveTvModule.java31
-rw-r--r--src/com/android/tv/data/ChannelDataManager.java30
-rw-r--r--src/com/android/tv/data/PreviewDataManager.java10
-rw-r--r--src/com/android/tv/data/ProgramDataManager.java126
-rw-r--r--src/com/android/tv/data/epg/EpgFetcherImpl.java9
-rw-r--r--src/com/android/tv/data/epg/EpgInputWhiteList.java16
-rw-r--r--src/com/android/tv/data/epg/StubEpgReader.java5
-rw-r--r--src/com/android/tv/dialog/PinDialogFragment.java61
-rw-r--r--src/com/android/tv/dialog/picker/PinPicker.java18
-rw-r--r--src/com/android/tv/dialog/picker/TvPinPicker.java54
-rw-r--r--src/com/android/tv/dvr/data/ScheduledRecording.java2
-rw-r--r--src/com/android/tv/dvr/provider/DvrContract.java9
-rw-r--r--src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java7
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java6
-rw-r--r--src/com/android/tv/dvr/ui/DvrConflictFragment.java4
-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.java2
-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.java6
-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.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java8
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java4
-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/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.java17
-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.java14
-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.java4
-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.java22
-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/DvrSchedulesFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java2
-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/SchedulesHeaderRowPresenter.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java2
-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.java63
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlayer.java5
-rw-r--r--src/com/android/tv/features/TvFeatures.java14
-rw-r--r--src/com/android/tv/guide/GenreListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramGrid.java2
-rw-r--r--src/com/android/tv/guide/ProgramGuide.java19
-rw-r--r--src/com/android/tv/guide/ProgramItemView.java11
-rw-r--r--src/com/android/tv/guide/ProgramListAdapter.java2
-rw-r--r--src/com/android/tv/guide/ProgramManager.java19
-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.java39
-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/AppLinkCardView.java2
-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.java6
-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/MenuRowFactory.java17
-rw-r--r--src/com/android/tv/menu/TvOptionsRowAdapter.java11
-rw-r--r--src/com/android/tv/modules/TvApplicationModule.java39
-rw-r--r--src/com/android/tv/modules/TvSingletonsModule.java12
-rw-r--r--src/com/android/tv/onboarding/OnboardingActivity.java4
-rw-r--r--src/com/android/tv/onboarding/SetupSourcesFragment.java8
-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/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/PackageIntentsReceiver.java2
-rw-r--r--src/com/android/tv/recommendation/RecommendationDataManager.java3
-rw-r--r--src/com/android/tv/search/ProgramGuideSearchFragment.java24
-rw-r--r--src/com/android/tv/setup/SystemSetupActivity.java2
-rw-r--r--src/com/android/tv/ui/AppLayerTvView.java15
-rw-r--r--src/com/android/tv/ui/ChannelBannerView.java18
-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.java20
-rw-r--r--src/com/android/tv/ui/SelectInputView.java4
-rw-r--r--src/com/android/tv/ui/TunableTvView.java14
-rw-r--r--src/com/android/tv/ui/TvOverlayManager.java8
-rw-r--r--src/com/android/tv/ui/ViewUtils.java6
-rw-r--r--src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java61
-rw-r--r--src/com/android/tv/ui/sidepanel/SettingsFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragment.java4
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java2
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java23
-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/TvInputManagerHelper.java16
-rw-r--r--src/com/android/tv/util/TvProviderUtils.java6
-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.java42
130 files changed, 1174 insertions, 630 deletions
diff --git a/src/com/android/tv/LauncherActivity.java b/src/com/android/tv/LauncherActivity.java
index 679d612d..ccc5600a 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}, 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.
+ * 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.
*/
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 8718cac8..a018c930 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -44,6 +44,7 @@ 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;
@@ -110,7 +111,7 @@ 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.PerformanceMonitorManagerFactory;
+import com.android.tv.perf.StartupMeasureFactory;
import com.android.tv.receiver.AudioCapabilitiesReceiver;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
@@ -135,6 +136,7 @@ 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;
@@ -148,11 +150,12 @@ import com.android.tv.util.Utils;
import com.android.tv.util.ViewCache;
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.ContributesAndroidInjector;
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;
@@ -166,7 +169,7 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Provider;
-/** The main activity for the Live TV app. */
+/** The main activity for the TV app. */
public class MainActivity extends Activity
implements OnActionClickListener,
OnPinCheckedListener,
@@ -258,7 +261,7 @@ public class MainActivity extends Activity
private static final long START_UP_TIMER_RESET_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(3);
{
- PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
+ StartupMeasureFactory.create().onActivityInit();
}
private final MySingletonsImpl mMySingletons = new MySingletonsImpl();
@@ -278,8 +281,11 @@ 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;
@VisibleForTesting protected TunableTvView mTvView;
private View mContentView;
@@ -477,7 +483,6 @@ 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) {
@@ -496,6 +501,7 @@ public class MainActivity extends Activity
finishAndRemoveTask();
return;
}
+ mAccountHelper.init();
TvSingletons tvApplication = (TvSingletons) getApplication();
// In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
@@ -514,8 +520,8 @@ public class MainActivity extends Activity
return;
}
setContentView(R.layout.activity_tv);
- mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
- mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
+ mTvView = findViewById(R.id.main_tunable_tv_view);
+ mTvView.initialize(mProgramDataManager, mTvInputManagerHelper, mLegacyFlags);
mTvView.setOnUnhandledInputEventListener(
new OnUnhandledInputEventListener() {
@Override
@@ -545,6 +551,7 @@ 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));
}
@@ -612,13 +619,10 @@ public class MainActivity extends Activity
}
mTvViewUiManager =
new TvViewUiManager(
- this,
- mTvView,
- (FrameLayout) findViewById(android.R.id.content),
- mTvOptionsManager);
+ this, mTvView, findViewById(android.R.id.content), mTvOptionsManager);
mContentView = findViewById(android.R.id.content);
- ViewGroup sceneContainer = (ViewGroup) findViewById(R.id.scene_container);
+ ViewGroup sceneContainer = findViewById(R.id.scene_container);
ChannelBannerView channelBannerView =
(ChannelBannerView)
getLayoutInflater().inflate(R.layout.channel_banner, sceneContainer, false);
@@ -681,7 +685,8 @@ public class MainActivity extends Activity
inputBannerView,
selectInputView,
sceneContainer,
- mSearchFragment);
+ mSearchFragment,
+ mLegacyFlags);
mAccessibilityManager.addAccessibilityStateChangeListener(mOverlayManager);
mAudioManagerHelper = new AudioManagerHelper(this, mTvView);
@@ -740,7 +745,7 @@ public class MainActivity extends Activity
mChannelDataManager.reload();
mProgramDataManager.reload();
- // Restart live channels.
+ // Restart TV app.
Intent intent = getIntent();
finish();
startActivity(intent);
@@ -1125,8 +1130,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 Live channels
- // should go through Live channels SetupPassthroughActivity.
+ // Even though other app can handle the intent, the setup launched by TV app
+ // should go through TV app 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
@@ -1532,7 +1537,7 @@ public class MainActivity extends Activity
String inputId = mInitChannelUri.getQueryParameter("input");
long channelId = Utils.getLastWatchedChannelIdForInput(this, inputId);
if (channelId == Channel.INVALID_ID) {
- String[] projection = {Channels._ID};
+ String[] projection = {BaseColumns._ID};
long time = System.currentTimeMillis();
try (Cursor cursor =
getContentResolver().query(uri, projection, null, null, null)) {
@@ -2821,10 +2826,10 @@ public class MainActivity extends Activity
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.MyOnTuneListener.onTune");
mChannel = channel;
mWasUnderShrunkenTvView = wasUnderShrunkenTvView;
-
- if (mBackendKnobs.enablePartialProgramFetch()) {
+ if (mBackendKnobs.enablePartialProgramFetch()
+ || mBackendKnobs.fetchProgramsAsNeeded()) {
// Fetch complete projection of tuned channel.
- mProgramDataManager.prefetchChannel(channel.getId());
+ mProgramDataManager.onChannelTuned(channel.getId());
}
}
@@ -2980,5 +2985,11 @@ public class MainActivity extends Activity
public abstract static class Module {
@ContributesAndroidInjector
abstract MainActivity contributesMainActivityActivityInjector();
+
+ @ContributesAndroidInjector
+ abstract DeveloperOptionFragment contributesDeveloperOptionFragment();
+
+ @ContributesAndroidInjector
+ abstract RatingsFragment contributesRatingsFragment();
}
}
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 5185b122..95fd93d5 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -37,7 +37,10 @@ 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.
@@ -55,18 +58,19 @@ public class SetupPassthroughActivity extends Activity {
private TvInputInfo mTvInputInfo;
private Intent mActivityAfterCompletion;
private boolean mEpgFetcherDuringScan;
- private EpgInputWhiteList mEpgInputWhiteList;
+ @Inject EpgInputWhiteList mEpgInputWhiteList;
+ @Inject TvInputManagerHelper mInputManager;
+ @Inject SetupUtils mSetupUtils;
+ @Inject ChannelDataManager mChannelDataManager;
@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 = inputManager.getTvInputInfo(inputId);
- mEpgInputWhiteList = new EpgInputWhiteList(tvSingletons.getCloudEpgFlags());
+ mTvInputInfo = mInputManager.getTvInputInfo(inputId);
mActivityAfterCompletion = InputSetupActionUtils.getExtraActivityAfter(intent);
boolean needToFetchEpg =
mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId());
@@ -114,7 +118,7 @@ public class SetupPassthroughActivity extends Activity {
}
if (needToFetchEpg) {
if (sScanTimeoutMonitor == null) {
- sScanTimeoutMonitor = new ScanTimeoutMonitor(this);
+ sScanTimeoutMonitor = new ScanTimeoutMonitor(this, mChannelDataManager);
}
sScanTimeoutMonitor.startMonitoring();
TvSingletons.getSingletons(this).getEpgFetcher().onChannelScanStarted();
@@ -142,6 +146,16 @@ public class SetupPassthroughActivity extends Activity {
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)) {
+ epgFetcher.fetchImmediately();
+ }
+ }
+
if (mTvInputInfo == null) {
Log.w(
TAG,
@@ -152,21 +166,19 @@ public class SetupPassthroughActivity extends Activity {
finish();
return;
}
- 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();
- });
+ mSetupUtils.onTvInputSetupFinished(
+ mTvInputInfo.getId(),
+ () -> {
+ if (mActivityAfterCompletion != null) {
+ try {
+ startActivity(mActivityAfterCompletion);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity launch failed", e);
+ }
+ }
+ setResult(resultCode, data);
+ finish();
+ });
}
/**
@@ -207,9 +219,9 @@ public class SetupPassthroughActivity extends Activity {
};
private boolean mStarted;
- private ScanTimeoutMonitor(Context context) {
+ private ScanTimeoutMonitor(Context context, ChannelDataManager mChannelDataManager) {
mContext = context.getApplicationContext();
- mChannelDataManager = TvSingletons.getSingletons(context).getChannelDataManager();
+ this.mChannelDataManager = mChannelDataManager;
}
private void startMonitoring() {
@@ -240,4 +252,11 @@ public class SetupPassthroughActivity extends Activity {
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 779e8df6..c165af33 100644
--- a/src/com/android/tv/TimeShiftManager.java
+++ b/src/com/android/tv/TimeShiftManager.java
@@ -50,7 +50,7 @@ import java.util.Queue;
import java.util.concurrent.TimeUnit;
/**
- * A class which manages the time shift feature in Live TV. It consists of two parts. {@link
+ * A class which manages the time shift feature in TV app. 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
@@ -144,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 Live TV. 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 TV app. 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;
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index 5f25a24b..65a3d928 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -47,6 +47,7 @@ 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.EpgFetcherImpl;
+import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
@@ -56,8 +57,9 @@ 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.PerformanceMonitorManager;
-import com.android.tv.perf.PerformanceMonitorManagerFactory;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.StartupMeasure;
+import com.android.tv.perf.StartupMeasureFactory;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.RecordedProgramPreviewUpdater;
import com.android.tv.tunerinputcontroller.BuiltInTunerManager;
@@ -68,25 +70,23 @@ 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;
/**
- * Live TV application.
+ * TV application.
*
* <p>This includes all the Google specific hooks.
*/
public abstract class TvApplication extends BaseApplication implements TvSingletons, Starter {
- protected static final PerformanceMonitorManager PERFORMANCE_MONITOR_MANAGER =
- PerformanceMonitorManagerFactory.create();
+ protected static final StartupMeasure STARTUP_MEASURE = StartupMeasureFactory.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
@@ -102,7 +102,7 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
private SelectInputActivity mSelectInputActivity;
- private ChannelDataManager mChannelDataManager;
+ @Inject Lazy<ChannelDataManager> mChannelDataManager;
private volatile ProgramDataManager mProgramDataManager;
private PreviewDataManager mPreviewDataManager;
private DvrManager mDvrManager;
@@ -122,6 +122,11 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
@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() {
@@ -132,6 +137,8 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
throw new IllegalStateException(msg);
}
super.onCreate();
+ mPerformanceMonitor.startMemoryMonitor();
+ mPerformanceMonitor.startCrashMonitor();
SharedPreferencesUtils.initialize(
this,
() -> {
@@ -146,16 +153,16 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
Log.w(TAG, "Unable to find package '" + getPackageName() + "'.", e);
mVersionName = "";
}
- Log.i(TAG, "Starting Live TV " + getVersionName());
+ Log.i(TAG, "Starting TV app " + 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);
+ mEpgFetcher = EpgFetcherImpl.create(this, mCloudEpgFlags, mLegacyFlags);
SetupAnimationHelper.initialize(this);
getTvInputManagerHelper();
- Log.i(TAG, "Started Live TV " + mVersionName);
+ Log.i(TAG, "Started TV app " + mVersionName);
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.onCreate");
}
@@ -210,8 +217,10 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
mEpgFetcher.startRoutineService();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ChannelPreviewUpdater.getInstance(this).startRoutineService();
- RecordedProgramPreviewUpdater.getInstance(this)
- .updatePreviewDataForRecordedPrograms();
+ if (CommonFeatures.DVR.isEnabled(this)) {
+ RecordedProgramPreviewUpdater.getInstance(this)
+ .updatePreviewDataForRecordedPrograms();
+ }
}
}
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.start");
@@ -286,16 +295,12 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
/** Returns {@link ChannelDataManager}. */
@Override
public ChannelDataManager getChannelDataManager() {
- if (mChannelDataManager == null) {
- mChannelDataManager = new ChannelDataManager(this, getTvInputManagerHelper());
- mChannelDataManager.start();
- }
- return mChannelDataManager;
+ return mChannelDataManager.get();
}
@Override
public boolean isChannelDataManagerLoadFinished() {
- return mChannelDataManager != null && mChannelDataManager.isDbLoadFinished();
+ return mChannelDataManager.get().isDbLoadFinished();
}
/** Returns {@link ProgramDataManager}. */
@@ -351,6 +356,11 @@ 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() {
@@ -450,7 +460,7 @@ public abstract class TvApplication extends BaseApplication implements TvSinglet
}
/**
- * Returns the version name of the live channels.
+ * Returns the version name of the TV app.
*
* @see PackageInfo#versionName
*/
@@ -489,6 +499,37 @@ 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) {
@@ -515,13 +556,24 @@ 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") + " Live TV.");
+ Log.i(TAG, (enable ? "Un-hide" : "Hide") + " TV app.");
}
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 20edf3d4..8f9fd25e 100644
--- a/src/com/android/tv/TvSingletons.java
+++ b/src/com/android/tv/TvSingletons.java
@@ -21,7 +21,6 @@ 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;
@@ -38,9 +37,9 @@ import com.android.tv.tunerinputcontroller.HasBuiltInTunerManager;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.account.AccountHelper;
+import dagger.Lazy;
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 {
@@ -80,6 +79,8 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
PreviewDataManager getPreviewDataManager();
+ /** @deprecated use injection instead. */
+ @Deprecated
DvrDataManager getDvrDataManager();
DvrScheduleManager getDvrScheduleManager();
@@ -88,6 +89,8 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
RecordingScheduler getRecordingScheduler();
+ /** @deprecated use injection instead. */
+ @Deprecated
DvrWatchedPositionManager getDvrWatchedPositionManager();
InputSessionManager getInputSessionManager();
@@ -96,17 +99,21 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
MainActivityWrapper getMainActivityWrapper();
+ /** @deprecated use injection instead. */
+ @Deprecated
AccountHelper getAccountHelper();
boolean isRunningInMainProcess();
+ /** @deprecated use injection instead. */
+ @Deprecated
PerformanceMonitor getPerformanceMonitor();
/** @deprecated use injection instead. */
@Deprecated
TvInputManagerHelper getTvInputManagerHelper();
- Provider<EpgReader> providesEpgReader();
+ Lazy<EpgReader> providesEpgReader();
EpgFetcher getEpgFetcher();
@@ -114,8 +121,6 @@ public interface TvSingletons extends BaseSingletons, HasBuiltInTunerManager, Ha
@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 38e85e48..dcd4a66d 100644
--- a/src/com/android/tv/app/LiveTvApplication.java
+++ b/src/com/android/tv/app/LiveTvApplication.java
@@ -22,50 +22,35 @@ 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.Provider;
+import javax.inject.Inject;
/** The top level application for Live TV. */
public class LiveTvApplication extends TvApplication implements HasSingletons<TvSingletons> {
static {
- PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppClassLoaded();
+ STARTUP_MEASURE.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;
+ @Inject AccountHelper mAccountHelper;
private Analytics mAnalytics;
private Tracker mTracker;
- private ExperimentLoader mExperimentLoader;
- private PerformanceMonitor mPerformanceMonitor;
+ @Inject PerformanceMonitor mPerformanceMonitor;
@Override
protected AndroidInjector<LiveTvApplication> applicationInjector() {
@@ -78,38 +63,20 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
@Override
public void onCreate() {
super.onCreate();
- PERFORMANCE_MONITOR_MANAGER.getStartupMeasure().onAppCreate(this);
+ STARTUP_MEASURE.onAppCreate(this);
}
- /** Returns the {@link AccountHelperImpl}. */
@Override
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);
- }
+ public PerformanceMonitor getPerformanceMonitor() {
return mPerformanceMonitor;
}
@Override
- public Provider<EpgReader> providesEpgReader() {
- return mEpgReaderProvider;
- }
-
- @Override
- public ExperimentLoader getExperimentLoader() {
- mExperimentLoader = new ExperimentLoader();
- return mExperimentLoader;
- }
-
- @Override
public DefaultBackendKnobsFlags getBackendKnobs() {
return mBackendKnobsFlags;
}
@@ -148,11 +115,6 @@ public class LiveTvApplication extends TvApplication implements HasSingletons<Tv
}
@Override
- public BuildType getBuildType() {
- return BuildType.AOSP;
- }
-
- @Override
public DefaultConcurrentDvrPlaybackFlags getConcurrentDvrPlaybackFlags() {
return mConcurrentDvrPlaybackFlags;
}
diff --git a/src/com/android/tv/app/LiveTvModule.java b/src/com/android/tv/app/LiveTvModule.java
index a28749bd..db631bc0 100644
--- a/src/com/android/tv/app/LiveTvModule.java
+++ b/src/com/android/tv/app/LiveTvModule.java
@@ -16,18 +16,49 @@
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/ChannelDataManager.java b/src/com/android/tv/data/ChannelDataManager.java
index a5c786cf..67c32309 100644
--- a/src/com/android/tv/data/ChannelDataManager.java
+++ b/src/com/android/tv/data/ChannelDataManager.java
@@ -37,15 +37,18 @@ 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;
@@ -56,6 +59,7 @@ 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
@@ -64,6 +68,8 @@ import java.util.concurrent.Executor;
* 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;
@@ -143,21 +149,11 @@ public class ChannelDataManager {
};
@MainThread
- 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) {
+ public ChannelDataManager(
+ @Provided @ApplicationContext Context context,
+ @Provided TvInputManagerHelper inputManager,
+ @Provided @DbExecutor Executor executor,
+ @Provided ContentResolver contentResolver) {
mContext = context;
mInputManager = inputManager;
mDbExecutor = executor;
@@ -729,7 +725,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 TvSingletons#getDbExecutor()}.
+ * operations will run on @{@link DbExecutor}.
*/
private void updateOneColumnValue(
final String columnName, final int columnValue, final List<Long> ids) {
diff --git a/src/com/android/tv/data/PreviewDataManager.java b/src/com/android/tv/data/PreviewDataManager.java
index 8616aeec..91aca09a 100644
--- a/src/com/android/tv/data/PreviewDataManager.java
+++ b/src/com/android/tv/data/PreviewDataManager.java
@@ -36,6 +36,7 @@ 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;
@@ -428,10 +429,14 @@ public class PreviewDataManager {
continue;
}
try {
+ int aspectRatio =
+ ImageLoader.getAspectRatioFromPosterArtUri(
+ mContext, program.getPosterArtUri().toString());
Uri programUri =
mContentResolver.insert(
TvContract.PreviewPrograms.CONTENT_URI,
- PreviewDataUtils.createPreviewProgramFromContent(program)
+ PreviewDataUtils.createPreviewProgramFromContent(
+ program, aspectRatio)
.toContentValues());
if (programUri != null) {
long previewProgramId = ContentUris.parseId(programUri);
@@ -592,13 +597,14 @@ public class PreviewDataManager {
/** Creates a preview program. */
public static PreviewProgram createPreviewProgramFromContent(
- PreviewProgramContent program) {
+ PreviewProgramContent program, int aspectRatio) {
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/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index bd74cf34..8b38060a 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -76,6 +76,11 @@ 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";
@@ -128,6 +133,11 @@ 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) {
@@ -266,17 +276,79 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- public void prefetchChannel(long channelId) {
- if (mCompleteInfoChannelIds.add(channelId)) {
- long startTimeMs =
- Utils.floorTime(
- mClock.currentTimeMillis() - PROGRAM_GUIDE_SNAP_TIME_MS,
- PROGRAM_GUIDE_SNAP_TIME_MS);
- long endTimeMs = startTimeMs + TimeUnit.HOURS.toMillis(getFetchDuration());
- new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs).executeOnDbThread();
+ /**
+ * 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);
+
+ if (!mBackendKnobsFlags.fetchProgramsAsNeeded()) {
+ if (mCompleteInfoChannelIds.add(channelId)) {
+ long endTimeMs = startTimeMs + TimeUnit.HOURS.toMillis(getFetchDuration());
+ mCompleteInfoChannelIds.clear();
+ new SingleChannelPrefetchTask(channelId, startTimeMs, endTimeMs)
+ .executeOnDbThread();
+ }
+ } else {
+ 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();
+ }
}
}
+ /**
+ * 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) {
+ long marginEndTime = startTimeMs + mMaxFetchHoursMs - BUFFER_HOURS_MS;
+ return (mChannelIdProgramCache.containsKey(channelId)
+ && mChannelIdProgramCache.get(channelId).size() > selectedProgramIndex
+ && mChannelIdProgramCache
+ .get(channelId)
+ .get(selectedProgramIndex)
+ .getEndTimeUtcMillis()
+ > marginEndTime);
+ }
+
+ public void onChannelTuned(long channelId) {
+ mTunedChannelId = channelId;
+ prefetchChannel(channelId, 0);
+ }
+
/** A Callback interface to receive notification on program data retrieval from DB. */
public interface Callback {
/**
@@ -293,6 +365,12 @@ public class ProgramDataManager implements MemoryManageable {
* @param channelId
*/
void onSingleChannelUpdated(long channelId);
+
+ /**
+ * 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.
+ */
+ void onChannelUpdated();
}
/** Adds the {@link Callback}. */
@@ -319,7 +397,7 @@ public class ProgramDataManager implements MemoryManageable {
} else {
mPrefetchEnabled = false;
cancelPrefetchTask();
- mChannelIdProgramCache.clear();
+ clearChannelInfoMap();
mHandler.removeMessages(MSG_UPDATE_PREFETCH_PROGRAM);
}
}
@@ -548,6 +626,7 @@ public class ProgramDataManager implements MemoryManageable {
String[] projection =
mBackendKnobsFlags.enablePartialProgramFetch()
+ || mBackendKnobsFlags.fetchProgramsAsNeeded()
? Program.PARTIAL_PROJECTION
: Program.PROJECTION;
if (TvProviderUtils.checkSeriesIdColumn(mContext, Programs.CONTENT_URI)) {
@@ -636,13 +715,19 @@ public class ProgramDataManager implements MemoryManageable {
PROGRAM_GUIDE_SNAP_TIME_MS)
- currentTime;
// Issue second pre-fetch immediately after the first partial update
- if (mChannelIdProgramCache.isEmpty()) {
+ if (!mBackendKnobsFlags.fetchProgramsAsNeeded()
+ && mChannelIdProgramCache.isEmpty()) {
nextMessageDelayedTime = 0;
}
mChannelIdProgramCache = programs;
- if (mBackendKnobsFlags.enablePartialProgramFetch()) {
+ if (mBackendKnobsFlags.enablePartialProgramFetch()
+ || mBackendKnobsFlags.fetchProgramsAsNeeded()) {
// Since cache has partial data we need to reset the map of complete data.
- mCompleteInfoChannelIds.clear();
+ clearChannelInfoMap();
+ // Get complete projection of tuned channel.
+ if (mBackendKnobsFlags.fetchProgramsAsNeeded()) {
+ prefetchChannel(mTunedChannelId, 0);
+ }
}
notifyProgramUpdated();
if (mFromEmptyCacheTimeEvent != null) {
@@ -661,6 +746,11 @@ 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());
@@ -712,7 +802,11 @@ public class ProgramDataManager implements MemoryManageable {
@Override
protected void onPostExecute(ArrayList<Program> programs) {
mChannelIdProgramCache.put(mChannelId, programs);
- notifySingleChannelUpdated(mChannelId);
+ if (mBackendKnobsFlags.fetchProgramsAsNeeded()) {
+ notifyChannelUpdated();
+ } else {
+ notifySingleChannelUpdated(mChannelId);
+ }
}
}
@@ -728,6 +822,12 @@ public class ProgramDataManager implements MemoryManageable {
}
}
+ private void notifyChannelUpdated() {
+ for (Callback callback : mCallbacks) {
+ callback.onChannelUpdated();
+ }
+ }
+
private class ProgramsUpdateTask extends AsyncDbTask.AsyncQueryTask<List<Program>> {
public ProgramsUpdateTask(long time) {
super(
diff --git a/src/com/android/tv/data/epg/EpgFetcherImpl.java b/src/com/android/tv/data/epg/EpgFetcherImpl.java
index b191421f..b40ce0d2 100644
--- a/src/com/android/tv/data/epg/EpgFetcherImpl.java
+++ b/src/com/android/tv/data/epg/EpgFetcherImpl.java
@@ -63,6 +63,8 @@ import com.google.android.tv.partner.support.EpgInput;
import com.google.android.tv.partner.support.EpgInputs;
import com.google.common.collect.ImmutableSet;
import com.android.tv.common.flags.BackendKnobsFlags;
+import com.android.tv.common.flags.CloudEpgFlags;
+import com.android.tv.common.flags.LegacyFlags;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -130,15 +132,15 @@ public class EpgFetcherImpl implements EpgFetcher {
private Clock mClock;
- public static EpgFetcher create(Context context) {
+ public static EpgFetcher create(
+ Context context, CloudEpgFlags cloudEpgFlags, LegacyFlags legacyFlags) {
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());
+ EpgInputWhiteList epgInputWhiteList = new EpgInputWhiteList(cloudEpgFlags, legacyFlags);
BackendKnobsFlags backendKnobsFlags = tvSingletons.getBackendKnobs();
HasBuildType.BuildType buildType = tvSingletons.getBuildType();
return new EpgFetcherImpl(
@@ -604,6 +606,7 @@ 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 24b4fe3d..4a5f98bb 100644
--- a/src/com/android/tv/data/epg/EpgInputWhiteList.java
+++ b/src/com/android/tv/data/epg/EpgInputWhiteList.java
@@ -21,13 +21,14 @@ 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 {
@@ -36,6 +37,7 @@ 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
@@ -43,10 +45,12 @@ public final class EpgInputWhiteList {
return inputId == null ? null : inputId.substring(0, inputId.indexOf("/"));
}
- private final CloudEpgFlags cloudEpgFlags;
+ private final CloudEpgFlags mCloudEpgFlags;
- public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags) {
- this.cloudEpgFlags = cloudEpgFlags;
+ @Inject
+ public EpgInputWhiteList(CloudEpgFlags cloudEpgFlags, LegacyFlags legacyFlags) {
+ mCloudEpgFlags = cloudEpgFlags;
+ mLegacyFlags = legacyFlags;
}
public boolean isInputWhiteListed(String inputId) {
@@ -71,8 +75,8 @@ public final class EpgInputWhiteList {
}
private Set<String> getWhiteListedInputs() {
- Set<String> result = toInputSet(cloudEpgFlags.thirdPartyEpgInputsCsv());
- if (BuildConfig.ENG || Experiments.ENABLE_QA_FEATURES.get()) {
+ Set<String> result = toInputSet(mCloudEpgFlags.thirdPartyEpgInputsCsv());
+ if (BuildConfig.ENG || mLegacyFlags.enableQaFeatures()) {
HashSet<String> moreInputs = new HashSet<>(toInputSet(QA_DEV_INPUTS));
if (result.isEmpty()) {
result = moreInputs;
diff --git a/src/com/android/tv/data/epg/StubEpgReader.java b/src/com/android/tv/data/epg/StubEpgReader.java
index 3b001481..bb069dba 100644
--- a/src/com/android/tv/data/epg/StubEpgReader.java
+++ b/src/com/android/tv/data/epg/StubEpgReader.java
@@ -16,7 +16,6 @@
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;
@@ -27,10 +26,12 @@ 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 {
- public StubEpgReader(@SuppressWarnings("unused") Context context) {}
+ @Inject
+ public StubEpgReader() {}
@Override
public boolean isAvailable() {
diff --git a/src/com/android/tv/dialog/PinDialogFragment.java b/src/com/android/tv/dialog/PinDialogFragment.java
index 87308093..ad245fad 100644
--- a/src/com/android/tv/dialog/PinDialogFragment.java
+++ b/src/com/android/tv/dialog/PinDialogFragment.java
@@ -18,6 +18,7 @@ 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;
@@ -33,10 +34,14 @@ 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.PinPicker;
+import com.android.tv.dialog.picker.TvPinPicker;
+import com.android.tv.util.TvInputManagerHelper;
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";
@@ -80,7 +85,9 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private TextView mWrongPinView;
private View mEnterPinView;
private TextView mTitleView;
+
private PinPicker mPicker;
+ private TvPinPicker mTvPinPicker;
private SharedPreferences mSharedPreferences;
private String mPrevPin;
private String mPin;
@@ -88,6 +95,8 @@ 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);
@@ -103,6 +112,12 @@ 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);
@@ -155,13 +170,26 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mEnterPinView = v.findViewById(R.id.enter_pin);
mTitleView = (TextView) mEnterPinView.findViewById(R.id.title);
mPicker = v.findViewById(R.id.pin_picker);
- mPicker.setOnClickListener(
- view -> {
- String pin = getPinInput();
- if (!TextUtils.isEmpty(pin)) {
- done(pin);
- }
- });
+ mTvPinPicker = v.findViewById(R.id.tv_pin_picker);
+ if (!mUiFlags.useLeanbackPinPicker()) {
+ mTvPinPicker.setVisibility(View.GONE);
+ mPicker.setOnClickListener(
+ view -> {
+ String pin = getPinInput();
+ if (!TextUtils.isEmpty(pin)) {
+ done(pin);
+ }
+ });
+ } else {
+ mPicker.setVisibility(View.GONE);
+ mTvPinPicker.setOnClickListener(
+ view -> {
+ String pin = getPinInput();
+ if (!TextUtils.isEmpty(pin)) {
+ done(pin);
+ }
+ });
+ }
if (TextUtils.isEmpty(getPin())) {
// If PIN isn't set, user should set a PIN.
// Successfully setting a new set is considered as entering correct PIN.
@@ -183,8 +211,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mTitleView.setText(
getString(
R.string.pin_enter_unlock_dvr,
- TvSingletons.getSingletons(getContext())
- .getTvInputManagerHelper()
+ mTvInputManagerHelper
.getContentRatingsManager()
.getDisplayNameForRating(tvContentRating)));
}
@@ -204,7 +231,11 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
if (mType != PIN_DIALOG_TYPE_NEW_PIN) {
updateWrongPin();
}
- mPicker.requestFocus();
+ if (!mUiFlags.useLeanbackPinPicker()) {
+ mPicker.requestFocus();
+ } else {
+ mTvPinPicker.requestFocus();
+ }
return v;
}
@@ -338,11 +369,15 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private String getPinInput() {
- return mPicker.getPinInput();
+ return (mUiFlags.useLeanbackPinPicker() ? mTvPinPicker.getPin() : mPicker.getPinInput());
}
private void resetPinInput() {
- mPicker.resetPinInput();
+ if (!mUiFlags.useLeanbackPinPicker()) {
+ mPicker.resetPinInput();
+ } else {
+ mTvPinPicker.resetPin();
+ }
}
/**
diff --git a/src/com/android/tv/dialog/picker/PinPicker.java b/src/com/android/tv/dialog/picker/PinPicker.java
index f501dfd1..7af62585 100644
--- a/src/com/android/tv/dialog/picker/PinPicker.java
+++ b/src/com/android/tv/dialog/picker/PinPicker.java
@@ -15,15 +15,18 @@
*/
package com.android.tv.dialog.picker;
+import static android.content.Context.ACCESSIBILITY_SERVICE;
+
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 androidx.leanback.widget.picker.Picker;
+import androidx.leanback.widget.picker.PickerColumn;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
import java.util.ArrayList;
import java.util.List;
@@ -33,6 +36,8 @@ public final class PinPicker extends Picker {
private final List<PickerColumn> mPickers = new ArrayList<>();
private OnClickListener mOnClickListener;
+ private boolean mSkipPerformClick = true;
+ private boolean mIsAccessibilityEnabled = false;
// the version of picker I link to does not have this constructor
public PinPicker(Context context, AttributeSet attributeSet) {
@@ -53,6 +58,9 @@ public final class PinPicker extends Picker {
setColumns(mPickers);
setActivated(true);
setFocusable(true);
+ AccessibilityManager am =
+ (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
+ mIsAccessibilityEnabled = am.isEnabled();
super.setOnClickListener(this::onClick);
}
@@ -76,6 +84,12 @@ public final class PinPicker extends Picker {
private void onClick(View v) {
int selectedColumn = getSelectedColumn();
+ // (b/120096347) Skip first click when talkback is enabled
+ if (mSkipPerformClick && mIsAccessibilityEnabled) {
+ mSkipPerformClick = false;
+ /* Force focus to next value */
+ setColumnValue(selectedColumn, 1, true);
+ }
int nextColumn = selectedColumn + 1;
// Only call the click listener if we are on the last column
// Otherwise move to the next column
diff --git a/src/com/android/tv/dialog/picker/TvPinPicker.java b/src/com/android/tv/dialog/picker/TvPinPicker.java
new file mode 100644
index 00000000..064b7f02
--- /dev/null
+++ b/src/com/android/tv/dialog/picker/TvPinPicker.java
@@ -0,0 +1,54 @@
+/*
+ * 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/data/ScheduledRecording.java b/src/com/android/tv/dvr/data/ScheduledRecording.java
index ba6d3cf9..7833f6f3 100644
--- a/src/com/android/tv/dvr/data/ScheduledRecording.java
+++ b/src/com/android/tv/dvr/data/ScheduledRecording.java
@@ -492,7 +492,7 @@ public final class ScheduledRecording implements Parcelable {
}
};
- /** The ID internal to Live TV */
+ /** The ID internal to TV app */
private long mId;
/**
diff --git a/src/com/android/tv/dvr/provider/DvrContract.java b/src/com/android/tv/dvr/provider/DvrContract.java
index a5f2e2cd..8539ae36 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 Live TV.
+ * columns. It's for the internal use in TV app.
*/
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,8 +84,7 @@ 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/recorder/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
index 696038cf..e8f077ca 100644
--- a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
+++ b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
@@ -43,6 +43,7 @@ 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;
@@ -54,7 +55,6 @@ 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
@@ -529,10 +529,9 @@ public class SeriesRecordingScheduler {
private class FetchSeriesInfoTask extends AsyncTask<Void, Void, SeriesInfo> {
private final SeriesRecording mSeriesRecording;
- private final Provider<EpgReader> mEpgReaderProvider;
+ private final Lazy<EpgReader> mEpgReaderProvider;
- FetchSeriesInfoTask(
- SeriesRecording seriesRecording, Provider<EpgReader> epgReaderProvider) {
+ FetchSeriesInfoTask(SeriesRecording seriesRecording, Lazy<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 5e3caa9c..a0daf5e7 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
@@ -22,8 +22,8 @@ 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 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.Program;
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
index a6bbe137..bde896a8 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
@@ -22,8 +22,8 @@ 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 androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
index 6be35cb2..b24281ad 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 android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
+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;
diff --git a/src/com/android/tv/dvr/ui/DvrConflictFragment.java b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
index 649cc89a..31ef7339 100644
--- a/src/com/android/tv/dvr/ui/DvrConflictFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
@@ -21,8 +21,8 @@ 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 androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java b/src/com/android/tv/dvr/ui/DvrGuidedActionsStylist.java
index 611962d0..81fc3ed5 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 android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.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 a900cc70..fda4cdee 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 android.support.v17.leanback.widget.GuidanceStylist;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.VerticalGridView;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.leanback.widget.GuidedAction;
+import androidx.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 e6b54f67..608a5f8e 100644
--- a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
@@ -20,7 +20,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
+import androidx.leanback.app.GuidedStepFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
index 6fba4d98..01631b99 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 android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
+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;
diff --git a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
index 02b2da1d..3237acd7 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 android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.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 5bb97e90..ae41f501 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 android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
+import androidx.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 72603d03..613484d5 100644
--- a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
@@ -22,9 +22,9 @@ 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 androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
index a237f1d2..730237c4 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
@@ -20,15 +20,13 @@ import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import android.support.v17.leanback.app.GuidedStepFragment;
+import androidx.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;
@@ -70,7 +68,7 @@ public class DvrSeriesDeletionActivity extends Activity {
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
deleteSelectedIds(true);
} else {
- // NOTE: If Live TV ever supports both embedded and separate DVR inputs
+ // NOTE: If TV app ever supports both embedded and separate DVR inputs
// then we should try to do the delete regardless.
Log.i(
TAG,
@@ -93,14 +91,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 ff213231..10ef226b 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 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 androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
+import androidx.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 9acb5b5e..d72099ba 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 android.support.v17.leanback.app.GuidedStepFragment;
+import androidx.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 c6e26850..6cb8c1ad 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
@@ -20,8 +20,8 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.support.v17.leanback.widget.GuidanceStylist;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.data.Program;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
index 1a51cf46..48bacf35 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
@@ -19,7 +19,7 @@ package com.android.tv.dvr.ui;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
+import androidx.leanback.app.GuidedStepFragment;
import com.android.tv.R;
import com.android.tv.Starter;
import com.android.tv.common.SoftPreconditions;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
index eadb3b9e..f191582e 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
@@ -21,10 +21,10 @@ 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 androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidedActionsStylist;
import android.util.LongSparseArray;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
index 1ab4c500..ca2d8f89 100644
--- a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
@@ -23,8 +23,8 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrDataManager;
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingDialogFragment.java
index 15abf902..4a8ce04e 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 android.support.v17.leanback.app.GuidedStepFragment;
+import androidx.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 99211fdb..0b8f5df0 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 android.support.v17.leanback.widget.GuidanceStylist;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.leanback.widget.GuidedAction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java b/src/com/android/tv/dvr/ui/DvrWriteStoragePermissionRationaleFragment.java
index c93f5831..25f7f38b 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 android.support.v17.leanback.widget.GuidanceStylist;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.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 1eb8080a..7a26d5ed 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 android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.PresenterSelector;
+import androidx.leanback.widget.ArrayObjectAdapter;
+import androidx.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 0172f76f..c0a57c0f 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 android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.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 41ace9a4..a06705c6 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 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 androidx.leanback.R;
+import androidx.leanback.widget.Action;
+import androidx.leanback.widget.Presenter;
+import androidx.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 8c311d68..ed548728 100644
--- a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
@@ -19,12 +19,11 @@ package com.android.tv.dvr.ui.browse;
import android.content.Context;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import androidx.leanback.widget.Action;
+import androidx.leanback.widget.OnActionClickedListener;
+import androidx.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;
@@ -33,7 +32,9 @@ 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 com.android.tv.common.flags.ConcurrentDvrPlaybackFlags;
+import javax.inject.Inject;
/** {@link RecordingDetailsFragment} for current recording in DVR. */
public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
@@ -43,8 +44,8 @@ public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
private DvrDataManager mDvrDataManger;
private RecordedProgram mRecordedProgram;
- private DvrWatchedPositionManager mDvrWatchedPositionManager;
- private ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
+ @Inject DvrWatchedPositionManager mDvrWatchedPositionManager;
+ @Inject ConcurrentDvrPlaybackFlags mConcurrentDvrPlaybackFlags;
private boolean mPaused;
private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
new DvrDataManager.ScheduledRecordingListener() {
@@ -76,12 +77,10 @@ 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
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
index 6b5fd1fd..fafc70cf 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 android.support.v17.leanback.widget.Presenter;
+import androidx.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
- * android.support.v17.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
- * originated from {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
+ * androidx.leanback.widget.DetailsOverviewRowPresenter}. Most codes of this class is
+ * originated from {@link androidx.leanback.widget.AbstractDetailsDescriptionPresenter}.
* The latter class are re-used to provide a customized version of {@link
- * android.support.v17.leanback.widget.DetailsOverviewRow}.
+ * androidx.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 4e41daee..8a4c7854 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 android.support.v17.leanback.app.BackgroundManager;
+import androidx.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 5743ea5c..7262b4a0 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.PerformanceMonitorManagerFactory;
+import com.android.tv.perf.StartupMeasureFactory;
/** {@link android.app.Activity} for DVR UI. */
public class DvrBrowseActivity extends Activity {
{
- PerformanceMonitorManagerFactory.create().getStartupMeasure().onActivityInit();
+ StartupMeasureFactory.create().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 3251200f..276bc114 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
@@ -21,14 +21,14 @@ import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v17.leanback.app.BrowseFragment;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.TitleViewAdapter;
import android.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.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
index f90981f0..a38180a5 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 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 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.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 4298d86a..ebdee32f 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 android.support.v17.leanback.widget.Presenter;
+import androidx.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 a2d1cb28..625f8f76 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 android.support.v17.leanback.widget.ListRowPresenter;
+import androidx.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 bf963547..5f58af8e 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 android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import androidx.leanback.widget.Action;
+import androidx.leanback.widget.OnActionClickedListener;
+import androidx.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 android.support.v17.leanback.app.DetailsFragment} for recorded program in DVR. */
+/** {@link androidx.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 2ffad327..ac7c5745 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
+++ b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
@@ -23,7 +23,6 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
-import android.support.v17.leanback.widget.BaseCardView;
import android.text.Layout;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -33,6 +32,7 @@ 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 +44,7 @@ import com.android.tv.util.images.ImageLoader;
*/
public class RecordingCardView extends BaseCardView {
// This value should be the same with
- // android.support.v17.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
+ // androidx.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
private static final int ANIMATION_DURATION = 150;
private final ImageView mImageView;
private final int mImageWidth;
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
index 243681c6..e85f983f 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 android.support.v17.leanback.app.DetailsFragment;
+import androidx.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 f08bb12b..7ef8e59f 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 android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import androidx.leanback.widget.Action;
+import androidx.leanback.widget.OnActionClickedListener;
+import androidx.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 9104ef10..7c1e1164 100644
--- a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
@@ -21,17 +21,17 @@ 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 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 android.text.TextUtils;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
index 77a63508..293e1d94 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 android.support.v17.leanback.app.DetailsFragment;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
+import androidx.leanback.app.DetailsFragment;
+import androidx.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 0ca05fac..1d93c8cb 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
@@ -17,23 +17,24 @@
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;
@@ -48,11 +49,17 @@ public class DvrHistoryFragment extends DetailsFragment
presenterSelector.addClassPresenter(
ScheduleRow.class, new ScheduleRowPresenter(getContext()));
TvSingletons singletons = TvSingletons.getSingletons(getContext());
- mRowsAdapter = new DvrHistoryRowAdapter(
- getContext(), presenterSelector, singletons.getClock());
+ UiFlags uiFlags = singletons.getUiFlags();
+ mDvrDataManager = singletons.getDvrDataManager();
+ mRowsAdapter =
+ new DvrHistoryRowAdapter(
+ getContext(),
+ presenterSelector,
+ singletons.getClock(),
+ mDvrDataManager,
+ uiFlags);
setAdapter(mRowsAdapter);
mRowsAdapter.start();
- mDvrDataManager = singletons.getDvrDataManager();
mDvrDataManager.addScheduledRecordingListener(this);
mDvrDataManager.addRecordedProgramListener(this);
mEmptyInfoScreenView = (TextView) getActivity().findViewById(R.id.empty_info_screen);
@@ -135,7 +142,6 @@ 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 156d1a7e..a10367fb 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
@@ -20,20 +20,19 @@ 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;
@@ -48,8 +47,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;
@@ -57,11 +56,16 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private final Map<Long, ScheduledRecording> mRecordedProgramScheduleMap = new HashMap<>();
public DvrHistoryRowAdapter(
- Context context, ClassPresenterSelector classPresenterSelector, Clock clock) {
+ Context context,
+ ClassPresenterSelector classPresenterSelector,
+ Clock clock,
+ DvrDataManager dvrDataManager,
+ UiFlags uiFlags) {
super(classPresenterSelector);
mContext = context;
mClock = clock;
- mDvrDataManager = TvSingletons.getSingletons(mContext).getDvrDataManager();
+ mDvrDataManager = dvrDataManager;
+ mMaxHistoryDays = uiFlags.maxHistoryDays();
mTitles.add(mContext.getString(R.string.dvr_date_today));
mTitles.add(mContext.getString(R.string.dvr_date_yesterday));
}
@@ -78,9 +82,9 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
List<RecordedProgram> recordedProgramList = mDvrDataManager.getRecordedPrograms();
recordingList.addAll(
- recordedProgramsToScheduledRecordings(recordedProgramList, MAX_HISTORY_DAYS));
- recordingList
- .sort(ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
+ recordedProgramsToScheduledRecordings(recordedProgramList, mMaxHistoryDays));
+ 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<>();
@@ -128,7 +132,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
}
private List<ScheduledRecording> recordedProgramsToScheduledRecordings(
- List<RecordedProgram> programs, int maxDays) {
+ List<RecordedProgram> programs, long maxDays) {
List<ScheduledRecording> result = new ArrayList<>();
for (RecordedProgram recordedProgram : programs) {
ScheduledRecording scheduledRecording =
@@ -142,12 +146,12 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
@Nullable
private ScheduledRecording recordedProgramsToScheduledRecordings(
- RecordedProgram program, int maxDays) {
+ RecordedProgram program, long maxDays) {
long firstMillisecondToday = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
- if (maxDays
- < Utils.computeDateDifference(
- program.getStartTimeUtcMillis(),
- firstMillisecondToday)) {
+ if (maxDays != 0
+ && maxDays
+ < Utils.computeDateDifference(
+ program.getStartTimeUtcMillis(), firstMillisecondToday)) {
return null;
}
ScheduledRecording scheduledRecording = ScheduledRecording.builder(program).build();
@@ -175,7 +179,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
return;
}
ScheduledRecording schedule =
- recordedProgramsToScheduledRecordings(program, MAX_HISTORY_DAYS);
+ recordedProgramsToScheduledRecordings(program, mMaxHistoryDays);
if (schedule == null) {
return;
}
@@ -248,8 +252,10 @@ 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/DvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
index d97b61f4..43a3579a 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 android.support.v17.leanback.widget.ClassPresenterSelector;
+import androidx.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 d376e358..319b583b 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
@@ -25,7 +25,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
+import androidx.leanback.widget.ClassPresenterSelector;
import android.transition.Fade;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
index ef4a4337..de259f5a 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 android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
+import androidx.leanback.widget.ArrayObjectAdapter;
+import androidx.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 11680a0d..ff296f49 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 android.support.v17.leanback.widget.RowPresenter;
+import androidx.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/SchedulesHeaderRowPresenter.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
index 28a44bf3..2550eebc 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 android.support.v17.leanback.widget.RowPresenter;
+import androidx.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 9a9c94ea..9158423c 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
@@ -20,7 +20,7 @@ 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 androidx.leanback.widget.ClassPresenterSelector;
import android.util.ArrayMap;
import android.util.Log;
import com.android.tv.R;
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
index f24ad2c0..4aa1200e 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
@@ -16,7 +16,6 @@
package com.android.tv.dvr.ui.playback;
-import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.content.res.Configuration;
@@ -28,9 +27,12 @@ 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 Activity implements OnPinCheckedListener {
+public class DvrPlaybackActivity extends DaggerActivity implements OnPinCheckedListener {
private static final String TAG = "DvrPlaybackActivity";
private static final boolean DEBUG = false;
@@ -39,6 +41,7 @@ public class DvrPlaybackActivity extends Activity implements OnPinCheckedListene
@Override
public void onCreate(Bundle savedInstanceState) {
+ AndroidInjection.inject(this);
Starter.start(this);
if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
@@ -92,4 +95,16 @@ public class DvrPlaybackActivity extends Activity implements OnPinCheckedListene
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 791d26bb..35c5d4e4 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 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 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.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 1059e852..a111738e 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
@@ -26,23 +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.TvSingletons;
+import com.android.tv.audio.AudioManagerHelper;
+import com.android.tv.common.buildtype.HasBuildType.BuildType;
import com.android.tv.data.BaseProgram;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dvr.DvrDataManager;
@@ -55,8 +56,11 @@ 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.
@@ -75,7 +79,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackFragment {
private ArrayObjectAdapter mRowsAdapter;
private SortedArrayAdapter<BaseProgram> mRelatedRecordingsRowAdapter;
private DvrPlaybackCardPresenter mRelatedRecordingCardPresenter;
- private DvrDataManager mDvrDataManager;
+ private AudioManagerHelper mAudioManagerHelper;
private AppLayerTvView mTvView;
private View mBlockScreenView;
private ListRow mRelatedRecordingsRow;
@@ -97,9 +101,24 @@ 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()
@@ -115,7 +134,6 @@ 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() {
@@ -153,6 +171,8 @@ 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 =
@@ -240,13 +260,16 @@ 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());
@@ -255,7 +278,9 @@ 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) {
@@ -270,9 +295,12 @@ 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();
@@ -416,6 +444,7 @@ 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 b4481df8..95858e3c 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 android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidedAction;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.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 d14646b8..e8325e1f 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
@@ -326,6 +326,11 @@ 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;
diff --git a/src/com/android/tv/features/TvFeatures.java b/src/com/android/tv/features/TvFeatures.java
index 208d53f6..68988bb3 100644
--- a/src/com/android/tv/features/TvFeatures.java
+++ b/src/com/android/tv/features/TvFeatures.java
@@ -28,9 +28,7 @@ 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;
@@ -42,7 +40,7 @@ import com.android.tv.common.singletons.HasSingletons;
import com.android.tv.common.util.PermissionUtils;
/**
- * List of {@link Feature} for the Live TV App.
+ * List of {@link Feature} for the TV app.
*
* <p>Remove the {@code Feature} once it is launched.
*/
@@ -51,16 +49,6 @@ 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);
diff --git a/src/com/android/tv/guide/GenreListAdapter.java b/src/com/android/tv/guide/GenreListAdapter.java
index b4baf421..995b053c 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 android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.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 caafb045..d0e050b2 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 android.support.v17.leanback.widget.VerticalGridView;
+import androidx.leanback.widget.VerticalGridView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index bc1b11b6..bddcc8bb 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -32,10 +32,7 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-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 androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;
@@ -44,6 +41,9 @@ 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;
@@ -66,6 +66,7 @@ import com.android.tv.ui.hideable.AutoHideScheduler;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.common.flags.BackendKnobsFlags;
+import com.android.tv.common.flags.UiFlags;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -112,6 +113,7 @@ 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;
@@ -186,6 +188,7 @@ public class ProgramGuide
TvSingletons singletons = TvSingletons.getSingletons(mActivity);
mPerformanceMonitor = singletons.getPerformanceMonitor();
BackendKnobsFlags backendKnobsFlags = singletons.getBackendKnobs();
+ mUiFlags = singletons.getUiFlags();
mProgramManager =
new ProgramManager(
tvInputManagerHelper,
@@ -193,7 +196,8 @@ public class ProgramGuide
programDataManager,
dvrDataManager,
dvrScheduleManager,
- backendKnobsFlags);
+ backendKnobsFlags,
+ mUiFlags);
mChannelTuner = channelTuner;
mTracker = tracker;
mPreShowRunnable = preShowRunnable;
@@ -261,7 +265,7 @@ public class ProgramGuide
}
});
mSidePanelGridView.setOnChildSelectedListener(
- new android.support.v17.leanback.widget.OnChildSelectedListener() {
+ new androidx.leanback.widget.OnChildSelectedListener() {
@Override
public void onChildSelected(ViewGroup viewGroup, View view, int i, long l) {
mSearchOrb.animate().alpha(i == 0 ? 1.0f : 0.0f);
@@ -282,7 +286,8 @@ public class ProgramGuide
res.getInteger(R.integer.max_recycled_view_pool_epg_header_row_item));
mTimelineRow.setAdapter(mTimeListAdapter);
- ProgramTableAdapter programTableAdapter = new ProgramTableAdapter(mActivity, this);
+ ProgramTableAdapter programTableAdapter =
+ new ProgramTableAdapter(mActivity, this, mUiFlags);
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 a46beab7..a7a545e6 100644
--- a/src/com/android/tv/guide/ProgramItemView.java
+++ b/src/com/android/tv/guide/ProgramItemView.java
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Handler;
+import android.support.v4.os.BuildCompat; // AOSP_Before_Q_Comment_Out
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
@@ -530,6 +531,11 @@ public class ProgramItemView extends TextView {
}
private static int getStateCount(StateListDrawable stateListDrawable) {
+ /* Begin_AOSP_Before_Q_Comment_Out */
+ if (BuildCompat.isAtLeastQ()) {
+ return stateListDrawable.getStateCount();
+ }
+ /* End_AOSP_Before_Q_Comment_Out */
try {
Object stateCount =
StateListDrawable.class
@@ -546,6 +552,11 @@ public class ProgramItemView extends TextView {
}
private static Drawable getStateDrawable(StateListDrawable stateListDrawable, int index) {
+ /* Begin_AOSP_Before_Q_Comment_Out */
+ if (BuildCompat.isAtLeastQ()) {
+ return stateListDrawable.getStateDrawable(index);
+ }
+ /* End_AOSP_Before_Q_Comment_Out */
try {
Object drawable =
StateListDrawable.class
diff --git a/src/com/android/tv/guide/ProgramListAdapter.java b/src/com/android/tv/guide/ProgramListAdapter.java
index 397bacfb..68ae43ee 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 android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.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 3a5a4a02..e059b259 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -33,6 +33,7 @@ import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.common.flags.BackendKnobsFlags;
+import com.android.tv.common.flags.UiFlags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -124,6 +125,12 @@ public class ProgramManager {
}
@Override
+ public void onChannelUpdated() {
+ updateTableEntriesWithoutNotification(false);
+ notifyTableEntriesUpdated();
+ }
+
+ @Override
public void onSingleChannelUpdated(long channelId) {
boolean parentalControlsEnabled =
mTvInputManagerHelper
@@ -216,7 +223,8 @@ public class ProgramManager {
ProgramDataManager programDataManager,
@Nullable DvrDataManager dvrDataManager,
@Nullable DvrScheduleManager dvrScheduleManager,
- BackendKnobsFlags backendKnobsFlags) {
+ BackendKnobsFlags backendKnobsFlags,
+ UiFlags uiFlags) {
mTvInputManagerHelper = tvInputManagerHelper;
mChannelDataManager = channelDataManager;
mProgramDataManager = programDataManager;
@@ -431,8 +439,9 @@ public class ProgramManager {
* (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
*/
TableEntry getTableEntry(long channelId, int index) {
- if (mBackendKnobsFlags.enablePartialProgramFetch()) {
- mProgramDataManager.prefetchChannel(channelId);
+ if (mBackendKnobsFlags.enablePartialProgramFetch()
+ || mBackendKnobsFlags.fetchProgramsAsNeeded()) {
+ mProgramDataManager.prefetchChannel(channelId, index);
}
return mChannelIdEntriesMap.get(channelId).get(index);
}
@@ -707,7 +716,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
- * android.support.v17.leanback.widget.HorizontalGridView} ignores margins between items.
+ * androidx.leanback.widget.HorizontalGridView} ignores margins between items.
*/
static class TableEntry {
/** Channel ID which this entry is included. */
@@ -759,7 +768,7 @@ public class ProgramManager {
mIsBlocked = isBlocked;
}
- /** A stable id useful for {@link android.support.v7.widget.RecyclerView.Adapter}. */
+ /** A stable id useful for {@link androidx.recyclerview.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 3317c15f..6f8f31c1 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 android.support.v7.widget.LinearLayoutManager;
+import androidx.recyclerview.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 5e498be4..a6a4624b 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 android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerViewAccessibilityDelegate;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.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 7576bf50..2028c649 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 android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.RecycledViewPool;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.RecycledViewPool;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
@@ -66,7 +66,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.android.tv.common.flags.UiFlags;
import java.util.ArrayList;
import java.util.List;
@@ -109,10 +109,11 @@ 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) {
+ ProgramTableAdapter(Context context, ProgramGuide programGuide, UiFlags uiFlags) {
mContext = context;
mAccessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -126,6 +127,7 @@ class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.Progr
}
mProgramGuide = programGuide;
mProgramManager = programGuide.getProgramManager();
+ mUiFlags = uiFlags;
Resources res = context.getResources();
mChannelLogoWidth =
@@ -656,6 +658,35 @@ 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 9c10c952..62fec69a 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 android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.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 c4922b75..2d257878 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 android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
diff --git a/src/com/android/tv/menu/AppLinkCardView.java b/src/com/android/tv/menu/AppLinkCardView.java
index fd93c314..49d32fed 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/ChannelsRow.java b/src/com/android/tv/menu/ChannelsRow.java
index 7d03bf2b..dbfc7820 100644
--- a/src/com/android/tv/menu/ChannelsRow.java
+++ b/src/com/android/tv/menu/ChannelsRow.java
@@ -73,6 +73,7 @@ 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 4a9e4765..e6b61037 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -47,6 +47,7 @@ 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;
@@ -66,10 +67,9 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channels
mMaxCount = maxCount;
setHasStableIds(true);
mChannelChanger = (ChannelChanger) (context);
- AccessibilityManager accessibilityManager =
- context.getSystemService(AccessibilityManager.class);
- mShowChannelUpDown = accessibilityManager.isEnabled();
- accessibilityManager.addAccessibilityStateChangeListener(this);
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ mShowChannelUpDown = mAccessibilityManager.isEnabled();
+ mAccessibilityManager.addAccessibilityStateChangeListener(this);
}
@Override
@@ -316,4 +316,10 @@ 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 7042324d..16d5c3eb 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 android.support.v17.leanback.widget.HorizontalGridView;
-import android.support.v17.leanback.widget.OnChildSelectedListener;
-import android.support.v7.widget.RecyclerView;
+import androidx.leanback.widget.HorizontalGridView;
+import androidx.leanback.widget.OnChildSelectedListener;
+import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/menu/Menu.java b/src/com/android/tv/menu/Menu.java
index 6bdbf87b..0687441e 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 android.support.v17.leanback.widget.HorizontalGridView;
+import androidx.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 a600f704..8f95db77 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 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 androidx.recyclerview.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/MenuRowFactory.java b/src/com/android/tv/menu/MenuRowFactory.java
index 048d725d..a3837a10 100644
--- a/src/com/android/tv/menu/MenuRowFactory.java
+++ b/src/com/android/tv/menu/MenuRowFactory.java
@@ -24,6 +24,7 @@ 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. */
@@ -31,12 +32,15 @@ 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) {
+ public MenuRowFactory(
+ MainActivity mainActivity, TunableTvView tvView, LegacyFlags mLegacyFlags) {
mMainActivity = mainActivity;
mTvView = tvView;
mCustomizationManager = new CustomizationManager(mainActivity);
+ this.mLegacyFlags = mLegacyFlags;
mCustomizationManager.initialize();
}
@@ -60,7 +64,8 @@ public class MenuRowFactory {
return new TvOptionsRow(
mMainActivity,
menu,
- mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW));
+ mCustomizationManager.getCustomActions(CustomizationManager.ID_OPTIONS_ROW),
+ mLegacyFlags);
}
return null;
}
@@ -70,13 +75,17 @@ 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) {
+ private TvOptionsRow(
+ Context context,
+ Menu menu,
+ List<CustomAction> customActions,
+ LegacyFlags legacyFlags) {
super(
context,
menu,
R.string.menu_title_options,
R.dimen.action_card_height,
- new TvOptionsRowAdapter(context, customActions));
+ new TvOptionsRowAdapter(context, customActions, legacyFlags));
}
}
diff --git a/src/com/android/tv/menu/TvOptionsRowAdapter.java b/src/com/android/tv/menu/TvOptionsRowAdapter.java
index fe52b25e..418560a8 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,6 +28,7 @@ import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
+import com.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.List;
@@ -35,8 +36,12 @@ import java.util.List;
* An adapter of options.
*/
public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
- public TvOptionsRowAdapter(Context context, List<CustomAction> customActions) {
+ private final LegacyFlags mLegacyFlags;
+
+ public TvOptionsRowAdapter(
+ Context context, List<CustomAction> customActions, LegacyFlags mLegacyFlags) {
super(context, customActions);
+ this.mLegacyFlags = mLegacyFlags;
}
@Override
@@ -49,7 +54,7 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
}
actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
actionList.add(MenuAction.MORE_CHANNELS_ACTION);
- if (CommonUtils.isDeveloper()) {
+ if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
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 45383ae1..26c2be23 100644
--- a/src/com/android/tv/modules/TvApplicationModule.java
+++ b/src/com/android/tv/modules/TvApplicationModule.java
@@ -17,15 +17,24 @@ 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.dialog.PinDialogFragment;
+import com.android.tv.dvr.ui.playback.DvrPlaybackActivity;
import com.android.tv.onboarding.OnboardingActivity;
+import com.android.tv.ui.DetailsActivity;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.TvInputManagerHelper;
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;
@@ -34,25 +43,43 @@ import javax.inject.Singleton;
@Module(
includes = {
ApplicationModule.class,
- TvSingletonsModule.class,
+ BuildTypeModule.class,
+ DetailsActivity.Module.class,
+ DvrPlaybackActivity.Module.class,
MainActivity.Module.class,
- OnboardingActivity.Module.class
+ OnboardingActivity.Module.class,
+ SetupPassthroughActivity.Module.class,
+ TvSingletonsModule.class,
})
-public class TvApplicationModule {
+public abstract class TvApplicationModule {
private static final NamedThreadFactory THREAD_FACTORY = new NamedThreadFactory("tv-app-db");
@Provides
@AsyncDbTask.DbExecutor
@Singleton
- Executor providesDbExecutor() {
+ static Executor providesDbExecutor() {
return Executors.newSingleThreadExecutor(THREAD_FACTORY);
}
@Provides
@Singleton
- TvInputManagerHelper providesTvInputManagerHelper(@ApplicationContext Context context) {
- TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context);
+ static TvInputManagerHelper providesTvInputManagerHelper(
+ @ApplicationContext Context context, LegacyFlags legacyFlags) {
+ TvInputManagerHelper tvInputManagerHelper = new TvInputManagerHelper(context, legacyFlags);
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;
+ }
+
+ @ContributesAndroidInjector
+ abstract PinDialogFragment contributesPinDialogFragment();
}
diff --git a/src/com/android/tv/modules/TvSingletonsModule.java b/src/com/android/tv/modules/TvSingletonsModule.java
index f998c08b..41206c9b 100644
--- a/src/com/android/tv/modules/TvSingletonsModule.java
+++ b/src/com/android/tv/modules/TvSingletonsModule.java
@@ -16,8 +16,9 @@
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.DvrDataManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
import dagger.Module;
import dagger.Provides;
@@ -36,8 +37,13 @@ public class TvSingletonsModule {
}
@Provides
- ChannelDataManager providesChannelDataManager() {
- return mTvSingletons.getChannelDataManager();
+ DvrDataManager providesDvrDataManager() {
+ return mTvSingletons.getDvrDataManager();
+ }
+
+ @Provides
+ DvrWatchedPositionManager providesDvrWatchedPositionManager() {
+ return mTvSingletons.getDvrWatchedPositionManager();
}
@Provides
diff --git a/src/com/android/tv/onboarding/OnboardingActivity.java b/src/com/android/tv/onboarding/OnboardingActivity.java
index 776ae664..1739e5a0 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 Live TV
+ // Make the channels of the new inputs which have been setup outside TV app
// 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 Live channels SetupPassthroughActivity.
+ // channels should go through TV app 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 3566c9c3..bf842dd8 100644
--- a/src/com/android/tv/onboarding/SetupSourcesFragment.java
+++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java
@@ -22,10 +22,10 @@ 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 androidx.leanback.widget.GuidanceStylist.Guidance;
+import androidx.leanback.widget.GuidedAction;
+import androidx.leanback.widget.GuidedActionsStylist;
+import androidx.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/src/com/android/tv/onboarding/WelcomeFragment.java b/src/com/android/tv/onboarding/WelcomeFragment.java
index 8c119a8a..667da058 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 android.support.v17.leanback.app.OnboardingFragment;
+import androidx.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(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);
+ 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);
mStartButton.setAccessibilityDelegate(
new AccessibilityDelegate() {
diff --git a/src/com/android/tv/parental/ContentRatingsManager.java b/src/com/android/tv/parental/ContentRatingsManager.java
index 32a1325b..174039ba 100644
--- a/src/com/android/tv/parental/ContentRatingsManager.java
+++ b/src/com/android/tv/parental/ContentRatingsManager.java
@@ -22,6 +22,7 @@ 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;
@@ -42,13 +43,14 @@ public class ContentRatingsManager {
public void update() {
mContentRatingSystems.clear();
- 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);
+ 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);
+ }
}
}
}
diff --git a/src/com/android/tv/parental/ParentalControlSettings.java b/src/com/android/tv/parental/ParentalControlSettings.java
index b41b160e..9990ae35 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,14 +40,16 @@ 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) {
+ public ParentalControlSettings(Context context, LegacyFlags legacyFlags) {
mContext = context;
mTvInputManager = (TvInputManager) mContext.getSystemService(Context.TV_INPUT_SERVICE);
+ mLegacyFlags = legacyFlags;
}
public boolean isParentalControlsEnabled() {
@@ -130,7 +132,7 @@ public class ParentalControlSettings {
} else {
mRatings = ContentRatingLevelPolicy.getRatingsForLevel(this, manager, level);
if (level != TvSettings.CONTENT_RATING_LEVEL_NONE
- && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ && mLegacyFlags.enableUnratedContentSettings()) {
// 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 b1ae759d..30197c74 100644
--- a/src/com/android/tv/perf/PerformanceMonitor.java
+++ b/src/com/android/tv/perf/PerformanceMonitor.java
@@ -96,4 +96,14 @@ 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
deleted file mode 100644
index db6667d1..00000000
--- a/src/com/android/tv/perf/PerformanceMonitorManager.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.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/StartupMeasure.java b/src/com/android/tv/perf/StartupMeasure.java
index 5cf183ca..c7fa50fe 100644
--- a/src/com/android/tv/perf/StartupMeasure.java
+++ b/src/com/android/tv/perf/StartupMeasure.java
@@ -19,8 +19,16 @@ import android.app.Activity;
import android.app.Application;
/**
- * Measures App startup. This interface is lightweight to help measure both cold and warm startup
- * latency. Implementations must not throw any Exception.
+ * 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.
*/
public interface StartupMeasure {
diff --git a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
index 80c2f6c5..ac3dc250 100644
--- a/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
+++ b/src/com/android/tv/perf/stub/StubPerformanceMonitor.java
@@ -56,7 +56,6 @@ public final class StubPerformanceMonitor implements PerformanceMonitor {
return false;
}
- public static TimerEvent startBootstrapTimer() {
- return new TimerEvent() {};
- }
+ @Override
+ public void startCrashMonitor() {}
}
diff --git a/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java b/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
deleted file mode 100644
index 0c268155..00000000
--- a/src/com/android/tv/perf/stub/StubPerformanceMonitorManager.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.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/PackageIntentsReceiver.java b/src/com/android/tv/receiver/PackageIntentsReceiver.java
index 5bc6d724..7ff67b50 100644
--- a/src/com/android/tv/receiver/PackageIntentsReceiver.java
+++ b/src/com/android/tv/receiver/PackageIntentsReceiver.java
@@ -23,9 +23,7 @@ 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/RecommendationDataManager.java b/src/com/android/tv/recommendation/RecommendationDataManager.java
index fc20031c..83f11bd4 100644
--- a/src/com/android/tv/recommendation/RecommendationDataManager.java
+++ b/src/com/android/tv/recommendation/RecommendationDataManager.java
@@ -232,6 +232,9 @@ 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);
}
diff --git a/src/com/android/tv/search/ProgramGuideSearchFragment.java b/src/com/android/tv/search/ProgramGuideSearchFragment.java
index 6c94bd33..fa2e4516 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 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 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.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
diff --git a/src/com/android/tv/setup/SystemSetupActivity.java b/src/com/android/tv/setup/SystemSetupActivity.java
index b2160b3a..a392fdbe 100644
--- a/src/com/android/tv/setup/SystemSetupActivity.java
+++ b/src/com/android/tv/setup/SystemSetupActivity.java
@@ -92,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 Live channels SetupPassthroughActivity.
+ // channels should go through TV app SetupPassthroughActivity.
intent.setComponent(
new ComponentName(this, SetupPassthroughActivity.class));
try {
diff --git a/src/com/android/tv/ui/AppLayerTvView.java b/src/com/android/tv/ui/AppLayerTvView.java
index e2b64a1e..4c54fb3c 100644
--- a/src/com/android/tv/ui/AppLayerTvView.java
+++ b/src/com/android/tv/ui/AppLayerTvView.java
@@ -21,7 +21,6 @@ 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;
/**
@@ -29,9 +28,14 @@ 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. TODO: remove this class once the TvView.setMain() is revisited.
+ * uses only application layer.
+ *
+ * <p>TODO: remove this class once the TvView.setMain() is revisited.
*/
public class AppLayerTvView extends TvViewCompat {
+
+ boolean mUseSecureSurface = true;
+
public AppLayerTvView(Context context) {
super(context);
}
@@ -44,6 +48,11 @@ 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;
@@ -53,7 +62,7 @@ public class AppLayerTvView extends TvViewCompat {
public void onViewAdded(View child) {
if (child instanceof SurfaceView) {
// Note: See b/29118070 for detail.
- ((SurfaceView) child).setSecure(!CommonUtils.isDeveloper());
+ ((SurfaceView) child).setSecure(mUseSecureSurface);
}
super.onViewAdded(child);
}
diff --git a/src/com/android/tv/ui/ChannelBannerView.java b/src/com/android/tv/ui/ChannelBannerView.java
index 00ac7e32..bce4d6b5 100644
--- a/src/com/android/tv/ui/ChannelBannerView.java
+++ b/src/com/android/tv/ui/ChannelBannerView.java
@@ -118,6 +118,7 @@ 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;
@@ -278,8 +279,7 @@ public class ChannelBannerView extends FrameLayout
sClosedCaptionMark = context.getString(R.string.closed_caption);
}
mAutoHideScheduler = new AutoHideScheduler(context, this::hide);
- context.getSystemService(AccessibilityManager.class)
- .addAccessibilityStateChangeListener(mAutoHideScheduler);
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
}
@Override
@@ -319,6 +319,20 @@ 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) {
diff --git a/src/com/android/tv/ui/DetailsActivity.java b/src/com/android/tv/ui/DetailsActivity.java
index 80c0f64b..92c13f57 100644
--- a/src/com/android/tv/ui/DetailsActivity.java
+++ b/src/com/android/tv/ui/DetailsActivity.java
@@ -16,12 +16,11 @@
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 android.support.v17.leanback.app.DetailsFragment;
+import androidx.leanback.app.DetailsFragment;
import android.transition.Transition;
import android.transition.Transition.TransitionListener;
import android.util.Log;
@@ -35,9 +34,12 @@ 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 Activity implements PinDialogFragment.OnPinCheckedListener {
+public class DetailsActivity extends DaggerActivity
+ implements PinDialogFragment.OnPinCheckedListener {
private static final String TAG = "DetailsActivity";
private static final long INVALID_RECORD_ID = -1;
@@ -206,4 +208,15 @@ public class DetailsActivity extends Activity implements PinDialogFragment.OnPin
}
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 9685b04b..3aba5d1d 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 android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidedAction;
+import androidx.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 9b916afe..703dc242 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 android.support.v17.leanback.widget.VerticalGridView;
+import androidx.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 88a7b2ca..3d62e494 100644
--- a/src/com/android/tv/ui/ProgramDetailsFragment.java
+++ b/src/com/android/tv/ui/ProgramDetailsFragment.java
@@ -23,16 +23,16 @@ 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 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 android.text.TextUtils;
import com.android.tv.R;
import com.android.tv.TvSingletons;
diff --git a/src/com/android/tv/ui/SelectInputView.java b/src/com/android/tv/ui/SelectInputView.java
index f4949f08..a0cfad32 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 android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
+import androidx.leanback.widget.VerticalGridView;
+import androidx.recyclerview.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 5ac6bd83..5a99b8be 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -59,6 +59,7 @@ 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;
@@ -81,6 +82,7 @@ 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;
@@ -317,7 +319,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 Live TV ends,"
+ "Start up of TV app ends,"
+ " TunableTvView.onVideoAvailable resets timer");
Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
Debug.removeTimer(Debug.TAG_START_UP_TIMER);
@@ -473,8 +475,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void initialize(
- ProgramDataManager programDataManager, TvInputManagerHelper tvInputManagerHelper) {
+ ProgramDataManager programDataManager,
+ TvInputManagerHelper tvInputManagerHelper,
+ LegacyFlags mLegacyFlags) {
mTvView = findViewById(R.id.tv_view);
+ mTvView.setUseSecureSurface(!BuildConfig.ENG && !mLegacyFlags.enableDeveloperFeatures());
+
mProgramDataManager = programDataManager;
mInputManagerHelper = tvInputManagerHelper;
mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
@@ -553,7 +559,9 @@ public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvV
}
public void setMain() {
- mTvView.setMain();
+ if (PermissionUtils.hasChangeHdmiCecActiveSource(getContext())) {
+ mTvView.setMain();
+ }
}
public void setWatchedHistoryManager(WatchedHistoryManager watchedHistoryManager) {
diff --git a/src/com/android/tv/ui/TvOverlayManager.java b/src/com/android/tv/ui/TvOverlayManager.java
index b2854a1f..9b04d74e 100644
--- a/src/com/android/tv/ui/TvOverlayManager.java
+++ b/src/com/android/tv/ui/TvOverlayManager.java
@@ -68,6 +68,7 @@ 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.android.tv.common.flags.LegacyFlags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -216,6 +217,7 @@ 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;
@@ -229,9 +231,11 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
InputBannerView inputBannerView,
SelectInputView selectInputView,
ViewGroup sceneContainer,
- ProgramGuideSearchFragment searchFragment) {
+ ProgramGuideSearchFragment searchFragment,
+ LegacyFlags mLegacyFlags) {
mMainActivity = mainActivity;
mChannelTuner = channelTuner;
+ this.mLegacyFlags = mLegacyFlags;
TvSingletons singletons = TvSingletons.getSingletons(mainActivity);
mChannelDataManager = singletons.getChannelDataManager();
mInputManager = singletons.getTvInputManagerHelper();
@@ -271,7 +275,7 @@ public class TvOverlayManager implements AccessibilityStateChangeListener {
tvView,
optionsManager,
menuView,
- new MenuRowFactory(mainActivity, tvView),
+ new MenuRowFactory(mainActivity, tvView, this.mLegacyFlags),
new Menu.OnMenuVisibilityChangeListener() {
@Override
public void onMenuVisibilityChange(boolean visible) {
diff --git a/src/com/android/tv/ui/ViewUtils.java b/src/com/android/tv/ui/ViewUtils.java
index f64a70b2..faef2f50 100644
--- a/src/com/android/tv/ui/ViewUtils.java
+++ b/src/com/android/tv/ui/ViewUtils.java
@@ -18,6 +18,7 @@ package com.android.tv.ui;
import android.animation.Animator;
import android.animation.ValueAnimator;
+import android.support.v4.os.BuildCompat; // AOSP_Before_Q_Comment_Out
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@@ -33,6 +34,11 @@ public class ViewUtils {
}
public static void setTransitionAlpha(View v, float alpha) {
+ // Begin_AOSP_Before_Q_Comment_Out
+ if (BuildCompat.isAtLeastQ()) {
+ v.setTransitionAlpha(alpha);
+ }
+ // End_AOSP_Before_Q_Comment_Out
Method method;
try {
method = View.class.getDeclaredMethod("setTransitionAlpha", Float.TYPE);
diff --git a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
index 62130b64..b62a57ee 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 android.support.v17.leanback.widget.VerticalGridView;
+import androidx.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 36ee5a2d..81ff1fc5 100644
--- a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
+++ b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
@@ -16,29 +16,33 @@
package com.android.tv.ui.sidepanel;
-import android.accounts.Account;
-import android.app.Activity;
-import android.support.annotation.NonNull;
-import android.util.Log;
-import android.widget.Toast;
+import android.content.Context;
+import com.android.tv.MainActivity;
import com.android.tv.R;
-import com.android.tv.TvSingletons;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonPreferences;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.util.CommonUtils;
-
-
-
-
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.tv.perf.PerformanceMonitor;
+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;
/** 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(Context context) {
+ AndroidInjection.inject(this);
+ super.onAttach(context);
+ }
+
@Override
protected String getTitle() {
return getString(R.string.menu_developer_options);
@@ -50,8 +54,15 @@ public class DeveloperOptionFragment extends SideFragment {
}
@Override
- protected List<Item> getItemList() {
- List<Item> items = new ArrayList<>();
+ protected ImmutableList<Item> getItemList() {
+ ImmutableList.Builder<Item> items = ImmutableList.builder();
+ if (mAdditionalDeveloperItemsFactory.isPresent()) {
+ items.addAll(
+ mAdditionalDeveloperItemsFactory
+ .get()
+ .getAdditionalDevItems(getMainActivity()));
+ items.add(new DividerItem());
+ }
if (CommonFeatures.DVR.isEnabled(getContext())) {
items.add(
new ActionItem(getString(R.string.dev_item_dvr_history)) {
@@ -61,7 +72,7 @@ public class DeveloperOptionFragment extends SideFragment {
}
});
}
- if (CommonUtils.isDeveloper()) {
+ if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
items.add(
new ActionItem(getString(R.string.dev_item_watch_history)) {
@Override
@@ -87,17 +98,21 @@ public class DeveloperOptionFragment extends SideFragment {
CommonPreferences.setStoreTsStream(getContext(), isChecked());
}
});
- if (CommonUtils.isDeveloper()) {
+ if (BuildConfig.ENG || mLegacyFlags.enableDeveloperFeatures()) {
items.add(
new ActionItem(getString(R.string.dev_item_show_performance_monitor_log)) {
@Override
protected void onSelected() {
- TvSingletons.getSingletons(getContext())
- .getPerformanceMonitor()
- .startPerformanceMonitorEventDebugActivity(getContext());
+ mPerformanceMonitor.startPerformanceMonitorEventDebugActivity(
+ getContext());
}
});
}
- return items;
+ return items.build();
+ }
+
+ /** Factory to create additional items. */
+ public interface AdditionalDeveloperItemsFactory {
+ ImmutableList<Item> getAdditionalDevItems(MainActivity mainActivity);
}
}
diff --git a/src/com/android/tv/ui/sidepanel/SettingsFragment.java b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
index aa71fb75..1c03b6a9 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 Live TV settings. */
+/** Shows TV app 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 590f1300..1cbeeab5 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragment.java
@@ -20,8 +20,8 @@ import android.app.Fragment;
import android.content.Context;
import android.graphics.drawable.RippleDrawable;
import android.os.Bundle;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
+import androidx.leanback.widget.VerticalGridView;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/ChannelsBlockedFragment.java
index b14bf78d..620b7017 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 android.support.v17.leanback.widget.VerticalGridView;
+import androidx.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 d1ae4423..064f86f1 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
@@ -16,6 +16,7 @@
package com.android.tv.ui.sidepanel.parentalcontrols;
+import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.tv.TvContentRating;
import android.os.Bundle;
@@ -26,7 +27,6 @@ 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,10 +40,13 @@ 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;
@@ -51,6 +54,8 @@ public class RatingsFragment extends SideFragment {
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);
@@ -101,8 +106,7 @@ public class RatingsFragment extends SideFragment {
protected List<Item> getItemList() {
List<Item> items = new ArrayList<>();
- if (mBlockUnratedItem != null
- && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
items.add(mBlockUnratedItem);
items.add(new DividerItem());
}
@@ -158,7 +162,13 @@ public class RatingsFragment extends SideFragment {
super.onCreate(savedInstanceState);
mParentalControlSettings = getMainActivity().getParentalControlSettings();
mParentalControlSettings.loadRatings();
- if (Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ AndroidInjection.inject(this);
+ super.onAttach(context);
+ if (mLegacyFlags.enableUnratedContentSettings()) {
mBlockUnratedItem =
new CheckBoxItem(
getResources().getString(R.string.option_block_unrated_programs)) {
@@ -179,6 +189,8 @@ public class RatingsFragment extends SideFragment {
}
}
};
+ } else {
+ mBlockUnratedItem = null;
}
}
@@ -235,8 +247,7 @@ public class RatingsFragment extends SideFragment {
super.onSelected();
mParentalControlSettings.setContentRatingLevel(
getMainActivity().getContentRatingsManager(), mRatingLevel);
- if (mBlockUnratedItem != null
- && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ if (mBlockUnratedItem != null && mLegacyFlags.enableUnratedContentSettings()) {
// set checked if UNRATED is blocked, and set unchecked otherwise.
mBlockUnratedItem.setChecked(
mParentalControlSettings.isRatingBlocked(
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 3b72e091..4fae2f00 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -27,7 +27,9 @@ public final class OnboardingUtils {
private static final String PREF_KEY_ONBOARDING_VERSION_CODE = "pref_onbaording_versionCode";
private static final int ONBOARDING_VERSION = 1;
- private static final String MERCHANT_COLLECTION_URL_STRING = getMerchantCollectionUrl();
+ // Replace as needed
+ private static final String MERCHANT_COLLECTION_URL_STRING =
+ "https://play.google.com/store/apps/collection/promotion_3001bf9_ATV_livechannels";
/** Intent to show merchant collection in online store. */
public static final Intent ONLINE_STORE_INTENT =
@@ -69,10 +71,5 @@ 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 a9b67fa8..52b3e3e8 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -307,8 +307,7 @@ public class SetupUtils {
}
/**
- * Called when Live channels app is launched. Once it is called, {@link #isFirstTune} will
- * return false.
+ * Called when TV 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/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index a3064953..9945fbda 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -46,6 +46,7 @@ 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.android.tv.common.flags.LegacyFlags;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -127,6 +128,7 @@ 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";
@@ -158,6 +160,10 @@ 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 = {
@@ -292,8 +298,8 @@ public class TvInputManagerHelper {
private boolean mAllow3rdPartyInputs;
@Inject
- public TvInputManagerHelper(@ApplicationContext Context context) {
- this(context, createTvInputManagerWrapper(context));
+ public TvInputManagerHelper(@ApplicationContext Context context, LegacyFlags legacyFlags) {
+ this(context, createTvInputManagerWrapper(context), legacyFlags);
}
@Nullable
@@ -305,12 +311,14 @@ public class TvInputManagerHelper {
@VisibleForTesting
protected TvInputManagerHelper(
- Context context, @Nullable TvInputManagerInterface tvInputManager) {
+ Context context,
+ @Nullable TvInputManagerInterface tvInputManager,
+ LegacyFlags legacyFlags) {
mContext = context.getApplicationContext();
mPackageManager = context.getPackageManager();
mTvInputManager = tvInputManager;
mContentRatingsManager = new ContentRatingsManager(context, tvInputManager);
- mParentalControlSettings = new ParentalControlSettings(context);
+ mParentalControlSettings = new ParentalControlSettings(context, legacyFlags);
mTvInputInfoComparator = new InputComparatorInternal(this);
mContentObserver =
new ContentObserver(mHandler) {
diff --git a/src/com/android/tv/util/TvProviderUtils.java b/src/com/android/tv/util/TvProviderUtils.java
index 6b5aaecc..8cdf1c71 100644
--- a/src/com/android/tv/util/TvProviderUtils.java
+++ b/src/com/android/tv/util/TvProviderUtils.java
@@ -67,6 +67,9 @@ 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;
}
@@ -112,6 +115,9 @@ 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;
}
diff --git a/src/com/android/tv/util/account/AccountHelper.java b/src/com/android/tv/util/account/AccountHelper.java
index e98b42ec..d54c2f56 100644
--- a/src/com/android/tv/util/account/AccountHelper.java
+++ b/src/com/android/tv/util/account/AccountHelper.java
@@ -35,4 +35,11 @@ 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 58fbd27e..e97cc3f2 100644
--- a/src/com/android/tv/util/account/AccountHelperImpl.java
+++ b/src/com/android/tv/util/account/AccountHelperImpl.java
@@ -21,8 +21,12 @@ 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";
@@ -31,7 +35,8 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
@Nullable private Account mSelectedAccount;
- public AccountHelperImpl(Context context) {
+ @Inject
+ public AccountHelperImpl(@ApplicationContext Context context) {
mContext = context.getApplicationContext();
mDefaultPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
}
@@ -98,4 +103,9 @@ 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 d2ad0eb1..cbd386ad 100644
--- a/src/com/android/tv/util/images/ImageLoader.java
+++ b/src/com/android/tv/util/images/ImageLoader.java
@@ -29,6 +29,7 @@ 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;
@@ -428,6 +429,47 @@ 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());