aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/MainActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/MainActivity.java')
-rw-r--r--src/com/android/tv/MainActivity.java1281
1 files changed, 754 insertions, 527 deletions
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index ed5f79a1..94a86cce 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -17,9 +17,12 @@
package com.android.tv;
import android.app.Activity;
+import android.app.PendingIntent;
+import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
@@ -62,26 +65,31 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.Toast;
-
import com.android.tv.analytics.SendChannelStatusRunnable;
import com.android.tv.analytics.SendConfigInfoRunnable;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BuildConfig;
-import com.android.tv.common.MemoryManageable;
+import com.android.tv.common.CommonPreferences;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.TvCommonUtils;
import com.android.tv.common.TvContentRatingCache;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.memory.MemoryManageable;
import com.android.tv.common.ui.setup.OnActionClickListener;
-import com.android.tv.data.Channel;
+import com.android.tv.common.util.CommonUtils;
+import com.android.tv.common.util.ContentUriUtils;
+import com.android.tv.common.util.Debug;
+import com.android.tv.common.util.DurationTimer;
+import com.android.tv.common.util.PermissionUtils;
+import com.android.tv.common.util.SystemProperties;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.ChannelImpl;
import com.android.tv.data.OnCurrentProgramUpdatedListener;
import com.android.tv.data.Program;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
-import com.android.tv.data.epg.EpgFetcher;
+import com.android.tv.data.api.Channel;
import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
@@ -97,15 +105,10 @@ import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.perf.EventNames;
import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.perf.StubPerformanceMonitor;
import com.android.tv.perf.TimerEvent;
import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.search.ProgramGuideSearchFragment;
-import com.android.tv.tuner.TunerInputController;
-import com.android.tv.tuner.TunerPreferences;
-import com.android.tv.tuner.setup.TunerSetupActivity;
-import com.android.tv.tuner.tvinput.TunerTvInputService;
import com.android.tv.ui.ChannelBannerView;
import com.android.tv.ui.InputBannerView;
import com.android.tv.ui.KeypadChannelSwitchView;
@@ -124,21 +127,18 @@ import com.android.tv.ui.sidepanel.MultiAudioFragment;
import com.android.tv.ui.sidepanel.SettingsFragment;
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment;
-import com.android.tv.util.AccountHelper;
+import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.CaptionSettings;
-import com.android.tv.util.Debug;
-import com.android.tv.util.DurationTimer;
-import com.android.tv.util.ImageCache;
import com.android.tv.util.OnboardingUtils;
-import com.android.tv.util.PermissionUtils;
import com.android.tv.util.RecurringRunner;
import com.android.tv.util.SetupUtils;
-import com.android.tv.util.SystemProperties;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvTrackInfoUtils;
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 java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -148,19 +148,23 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-/**
- * The main activity for the Live TV app.
- */
+/** The main activity for the Live TV app. */
public class MainActivity extends Activity implements OnActionClickListener, OnPinCheckedListener {
private static final String TAG = "MainActivity";
private static final boolean DEBUG = false;
@Retention(RetentionPolicy.SOURCE)
- @IntDef({KEY_EVENT_HANDLER_RESULT_PASSTHROUGH, KEY_EVENT_HANDLER_RESULT_NOT_HANDLED,
- KEY_EVENT_HANDLER_RESULT_HANDLED, KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY})
+ @IntDef({
+ KEY_EVENT_HANDLER_RESULT_PASSTHROUGH,
+ KEY_EVENT_HANDLER_RESULT_NOT_HANDLED,
+ KEY_EVENT_HANDLER_RESULT_HANDLED,
+ KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY
+ })
public @interface KeyHandlerResultType {}
+
public static final int KEY_EVENT_HANDLER_RESULT_PASSTHROUGH = 0;
public static final int KEY_EVENT_HANDLER_RESULT_NOT_HANDLED = 1;
public static final int KEY_EVENT_HANDLER_RESULT_HANDLED = 2;
@@ -171,12 +175,12 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private static final float FRAME_RATE_FOR_FILM = 23.976f;
private static final float FRAME_RATE_EPSILON = 0.1f;
-
private static final int PERMISSIONS_REQUEST_READ_TV_LISTINGS = 1;
private static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
// Tracker screen names.
public static final String SCREEN_NAME = "Main";
+ private static final String SCREEN_PIP = "PIP";
private static final String SCREEN_BEHIND_NAME = "Behind";
private static final float REFRESH_RATE_EPSILON = 0.01f;
@@ -196,8 +200,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
BLACKLIST_KEYCODE_TO_TIS.add(KeyEvent.KEYCODE_WINDOW);
}
-
private static final IntentFilter SYSTEM_INTENT_FILTER = new IntentFilter();
+
static {
SYSTEM_INTENT_FILTER.addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED);
SYSTEM_INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
@@ -206,6 +210,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
+ private static final int REQUEST_CODE_NOW_PLAYING = 2;
private static final String KEY_INIT_CHANNEL_ID = "com.android.tv.init_channel_id";
@@ -240,14 +245,13 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private final DurationTimer mTuneDurationTimer = new DurationTimer();
private DvrManager mDvrManager;
private ConflictChecker mDvrConflictChecker;
+ private SetupUtils mSetupUtils;
private View mContentView;
private TunableTvView mTvView;
private Bundle mTuneParams;
- @Nullable
- private Uri mInitChannelUri;
- @Nullable
- private String mParentInputIdWhenScreenOff;
+ @Nullable private Uri mInitChannelUri;
+ @Nullable private String mParentInputIdWhenScreenOff;
private boolean mScreenOffIntentReceived;
private boolean mShowProgramGuide;
private boolean mShowSelectInputView;
@@ -274,6 +278,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private boolean mOtherActivityLaunched;
private PerformanceMonitor mPerformanceMonitor;
+ private boolean mIsInPIPMode;
private boolean mIsFilmModeSet;
private float mDefaultRefreshRate;
@@ -302,69 +307,74 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private final Handler mHandler = new MainActivityHandler(this);
private final Set<OnActionClickListener> mOnActionClickListeners = new ArraySet<>();
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- switch (intent.getAction()) {
- case Intent.ACTION_SCREEN_OFF:
- if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_OFF");
- // We need to stop TvView, when the screen is turned off. If not and TIS uses
- // MediaPlayer, a device may not go to the sleep mode and audio can be heard,
- // because MediaPlayer keeps playing media by its wake lock.
- mScreenOffIntentReceived = true;
- markCurrentChannelDuringScreenOff();
- stopAll(true);
- break;
- case Intent.ACTION_SCREEN_ON:
- if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_ON");
- if (!mActivityResumed && mVisibleBehind) {
- // ACTION_SCREEN_ON is usually called after onResume. But, if media is
- // played under launcher with requestVisibleBehind(true), onResume will
- // not be called. In this case, we need to resume TvView explicitly.
- resumeTvIfNeeded();
- }
- break;
- case TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED:
- if (DEBUG) Log.d(TAG, "Received parental control settings change");
- applyParentalControlSettings();
- checkChannelLockNeeded(mTvView, null);
- break;
- case Intent.ACTION_TIME_CHANGED:
- // Re-tune the current channel to prevent incorrect behavior of trick-play.
- // See: b/37393628
- if (mChannelTuner.getCurrentChannel() != null) {
- tune(true);
+ private final BroadcastReceiver mBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case Intent.ACTION_SCREEN_OFF:
+ if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_OFF");
+ // We need to stop TvView, when the screen is turned off. If not and TIS
+ // uses MediaPlayer, a device may not go to the sleep mode and audio
+ // can be heard, because MediaPlayer keeps playing media by its wake
+ // lock.
+ mScreenOffIntentReceived = true;
+ markCurrentChannelDuringScreenOff();
+ stopAll(true);
+ break;
+ case Intent.ACTION_SCREEN_ON:
+ if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_ON");
+ if (!mActivityResumed && mVisibleBehind) {
+ // ACTION_SCREEN_ON is usually called after onResume. But, if media
+ // is played under launcher with requestVisibleBehind(true),
+ // onResume will not be called. In this case, we need to resume
+ // TvView explicitly.
+ resumeTvIfNeeded();
+ }
+ break;
+ case TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED:
+ if (DEBUG) Log.d(TAG, "Received parental control settings change");
+ applyParentalControlSettings();
+ checkChannelLockNeeded(mTvView, null);
+ break;
+ case Intent.ACTION_TIME_CHANGED:
+ // Re-tune the current channel to prevent incorrect behavior of
+ // trick-play.
+ // See: b/37393628
+ if (mChannelTuner.getCurrentChannel() != null) {
+ tune(true);
+ }
+ break;
+ default: // fall out
}
- break;
- }
- }
- };
+ }
+ };
private final OnCurrentProgramUpdatedListener mOnCurrentProgramUpdatedListener =
new OnCurrentProgramUpdatedListener() {
- @Override
- public void onCurrentProgramUpdated(long channelId, Program program) {
- // Do not update channel banner by this notification
- // when the time shifting is available.
- if (mTimeShiftManager.isAvailable()) {
- return;
- }
- Channel channel = mTvView.getCurrentChannel();
- if (channel != null && channel.getId() == channelId) {
- mOverlayManager.updateChannelBannerAndShowIfNeeded(
- TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
- mMediaSessionWrapper.update(mTvView.isBlocked(), channel, program);
- }
- }
- };
+ @Override
+ public void onCurrentProgramUpdated(long channelId, Program program) {
+ // Do not update channel banner by this notification
+ // when the time shifting is available.
+ if (mTimeShiftManager.isAvailable()) {
+ return;
+ }
+ Channel channel = mTvView.getCurrentChannel();
+ if (channel != null && channel.getId() == channelId) {
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
+ mMediaSessionWrapper.update(mTvView.isBlocked(), channel, program);
+ }
+ }
+ };
private final ChannelTuner.Listener mChannelTunerListener =
new ChannelTuner.Listener() {
@Override
public void onLoadFinished() {
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
- "MainActivity.mChannelTunerListener.onLoadFinished");
- SetupUtils.getInstance(MainActivity.this).markNewChannelsBrowsable();
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log("MainActivity.mChannelTunerListener.onLoadFinished");
+ mSetupUtils.markNewChannelsBrowsable();
if (mActivityResumed) {
resumeTvIfNeeded();
}
@@ -389,30 +399,35 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
public void onChannelChanged(Channel previousChannel, Channel currentChannel) {}
};
- private final Runnable mRestoreMainViewRunnable = new Runnable() {
- @Override
- public void run() {
- restoreMainTvView();
- }
- };
+ private final Runnable mRestoreMainViewRunnable =
+ new Runnable() {
+ @Override
+ public void run() {
+ restoreMainTvView();
+ }
+ };
private ProgramGuideSearchFragment mSearchFragment;
- private final TvInputCallback mTvInputCallback = new TvInputCallback() {
- @Override
- public void onInputAdded(String inputId) {
- if (Features.TUNER.isEnabled(MainActivity.this) && mTunerInputId.equals(inputId)
- && TunerPreferences.shouldShowSetupActivity(MainActivity.this)) {
- Intent intent = TunerSetupActivity.createSetupActivity(MainActivity.this);
- startActivity(intent);
- TunerPreferences.setShouldShowSetupActivity(MainActivity.this, false);
- SetupUtils.getInstance(MainActivity.this).markAsKnownInput(mTunerInputId);
- }
- }
- };
+ private final TvInputCallback mTvInputCallback =
+ new TvInputCallback() {
+ @Override
+ public void onInputAdded(String inputId) {
+ if (TvFeatures.TUNER.isEnabled(MainActivity.this)
+ && mTunerInputId.equals(inputId)
+ && CommonPreferences.shouldShowSetupActivity(MainActivity.this)) {
+ Intent intent =
+ TvSingletons.getSingletons(MainActivity.this)
+ .getTunerSetupIntent(MainActivity.this);
+ startActivity(intent);
+ CommonPreferences.setShouldShowSetupActivity(MainActivity.this, false);
+ mSetupUtils.markAsKnownInput(mTunerInputId);
+ }
+ }
+ };
private void applyParentalControlSettings() {
- boolean parentalControlEnabled = mTvInputManagerHelper.getParentalControlSettings()
- .isParentalControlsEnabled();
+ boolean parentalControlEnabled =
+ mTvInputManagerHelper.getParentalControlSettings().isParentalControlsEnabled();
mTvView.onParentalControlChanged(parentalControlEnabled);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ChannelPreviewUpdater.getInstance(this).updatePreviewDataForChannelsImmediately();
@@ -421,7 +436,11 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
@Override
protected void onCreate(Bundle savedInstanceState) {
- TimerEvent timer = StubPerformanceMonitor.startBootstrapTimer();
+ mAccessibilityManager =
+ (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(this);
+ mPerformanceMonitor = tvSingletons.getPerformanceMonitor();
+ TimerEvent timer = mPerformanceMonitor.startTimer();
DurationTimer startUpDebugTimer = Debug.getTimer(Debug.TAG_START_UP_TIMER);
if (!startUpDebugTimer.isStarted()
|| startUpDebugTimer.getDuration() > START_UP_TIMER_RESET_THRESHOLD_MS) {
@@ -430,30 +449,33 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
startUpDebugTimer.start();
}
startUpDebugTimer.log("MainActivity.onCreate");
- if (DEBUG) Log.d(TAG,"onCreate()");
- TvApplication.setCurrentRunningProcess(this, true);
+ if (DEBUG) {
+ Log.d(TAG, "onCreate()");
+ }
+ Starter.start(this);
super.onCreate(savedInstanceState);
- ApplicationSingletons applicationSingletons = TvApplication.getSingletons(this);
- if (!applicationSingletons.getTvInputManagerHelper().hasTvInputManager()) {
+ if (!tvSingletons.getTvInputManagerHelper().hasTvInputManager()) {
Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
finishAndRemoveTask();
return;
}
- mPerformanceMonitor = applicationSingletons.getPerformanceMonitor();
+ mPerformanceMonitor = tvSingletons.getPerformanceMonitor();
+ mSetupUtils = tvSingletons.getSetupUtils();
TvApplication tvApplication = (TvApplication) getApplication();
mChannelDataManager = tvApplication.getChannelDataManager();
// In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
boolean isPassthroughInput =
TvContract.isChannelUriForPassthroughInput(getIntent().getData());
- boolean tuneToPassthroughInput = Intent.ACTION_VIEW.equals(getIntent().getAction())
- && isPassthroughInput;
- boolean channelLoadedAndNoChannelAvailable = mChannelDataManager.isDbLoadFinished()
- && mChannelDataManager.getChannelCount() <= 0;
+ boolean tuneToPassthroughInput =
+ Intent.ACTION_VIEW.equals(getIntent().getAction()) && isPassthroughInput;
+ boolean channelLoadedAndNoChannelAvailable =
+ mChannelDataManager.isDbLoadFinished()
+ && mChannelDataManager.getChannelCount() <= 0;
if ((OnboardingUtils.isFirstRunWithCurrentVersion(this)
- || channelLoadedAndNoChannelAvailable)
+ || channelLoadedAndNoChannelAvailable)
&& !tuneToPassthroughInput
- && !TvCommonUtils.isRunningInTest()) {
+ && !CommonUtils.isRunningInTest()) {
startOnboardingActivity();
return;
}
@@ -462,31 +484,38 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mTvInputManagerHelper = tvApplication.getTvInputManagerHelper();
mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
- mTvView.setOnUnhandledInputEventListener(new OnUnhandledInputEventListener() {
- @Override
- public boolean onUnhandledInputEvent(InputEvent event) {
- if (isKeyEventBlocked()) {
- return true;
- }
- if (event instanceof KeyEvent) {
- KeyEvent keyEvent = (KeyEvent) event;
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.isLongPress()) {
- if (onKeyLongPress(keyEvent.getKeyCode(), keyEvent)) {
+ mTvView.setOnUnhandledInputEventListener(
+ new OnUnhandledInputEventListener() {
+ @Override
+ public boolean onUnhandledInputEvent(InputEvent event) {
+ if (DEBUG) {
+ Log.d(TAG, "onUnhandledInputEvent " + event);
+ }
+ if (isKeyEventBlocked()) {
return true;
}
+ if (event instanceof KeyEvent) {
+ KeyEvent keyEvent = (KeyEvent) event;
+ if (keyEvent.getAction() == KeyEvent.ACTION_DOWN
+ && keyEvent.isLongPress()) {
+ if (onKeyLongPress(keyEvent.getKeyCode(), keyEvent)) {
+ return true;
+ }
+ }
+ if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
+ return onKeyUp(keyEvent.getKeyCode(), keyEvent);
+ } else if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ return onKeyDown(keyEvent.getKeyCode(), keyEvent);
+ }
+ }
+ return false;
}
- if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
- return onKeyUp(keyEvent.getKeyCode(), keyEvent);
- } else if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- return onKeyDown(keyEvent.getKeyCode(), keyEvent);
- }
- }
- return false;
- }
- });
+ });
+ mTvView.setOnTalkBackDpadKeyListener(keycode -> handleUpDownKeys(keycode, null));
long channelId = Utils.getLastWatchedChannelId(this);
String inputId = Utils.getLastWatchedTunerInputId(this);
- if (!isPassthroughInput && inputId != null
+ if (!isPassthroughInput
+ && inputId != null
&& channelId != Channel.INVALID_ID) {
mTvView.warmUpInput(inputId, TvContract.buildChannelUri(channelId));
}
@@ -496,12 +525,12 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
Toast.makeText(this, "Using Strict Mode for eng builds", Toast.LENGTH_SHORT).show();
}
mTracker = tvApplication.getTracker();
- if (Features.TUNER.isEnabled(this)) {
+ if (TvFeatures.TUNER.isEnabled(this)) {
mTvInputManagerHelper.addCallback(mTvInputCallback);
}
- mTunerInputId = TunerTvInputService.getInputId(this);
- mProgramDataManager.addOnCurrentProgramUpdatedListener(Channel.INVALID_ID,
- mOnCurrentProgramUpdatedListener);
+ mTunerInputId = tvSingletons.getEmbeddedTunerInputId();
+ mProgramDataManager.addOnCurrentProgramUpdatedListener(
+ Channel.INVALID_ID, mOnCurrentProgramUpdatedListener);
mProgramDataManager.setPrefetchEnabled(true);
mChannelTuner = new ChannelTuner(mChannelDataManager, mTvInputManagerHelper);
mChannelTuner.addListener(mChannelTunerListener);
@@ -512,91 +541,126 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
if (CommonFeatures.DVR.isEnabled(this)) {
mDvrManager = tvApplication.getDvrManager();
}
- mTimeShiftManager = new TimeShiftManager(this, mTvView, mProgramDataManager, mTracker,
- new OnCurrentProgramUpdatedListener() {
- @Override
- public void onCurrentProgramUpdated(long channelId, Program program) {
- mMediaSessionWrapper.update(mTvView.isBlocked(), getCurrentChannel(),
- program);
- switch (mTimeShiftManager.getLastActionId()) {
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND:
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_FAST_FORWARD:
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS:
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT:
- mOverlayManager.updateChannelBannerAndShowIfNeeded(
- TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
- break;
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE:
- case TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY:
- default:
- mOverlayManager.updateChannelBannerAndShowIfNeeded(
- TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
- break;
- }
- }
- });
+ mTimeShiftManager =
+ new TimeShiftManager(
+ this,
+ mTvView,
+ mProgramDataManager,
+ mTracker,
+ new OnCurrentProgramUpdatedListener() {
+ @Override
+ public void onCurrentProgramUpdated(long channelId, Program program) {
+ mMediaSessionWrapper.update(
+ mTvView.isBlocked(), getCurrentChannel(), program);
+ switch (mTimeShiftManager.getLastActionId()) {
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND:
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_FAST_FORWARD:
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS:
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT:
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager
+ .UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
+ break;
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE:
+ case TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY:
+ default:
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager
+ .UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
+ break;
+ }
+ }
+ });
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
mDefaultRefreshRate = display.getRefreshRate();
if (!PermissionUtils.hasAccessWatchedHistory(this)) {
- WatchedHistoryManager watchedHistoryManager = new WatchedHistoryManager(
- getApplicationContext());
+ WatchedHistoryManager watchedHistoryManager =
+ new WatchedHistoryManager(getApplicationContext());
watchedHistoryManager.start();
mTvView.setWatchedHistoryManager(watchedHistoryManager);
}
- mTvViewUiManager = new TvViewUiManager(this, mTvView,
- (FrameLayout) findViewById(android.R.id.content), mTvOptionsManager);
+ mTvViewUiManager =
+ new TvViewUiManager(
+ this,
+ mTvView,
+ (FrameLayout) findViewById(android.R.id.content),
+ mTvOptionsManager);
mContentView = findViewById(android.R.id.content);
ViewGroup sceneContainer = (ViewGroup) findViewById(R.id.scene_container);
- ChannelBannerView channelBannerView = (ChannelBannerView) getLayoutInflater().inflate(
- R.layout.channel_banner, sceneContainer, false);
- KeypadChannelSwitchView keypadChannelSwitchView = (KeypadChannelSwitchView)
- getLayoutInflater().inflate(R.layout.keypad_channel_switch, sceneContainer, false);
- InputBannerView inputBannerView = (InputBannerView) getLayoutInflater()
- .inflate(R.layout.input_banner, sceneContainer, false);
- SelectInputView selectInputView = (SelectInputView) getLayoutInflater()
- .inflate(R.layout.select_input, sceneContainer, false);
- selectInputView.setOnInputSelectedCallback(new OnInputSelectedCallback() {
- @Override
- public void onTunerInputSelected() {
- Channel currentChannel = mChannelTuner.getCurrentChannel();
- if (currentChannel != null && !currentChannel.isPassthrough()) {
- hideOverlays();
- } else {
- tuneToLastWatchedChannelForTunerInput();
- }
- }
+ ChannelBannerView channelBannerView =
+ (ChannelBannerView)
+ getLayoutInflater().inflate(R.layout.channel_banner, sceneContainer, false);
+ KeypadChannelSwitchView keypadChannelSwitchView =
+ (KeypadChannelSwitchView)
+ getLayoutInflater()
+ .inflate(R.layout.keypad_channel_switch, sceneContainer, false);
+ InputBannerView inputBannerView =
+ (InputBannerView)
+ getLayoutInflater().inflate(R.layout.input_banner, sceneContainer, false);
+ SelectInputView selectInputView =
+ (SelectInputView)
+ getLayoutInflater().inflate(R.layout.select_input, sceneContainer, false);
+ selectInputView.setOnInputSelectedCallback(
+ new OnInputSelectedCallback() {
+ @Override
+ public void onTunerInputSelected() {
+ Channel currentChannel = mChannelTuner.getCurrentChannel();
+ if (currentChannel != null && !currentChannel.isPassthrough()) {
+ hideOverlays();
+ } else {
+ tuneToLastWatchedChannelForTunerInput();
+ }
+ }
- @Override
- public void onPassthroughInputSelected(@NonNull TvInputInfo input) {
- Channel currentChannel = mChannelTuner.getCurrentChannel();
- String currentInputId = currentChannel == null ? null : currentChannel.getInputId();
- if (TextUtils.equals(input.getId(), currentInputId)) {
- hideOverlays();
- } else {
- tuneToChannel(Channel.createPassthroughChannel(input.getId()));
- }
- }
+ @Override
+ public void onPassthroughInputSelected(@NonNull TvInputInfo input) {
+ Channel currentChannel = mChannelTuner.getCurrentChannel();
+ String currentInputId =
+ currentChannel == null ? null : currentChannel.getInputId();
+ if (TextUtils.equals(input.getId(), currentInputId)) {
+ hideOverlays();
+ } else {
+ tuneToChannel(ChannelImpl.createPassthroughChannel(input.getId()));
+ }
+ }
- private void hideOverlays() {
- getOverlayManager().hideOverlays(
- TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
- }
- });
+ private void hideOverlays() {
+ getOverlayManager()
+ .hideOverlays(
+ TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
+ | TvOverlayManager
+ .FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
+ | TvOverlayManager
+ .FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
+ | TvOverlayManager
+ .FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
+ }
+ });
mSearchFragment = new ProgramGuideSearchFragment();
- mOverlayManager = new TvOverlayManager(this, mChannelTuner, mTvView, mTvOptionsManager,
- keypadChannelSwitchView, channelBannerView, inputBannerView,
- selectInputView, sceneContainer, mSearchFragment);
+ mOverlayManager =
+ new TvOverlayManager(
+ this,
+ mChannelTuner,
+ mTvView,
+ mTvOptionsManager,
+ keypadChannelSwitchView,
+ channelBannerView,
+ inputBannerView,
+ selectInputView,
+ sceneContainer,
+ mSearchFragment);
+ mAccessibilityManager.addAccessibilityStateChangeListener(mOverlayManager);
mAudioManagerHelper = new AudioManagerHelper(this, mTvView);
- mMediaSessionWrapper = new MediaSessionWrapper(this);
+ Intent nowPlayingIntent = new Intent(this, MainActivity.class);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(this, REQUEST_CODE_NOW_PLAYING, nowPlayingIntent, 0);
+ mMediaSessionWrapper = new MediaSessionWrapper(this, pendingIntent);
mTvViewUiManager.restoreDisplayMode(false);
if (!handleIntent(getIntent())) {
@@ -604,18 +668,21 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return;
}
- mAccessibilityManager =
- (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
- mSendConfigInfoRecurringRunner = new RecurringRunner(this, TimeUnit.DAYS.toMillis(1),
- new SendConfigInfoRunnable(mTracker, mTvInputManagerHelper), null);
+ mSendConfigInfoRecurringRunner =
+ new RecurringRunner(
+ this,
+ TimeUnit.DAYS.toMillis(1),
+ new SendConfigInfoRunnable(mTracker, mTvInputManagerHelper),
+ null);
mSendConfigInfoRecurringRunner.start();
- mChannelStatusRecurringRunner = SendChannelStatusRunnable
- .startChannelStatusRecurringRunner(this, mTracker, mChannelDataManager);
+ mChannelStatusRecurringRunner =
+ SendChannelStatusRunnable.startChannelStatusRecurringRunner(
+ this, mTracker, mChannelDataManager);
// To avoid not updating Rating systems when changing language.
mTvInputManagerHelper.getContentRatingsManager().update();
if (CommonFeatures.DVR.isEnabled(this)
- && Features.SHOW_UPCOMING_CONFLICT_DIALOG.isEnabled(this)) {
+ && TvFeatures.SHOW_UPCOMING_CONFLICT_DIALOG.isEnabled(this)) {
mDvrConflictChecker = new ConflictChecker(this);
}
initForTest();
@@ -632,13 +699,14 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
float density = getResources().getDisplayMetrics().density;
- mTvViewUiManager.onConfigurationChanged((int) (newConfig.screenWidthDp * density),
+ mTvViewUiManager.onConfigurationChanged(
+ (int) (newConfig.screenWidthDp * density),
(int) (newConfig.screenHeightDp * density));
}
@Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
- @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(
+ int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_TV_LISTINGS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Start reload of dependent data
@@ -650,14 +718,18 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
finish();
startActivity(intent);
} else {
- Toast.makeText(this, R.string.msg_read_tv_listing_permission_denied,
- Toast.LENGTH_LONG).show();
+ Toast.makeText(
+ this,
+ R.string.msg_read_tv_listing_permission_denied,
+ Toast.LENGTH_LONG)
+ .show();
finish();
}
}
}
- @BlockScreenType private int getDesiredBlockScreenType() {
+ @BlockScreenType
+ private int getDesiredBlockScreenType() {
if (!mActivityResumed) {
return TunableTvView.BLOCK_SCREEN_TYPE_NO_UI;
}
@@ -689,7 +761,9 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
@Override
protected void onNewIntent(Intent intent) {
- if (DEBUG) Log.d(TAG,"onNewIntent(): " + intent);
+ if (DEBUG) {
+ Log.d(TAG, "onNewIntent(): " + intent);
+ }
if (mOverlayManager == null) {
// It's called before onCreate. The intent will be handled at onCreate. b/30725058
return;
@@ -705,7 +779,9 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
@Override
protected void onStart() {
TimerEvent timer = mPerformanceMonitor.startTimer();
- if (DEBUG) Log.d(TAG,"onStart()");
+ if (DEBUG) {
+ Log.d(TAG, "onStart()");
+ }
super.onStart();
mScreenOffIntentReceived = false;
mActivityStarted = true;
@@ -720,9 +796,9 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
notificationIntent.setAction(NotificationService.ACTION_SHOW_RECOMMENDATION);
startService(notificationIntent);
}
- TunerInputController.executeNetworkTunerDiscoveryAsyncTask(this);
-
- EpgFetcher.getInstance(this).fetchImmediatelyIfNeeded();
+ TvSingletons singletons = TvSingletons.getSingletons(this);
+ singletons.getTunerInputController().executeNetworkTunerDiscoveryAsyncTask(this);
+ singletons.getEpgFetcher().fetchImmediatelyIfNeeded();
mPerformanceMonitor.stopTimer(timer, EventNames.MAIN_ACTIVITY_ONSTART);
}
@@ -732,10 +808,12 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.onResume start");
if (DEBUG) Log.d(TAG, "onResume()");
super.onResume();
+ mIsInPIPMode = false;
if (!PermissionUtils.hasAccessAllEpg(this)
&& checkSelfPermission(PERMISSION_READ_TV_LISTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{PERMISSION_READ_TV_LISTINGS},
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(
+ new String[] {PERMISSION_READ_TV_LISTINGS},
PERMISSIONS_REQUEST_READ_TV_LISTINGS);
}
mTracker.sendScreenView(SCREEN_NAME);
@@ -755,19 +833,20 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
Set<String> failedScheduledRecordingInfoSet =
Utils.getFailedScheduledRecordingInfoSet(getApplicationContext());
if (Utils.hasRecordingFailedReason(
- getApplicationContext(), TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE)
+ getApplicationContext(), TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE)
&& !failedScheduledRecordingInfoSet.isEmpty()) {
- runAfterAttachedToWindow(new Runnable() {
- @Override
- public void run() {
- DvrUiHelper.showDvrInsufficientSpaceErrorDialog(MainActivity.this,
- failedScheduledRecordingInfoSet);
- }
- });
+ runAfterAttachedToWindow(
+ new Runnable() {
+ @Override
+ public void run() {
+ DvrUiHelper.showDvrInsufficientSpaceErrorDialog(
+ MainActivity.this, failedScheduledRecordingInfoSet);
+ }
+ });
}
if (mChannelTuner.areAllChannelsLoaded()) {
- SetupUtils.getInstance(this).markNewChannelsBrowsable();
+ mSetupUtils.markNewChannelsBrowsable();
resumeTvIfNeeded();
}
mOverlayManager.showMenuWithTimeShiftPauseIfNeeded();
@@ -779,28 +858,29 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mInputToSetUp = null;
} else if (mShowProgramGuide) {
mShowProgramGuide = false;
- mHandler.post(new Runnable() {
- // This will delay the start of the animation until after the Live Channel app is
- // shown. Without this the animation is completed before it is actually visible on
- // the screen.
- @Override
- public void run() {
- mOverlayManager.showProgramGuide();
- }
- });
+ // This will delay the start of the animation until after the Live Channel app is
+ // shown. Without this the animation is completed before it is actually visible on
+ // the screen.
+ mHandler.post(
+ new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.showProgramGuide();
+ }
+ });
} else if (mShowSelectInputView) {
mShowSelectInputView = false;
- mHandler.post(new Runnable() {
- // mShowSelectInputView is true when the activity is started/resumed because the
- // TV_INPUT button was pressed in a different app.
- // This will delay the start of the animation until after the Live Channel app is
- // shown. Without this the animation is completed before it is actually visible on
- // the screen.
- @Override
- public void run() {
- mOverlayManager.showSelectInputView();
- }
- });
+ // mShowSelectInputView is true when the activity is started/resumed because the
+ // TV_INPUT button was pressed in a different app. This will delay the start of
+ // the animation until after the Live Channel app is shown. Without this the
+ // animation is completed before it is actually visible on the screen.
+ mHandler.post(
+ new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.showSelectInputView();
+ }
+ });
}
if (mDvrConflictChecker != null) {
mDvrConflictChecker.start();
@@ -823,25 +903,26 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mShowLockedChannelsTemporarily = false;
mShouldTuneToTunerChannel = false;
if (!mVisibleBehind) {
- mAudioManagerHelper.abandonAudioFocus();
- mMediaSessionWrapper.setPlaybackState(false);
- mTracker.sendScreenView("");
+ if (mIsInPIPMode) {
+ mTracker.sendScreenView(SCREEN_PIP);
+ } else {
+ mTracker.sendScreenView("");
+ mAudioManagerHelper.abandonAudioFocus();
+ mMediaSessionWrapper.setPlaybackState(false);
+ }
} else {
mTracker.sendScreenView(SCREEN_BEHIND_NAME);
}
+ TvSingletons.getSingletons(this).getExperimentLoader().asyncRefreshExperiments(this);
super.onPause();
}
- /**
- * Returns true if {@link #onResume} is called and {@link #onPause} is not called yet.
- */
+ /** Returns true if {@link #onResume} is called and {@link #onPause} is not called yet. */
public boolean isActivityResumed() {
return mActivityResumed;
}
- /**
- * Returns true if {@link #onStart} is called and {@link #onStop} is not called yet.
- */
+ /** Returns true if {@link #onStart} is called and {@link #onStop} is not called yet. */
public boolean isActivityStarted() {
return mActivityStarted;
}
@@ -867,12 +948,14 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mTvView.unblockContent(unblockedRating);
break;
case PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN:
- mOverlayManager.getSideFragmentManager()
+ mOverlayManager
+ .getSideFragmentManager()
.show(new ParentalControlsFragment(), false);
- // Pass through.
+ // fall through.
case PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN:
mOverlayManager.getSideFragmentManager().showSidePanel(true);
break;
+ default: // fall out
}
} else if (type == PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN) {
mOverlayManager.getSideFragmentManager().hideAll(false);
@@ -881,7 +964,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private void resumeTvIfNeeded() {
if (DEBUG) Log.d(TAG, "resumeTvIfNeeded()");
- if (!mTvView.isPlaying() || mInitChannelUri != null
+ if (!mTvView.isPlaying()
+ || mInitChannelUri != null
|| (mShouldTuneToTunerChannel && mChannelTuner.isCurrentChannelPassthrough())) {
if (TvContract.isChannelUriForPassthroughInput(mInitChannelUri)) {
// The target input may not be ready yet, especially, just after screen on.
@@ -917,9 +1001,11 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
// is playing, we stop the passthrough TV input.
stopTv();
}
- SoftPreconditions.checkState(TvContract.isChannelUriForPassthroughInput(channelUri)
- || mChannelTuner.areAllChannelsLoaded(),
- TAG, "startTV assumes that ChannelDataManager is already loaded.");
+ SoftPreconditions.checkState(
+ TvContract.isChannelUriForPassthroughInput(channelUri)
+ || mChannelTuner.areAllChannelsLoaded(),
+ TAG,
+ "startTV assumes that ChannelDataManager is already loaded.");
if (mTvView.isPlaying()) {
// TV has already started.
if (channelUri == null || channelUri.equals(mChannelTuner.getCurrentChannelUri())) {
@@ -945,15 +1031,19 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mChannelTuner.moveToChannel(mChannelTuner.findNearestBrowsableChannel(0));
} else {
if (TvContract.isChannelUriForPassthroughInput(channelUri)) {
- Channel channel = Channel.createPassthroughChannel(channelUri);
+ ChannelImpl channel = ChannelImpl.createPassthroughChannel(channelUri);
mChannelTuner.moveToChannel(channel);
} else {
long channelId = ContentUris.parseId(channelUri);
Channel channel = mChannelDataManager.getChannel(channelId);
if (channel == null || !mChannelTuner.moveToChannel(channel)) {
mChannelTuner.moveToChannel(mChannelTuner.findNearestBrowsableChannel(0));
- Log.w(TAG, "The requested channel (id=" + channelId + ") doesn't exist. "
- + "The first channel will be tuned to.");
+ Log.w(
+ TAG,
+ "The requested channel (id="
+ + channelId
+ + ") doesn't exist. "
+ + "The first channel will be tuned to.");
}
}
}
@@ -985,9 +1075,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
super.onStop();
}
- /**
- * Handles screen off to keep the current channel for next screen on.
- */
+ /** Handles screen off to keep the current channel for next screen on. */
private void markCurrentChannelDuringScreenOff() {
mInitChannelUri = mChannelTuner.getCurrentChannelUri();
if (mChannelTuner.isCurrentChannelPassthrough()) {
@@ -1015,7 +1103,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
* @param calledByPopup If true, startSetupActivity is invoked from the setup fragment.
*/
public void startSetupActivity(TvInputInfo input, boolean calledByPopup) {
- Intent intent = TvCommonUtils.createSetupIntent(input);
+ Intent intent = CommonUtils.createSetupIntent(input);
if (intent == null) {
Toast.makeText(this, R.string.msg_no_setup_activity, Toast.LENGTH_SHORT).show();
return;
@@ -1038,16 +1126,23 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY);
} catch (ActivityNotFoundException e) {
mInputIdUnderSetup = null;
- Toast.makeText(this, getString(R.string.msg_unable_to_start_setup_activity,
- input.loadLabel(this)), Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ this,
+ getString(
+ R.string.msg_unable_to_start_setup_activity,
+ input.loadLabel(this)),
+ Toast.LENGTH_SHORT)
+ .show();
return;
}
if (calledByPopup) {
- mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
+ mOverlayManager.hideOverlays(
+ TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
} else {
- mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY);
+ mOverlayManager.hideOverlays(
+ TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY);
}
}
@@ -1060,8 +1155,11 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
try {
startActivitySafe(intent);
} catch (ActivityNotFoundException e) {
- Toast.makeText(this, getString(R.string.msg_unable_to_start_system_captioning_settings),
- Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ this,
+ getString(R.string.msg_unable_to_start_system_captioning_settings),
+ Toast.LENGTH_SHORT)
+ .show();
}
}
@@ -1085,16 +1183,12 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return mTimeShiftManager;
}
- /**
- * Returns the instance of {@link TvOverlayManager}.
- */
+ /** Returns the instance of {@link TvOverlayManager}. */
public TvOverlayManager getOverlayManager() {
return mOverlayManager;
}
- /**
- * Returns the {@link ConflictChecker}.
- */
+ /** Returns the {@link ConflictChecker}. */
@Nullable
public ConflictChecker getDvrConflictChecker() {
return mDvrConflictChecker;
@@ -1109,9 +1203,10 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
/**
- * Returns the current program which the user is watching right now.<p>
+ * Returns the current program which the user is watching right now.
*
- * It might be a live program. If the time shifting is available, it can be a past program, too.
+ * <p>It might be a live program. If the time shifting is available, it can be a past program,
+ * too.
*/
public Program getCurrentProgram() {
if (!isChannelChangeKeyDownReceived() && mTimeShiftManager.isAvailable()) {
@@ -1122,9 +1217,9 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
/**
- * Returns the current playing time in milliseconds.<p>
+ * Returns the current playing time in milliseconds.
*
- * If the time shifting is available, the time is the playing position of the program,
+ * <p>If the time shifting is available, the time is the playing position of the program,
* otherwise, the system current time.
*/
public long getCurrentPlayingPosition() {
@@ -1152,18 +1247,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
LauncherActivity.startActivitySafe(this, intent);
}
- /**
- * Call {@link Activity#startActivityForResult} in a safe way.
- *
- * @see LauncherActivity
- */
- private void startActivityForResultSafe(Intent intent, int requestCode) {
- LauncherActivity.startActivityForResultSafe(this, intent, requestCode);
- }
-
- /**
- * Show settings fragment.
- */
+ /** Show settings fragment. */
public void showSettingsFragment() {
if (!mChannelTuner.areAllChannelsLoaded()) {
// Show ChannelSourcesFragment only if all the channels are loaded.
@@ -1180,8 +1264,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
* It is called when shrunken TvView is desired, such as EditChannelFragment and
* ChannelsLockedFragment.
*/
- public void startShrunkenTvView(boolean showLockedChannelsTemporarily,
- boolean willMainViewBeTunerInput) {
+ public void startShrunkenTvView(
+ boolean showLockedChannelsTemporarily, boolean willMainViewBeTunerInput) {
mChannelBeforeShrunkenTvView = mTvView.getCurrentChannel();
mWasChannelUnblockedBeforeShrunkenByUser = mIsCurrentChannelUnblockedByUser;
mAllowedRatingBeforeShrunken = mLastAllowedRatingForCurrentChannel;
@@ -1214,19 +1298,21 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
// The current channel is mTvView.getCurrentChannel() and need to tune to the returnChannel.
if (!Objects.equals(mTvView.getCurrentChannel(), returnChannel)) {
final Channel channel = returnChannel;
- Runnable tuneAction = new Runnable() {
- @Override
- public void run() {
- tuneToChannel(channel);
- if (mChannelBeforeShrunkenTvView == null
- || !mChannelBeforeShrunkenTvView.equals(channel)) {
- Utils.setLastWatchedChannel(MainActivity.this, channel);
- }
- mIsCompletingShrunkenTvView = false;
- mIsCurrentChannelUnblockedByUser = mWasChannelUnblockedBeforeShrunkenByUser;
- mTvView.setBlockScreenType(getDesiredBlockScreenType());
- }
- };
+ Runnable tuneAction =
+ new Runnable() {
+ @Override
+ public void run() {
+ tuneToChannel(channel);
+ if (mChannelBeforeShrunkenTvView == null
+ || !mChannelBeforeShrunkenTvView.equals(channel)) {
+ Utils.setLastWatchedChannel(MainActivity.this, channel);
+ }
+ mIsCompletingShrunkenTvView = false;
+ mIsCurrentChannelUnblockedByUser =
+ mWasChannelUnblockedBeforeShrunkenByUser;
+ mTvView.setBlockScreenType(getDesiredBlockScreenType());
+ }
+ };
mTvViewUiManager.fadeOutTvView(tuneAction);
// Will automatically fade-in when video becomes available.
} else {
@@ -1247,35 +1333,45 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
*/
public boolean isScreenBlockedByResourceConflictOrParentalControl() {
return mTvView.getVideoUnavailableReason()
- == TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE || mTvView.isBlocked();
+ == TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE
+ || mTvView.isBlocked();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQUEST_CODE_START_SETUP_ACTIVITY) {
- if (resultCode == RESULT_OK) {
- int count = mChannelDataManager.getChannelCountForInput(mInputIdUnderSetup);
- String text;
- if (count > 0) {
- text = getResources().getQuantityString(R.plurals.msg_channel_added,
- count, count);
+ switch (requestCode) {
+ case REQUEST_CODE_START_SETUP_ACTIVITY:
+ if (resultCode == RESULT_OK) {
+ int count = mChannelDataManager.getChannelCountForInput(mInputIdUnderSetup);
+ String text;
+ if (count > 0) {
+ text =
+ getResources()
+ .getQuantityString(
+ R.plurals.msg_channel_added, count, count);
+ } else {
+ text = getString(R.string.msg_no_channel_added);
+ }
+ Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
+ mInputIdUnderSetup = null;
+ if (mChannelTuner.getCurrentChannel() == null) {
+ mChannelTuner.moveToAdjacentBrowsableChannel(true);
+ }
+ if (mTunePending) {
+ tune(true);
+ }
} else {
- text = getString(R.string.msg_no_channel_added);
+ mInputIdUnderSetup = null;
}
- Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
- mInputIdUnderSetup = null;
- if (mChannelTuner.getCurrentChannel() == null) {
- mChannelTuner.moveToAdjacentBrowsableChannel(true);
+ if (!mIsSetupActivityCalledByPopup) {
+ mOverlayManager.getSideFragmentManager().showSidePanel(false);
}
- if (mTunePending) {
- tune(true);
- }
- } else {
- mInputIdUnderSetup = null;
- }
- if (!mIsSetupActivityCalledByPopup) {
- mOverlayManager.getSideFragmentManager().showSidePanel(false);
- }
+ break;
+ case REQUEST_CODE_NOW_PLAYING:
+ // nothing needs to be done. onResume will restore everything.
+ break;
+ default:
+ // do nothing
}
if (data != null) {
String errorMessage = data.getStringExtra(LauncherActivity.ERROR_MESSAGE);
@@ -1325,16 +1421,15 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return dispatchKeyEventToSession(event) || super.dispatchKeyEvent(event);
}
- /**
- * Notifies the key input focus is changed to the TV view.
- */
+ /** Notifies the key input focus is changed to the TV view. */
public void updateKeyInputFocus() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mTvView.setBlockScreenType(getDesiredBlockScreenType());
- }
- });
+ mHandler.post(
+ new Runnable() {
+ @Override
+ public void run() {
+ mTvView.setBlockScreenType(getDesiredBlockScreenType());
+ }
+ });
}
// It should be called before onResume.
@@ -1360,12 +1455,13 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
if (TvInputManager.ACTION_SETUP_INPUTS.equals(intent.getAction())) {
- runAfterAttachedToWindow(new Runnable() {
- @Override
- public void run() {
- mOverlayManager.showSetupFragment();
- }
- });
+ runAfterAttachedToWindow(
+ new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.showSetupFragment();
+ }
+ });
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
if (Utils.isProgramsUri(uri)) {
@@ -1388,18 +1484,34 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
if ((!Utils.isChannelUriForOneChannel(mInitChannelUri)
&& !Utils.isChannelUriForInput(mInitChannelUri))) {
- Log.w(TAG, "Malformed channel uri " + mInitChannelUri
- + " tuning to default instead");
+ Log.w(
+ TAG,
+ "Malformed channel uri " + mInitChannelUri + " tuning to default instead");
mInitChannelUri = null;
return true;
}
mTuneParams = intent.getExtras();
+ String programUriString = intent.getStringExtra(SearchManager.EXTRA_DATA_KEY);
+ Uri programUriFromIntent =
+ programUriString == null ? null : Uri.parse(programUriString);
+ long channelIdFromIntent = ContentUriUtils.safeParseId(mInitChannelUri);
+ if (programUriFromIntent != null && channelIdFromIntent != Channel.INVALID_ID) {
+ new AsyncQueryProgramTask(
+ TvSingletons.getSingletons(this).getDbExecutor(),
+ getContentResolver(),
+ programUriFromIntent,
+ Program.PROJECTION,
+ null,
+ null,
+ null,
+ channelIdFromIntent)
+ .executeOnDbThread();
+ }
if (mTuneParams == null) {
mTuneParams = new Bundle();
}
if (Utils.isChannelUriForTunerInput(mInitChannelUri)) {
- long channelId = ContentUris.parseId(mInitChannelUri);
- mTuneParams.putLong(KEY_INIT_CHANNEL_ID, channelId);
+ mTuneParams.putLong(KEY_INIT_CHANNEL_ID, channelIdFromIntent);
} else if (TvContract.isChannelUriForPassthroughInput(mInitChannelUri)) {
// If mInitChannelUri is for a passthrough TV input.
String inputId = mInitChannelUri.getPathSegments().get(1);
@@ -1419,16 +1531,20 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
String inputId = mInitChannelUri.getQueryParameter("input");
long channelId = Utils.getLastWatchedChannelIdForInput(this, inputId);
if (channelId == Channel.INVALID_ID) {
- String[] projection = { Channels._ID };
+ String[] projection = {Channels._ID};
long time = System.currentTimeMillis();
- try (Cursor cursor = getContentResolver().query(uri, projection,
- null, null, null)) {
+ try (Cursor cursor =
+ getContentResolver().query(uri, projection, null, null, null)) {
if (cursor != null && cursor.moveToNext()) {
channelId = cursor.getLong(0);
}
}
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity queries DB for "
- + "last channel check (" + (System.currentTimeMillis() - time) + "ms)");
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log(
+ "MainActivity queries DB for "
+ + "last channel check ("
+ + (System.currentTimeMillis() - time)
+ + "ms)");
}
if (channelId == Channel.INVALID_ID) {
// Couldn't find any channel probably because the input hasn't been set up.
@@ -1444,6 +1560,63 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return true;
}
+ private class AsyncQueryProgramTask extends AsyncDbTask.AsyncQueryTask<Program> {
+ private final long mChannelIdFromIntent;
+
+ public AsyncQueryProgramTask(
+ Executor executor,
+ ContentResolver contentResolver,
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String orderBy,
+ long channelId) {
+ super(executor, contentResolver, uri, projection, selection, selectionArgs, orderBy);
+ mChannelIdFromIntent = channelId;
+ }
+
+ @Override
+ protected Program onQuery(Cursor c) {
+ Program program = null;
+ if (c != null && c.moveToNext()) {
+ program = Program.fromCursor(c);
+ }
+ return program;
+ }
+
+ @Override
+ protected void onPostExecute(Program program) {
+ if (program == null || program.getStartTimeUtcMillis() <= System.currentTimeMillis()) {
+ // null or current program
+ return;
+ }
+ Channel channel = mChannelDataManager.getChannel(mChannelIdFromIntent);
+ if (channel != null) {
+ ScheduledRecording scheduledRecording =
+ TvSingletons.getSingletons(MainActivity.this)
+ .getDvrDataManager()
+ .getScheduledRecordingForProgramId(program.getId());
+ DvrUiHelper.checkStorageStatusAndShowErrorMessage(
+ MainActivity.this,
+ channel.getInputId(),
+ new Runnable() {
+ @Override
+ public void run() {
+ if (CommonFeatures.DVR.isEnabled(MainActivity.this)
+ && scheduledRecording == null
+ && mDvrManager.isProgramRecordable(program)) {
+ DvrUiHelper.requestRecordingFutureProgram(
+ MainActivity.this, program, false);
+ } else {
+ DvrUiHelper.showProgramInfoDialog(MainActivity.this, program);
+ }
+ }
+ });
+ }
+ }
+ }
+
private void stopTv() {
stopTv(null, false);
}
@@ -1462,7 +1635,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mAudioManagerHelper.abandonAudioFocus();
mMediaSessionWrapper.setPlaybackState(false);
}
- TvApplication.getSingletons(this).getMainActivityWrapper()
+ TvSingletons.getSingletons(this)
+ .getMainActivityWrapper()
.notifyCurrentChannelChange(this, null);
mChannelTuner.resetCurrentChannel();
mTunePending = false;
@@ -1473,9 +1647,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mHandler.postDelayed(mRestoreMainViewRunnable, TVVIEW_SET_MAIN_TIMEOUT_MS);
}
- /**
- * Says {@code text} when accessibility is turned on.
- */
+ /** Says {@code text} when accessibility is turned on. */
private void sendAccessibilityText(String text) {
if (mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain();
@@ -1510,8 +1682,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
finish();
return;
}
- SetupUtils setupUtils = SetupUtils.getInstance(this);
- if (setupUtils.isFirstTune()) {
+
+ if (mSetupUtils.isFirstTune()) {
if (!mChannelTuner.areAllChannelsLoaded()) {
// tune() will be called, once all channels are loaded.
stopTv("tune()", false);
@@ -1532,29 +1704,33 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return;
}
if (mTvInputManagerHelper.getTunerTvInputSize() == 1) {
- mOverlayManager.getSideFragmentManager().show(
- new CustomizeChannelListFragment());
+ mOverlayManager
+ .getSideFragmentManager()
+ .show(new CustomizeChannelListFragment());
} else {
mOverlayManager.showSetupFragment();
}
return;
}
- if (!TvCommonUtils.isRunningInTest() && mShowNewSourcesFragment
- && setupUtils.hasUnrecognizedInput(mTvInputManagerHelper)) {
+ if (!CommonUtils.isRunningInTest()
+ && mShowNewSourcesFragment
+ && mSetupUtils.hasUnrecognizedInput(mTvInputManagerHelper)) {
// Show new channel sources fragment.
- runAfterAttachedToWindow(new Runnable() {
- @Override
- public void run() {
- mOverlayManager.runAfterOverlaysAreClosed(new Runnable() {
+ runAfterAttachedToWindow(
+ new Runnable() {
@Override
public void run() {
- mOverlayManager.showNewSourcesFragment();
+ mOverlayManager.runAfterOverlaysAreClosed(
+ new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.showNewSourcesFragment();
+ }
+ });
}
});
- }
- });
}
- setupUtils.onTuned();
+ mSetupUtils.onTuned();
if (mTuneParams != null) {
Long initChannelId = mTuneParams.getLong(KEY_INIT_CHANNEL_ID);
if (initChannelId == channel.getId()) {
@@ -1571,9 +1747,11 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
// For every tune, we need to inform the tuned channel or input to a user,
// if Talkback is turned on.
- sendAccessibilityText(!mChannelTuner.isCurrentChannelPassthrough() ?
- Utils.loadLabel(this, mTvInputManagerHelper.getTvInputInfo(channel.getInputId()))
- : channel.getDisplayText());
+ sendAccessibilityText(
+ mChannelTuner.isCurrentChannelPassthrough()
+ ? Utils.loadLabel(
+ this, mTvInputManagerHelper.getTvInputInfo(channel.getInputId()))
+ : channel.getDisplayText());
boolean success = mTvView.tuneTo(channel, mTuneParams, mOnTuneListener);
mOnTuneListener.onTune(channel, isUnderShrunkenTvView());
@@ -1592,7 +1770,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
addToRecentChannels(channel.getId());
}
Utils.setLastWatchedChannel(this, channel);
- TvApplication.getSingletons(this).getMainActivityWrapper()
+ TvSingletons.getSingletons(this)
+ .getMainActivityWrapper()
.notifyCurrentChannelChange(this, channel);
}
// We have to provide channel here instead of using TvView's channel, because TvView's
@@ -1619,34 +1798,42 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
// If the activity is paused shortly, runnable may not be called because all the fragments
// should be closed when the activity is paused.
private void runAfterAttachedToWindow(final Runnable runnable) {
- final Runnable runOnlyIfActivityIsResumed = new Runnable() {
- @Override
- public void run() {
- if (mActivityResumed) {
- runnable.run();
- }
- }
- };
+ final Runnable runOnlyIfActivityIsResumed =
+ new Runnable() {
+ @Override
+ public void run() {
+ if (mActivityResumed) {
+ runnable.run();
+ }
+ }
+ };
if (mContentView.isAttachedToWindow()) {
mHandler.post(runOnlyIfActivityIsResumed);
} else {
- mContentView.getViewTreeObserver().addOnWindowAttachListener(
- new ViewTreeObserver.OnWindowAttachListener() {
- @Override
- public void onWindowAttached() {
- mContentView.getViewTreeObserver().removeOnWindowAttachListener(this);
- mHandler.post(runOnlyIfActivityIsResumed);
- }
+ mContentView
+ .getViewTreeObserver()
+ .addOnWindowAttachListener(
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ mContentView
+ .getViewTreeObserver()
+ .removeOnWindowAttachListener(this);
+ mHandler.post(runOnlyIfActivityIsResumed);
+ }
- @Override
- public void onWindowDetached() { }
- });
+ @Override
+ public void onWindowDetached() {}
+ });
}
}
boolean isNowPlayingProgram(Channel channel, Program program) {
- return program == null ? (channel != null && getCurrentProgram() == null
- && channel.equals(getCurrentChannel())) : program.equals(getCurrentProgram());
+ return program == null
+ ? (channel != null
+ && getCurrentProgram() == null
+ && channel.equals(getCurrentChannel()))
+ : program.equals(getCurrentProgram());
}
private void addToRecentChannels(long channelId) {
@@ -1659,9 +1846,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mOverlayManager.getMenu().onRecentChannelsChanged();
}
- /**
- * Returns the recently tuned channels.
- */
+ /** Returns the recently tuned channels. */
public ArrayDeque<Long> getRecentChannels() {
return mRecentChannels;
}
@@ -1694,9 +1879,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
}
- /**
- * Hide the overlays when tuning to a channel from the menu (e.g. Channels).
- */
+ /** Hide the overlays when tuning to a channel from the menu (e.g. Channels). */
public void hideOverlaysForTune() {
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SCENE);
}
@@ -1712,8 +1895,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
setPreferredRefreshRate(mDefaultRefreshRate);
mIsFilmModeSet = false;
} else if (!mIsFilmModeSet && is24Fps) {
- DisplayManager displayManager = (DisplayManager) getSystemService(
- Context.DISPLAY_SERVICE);
+ DisplayManager displayManager =
+ (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
float[] refreshRates = display.getSupportedRefreshRates();
@@ -1745,8 +1928,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
String id = TvSettings.getMultiAudioId(this);
String language = TvSettings.getMultiAudioLanguage(this);
int channelCount = TvSettings.getMultiAudioChannelCount(this);
- TvTrackInfo bestTrack = TvTrackInfoUtils
- .getBestTrackInfo(tracks, id, language, channelCount);
+ TvTrackInfo bestTrack =
+ TvTrackInfoUtils.getBestTrackInfo(tracks, id, language, channelCount);
if (bestTrack != null) {
String selectedTrack = getSelectedTrack(TvTrackInfo.TYPE_AUDIO);
if (!bestTrack.getId().equals(selectedTrack)) {
@@ -1787,8 +1970,13 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
mTvOptionsManager.onClosedCaptionsChanged(track, i);
}
if (DEBUG) {
- Log.d(TAG, "Subtitle Track Selected {id=" + track.getId()
- + ", language=" + track.getLanguage() + "}");
+ Log.d(
+ TAG,
+ "Subtitle Track Selected {id="
+ + track.getId()
+ + ", language="
+ + track.getLanguage()
+ + "}");
}
return;
} else if (alternativeTrack == null) {
@@ -1801,12 +1989,17 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
if (!alternativeTrack.getId().equals(selectedTrackId)) {
selectTrack(TvTrackInfo.TYPE_SUBTITLE, alternativeTrack, alternativeTrackIndex);
} else {
- mTvOptionsManager
- .onClosedCaptionsChanged(alternativeTrack, alternativeTrackIndex);
+ mTvOptionsManager.onClosedCaptionsChanged(
+ alternativeTrack, alternativeTrackIndex);
}
if (DEBUG) {
- Log.d(TAG, "Subtitle Track Selected {id=" + alternativeTrack.getId()
- + ", language=" + alternativeTrack.getLanguage() + "}");
+ Log.d(
+ TAG,
+ "Subtitle Track Selected {id="
+ + alternativeTrack.getId()
+ + ", language="
+ + alternativeTrack.getLanguage()
+ + "}");
}
return;
}
@@ -1820,8 +2013,11 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
public void showProgramGuideSearchFragment() {
- getFragmentManager().beginTransaction().replace(R.id.fragment_container, mSearchFragment)
- .addToBackStack(null).commit();
+ getFragmentManager()
+ .beginTransaction()
+ .replace(R.id.fragment_container, mSearchFragment)
+ .addToBackStack(null)
+ .commit();
}
@Override
@@ -1853,6 +2049,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
}
if (mOverlayManager != null) {
+ mAccessibilityManager.removeAccessibilityStateChangeListener(mOverlayManager);
mOverlayManager.release();
}
mMemoryManageables.clear();
@@ -1874,7 +2071,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
if (mTvInputManagerHelper != null) {
mTvInputManagerHelper.clearTvInputLabels();
- if (Features.TUNER.isEnabled(this)) {
+ if (TvFeatures.TUNER.isEnabled(this)) {
mTvInputManagerHelper.removeCallback(mTvInputCallback);
}
}
@@ -1895,7 +2092,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return false;
case KEY_EVENT_HANDLER_RESULT_PASSTHROUGH:
default:
- // pass through
+ // fall through
}
if (mSearchFragment.isVisible()) {
return super.onKeyDown(keyCode, event);
@@ -1903,35 +2100,51 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
if (!mChannelTuner.areAllChannelsLoaded()) {
return false;
}
+ if (handleUpDownKeys(keyCode, event)) {
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ private boolean handleUpDownKeys(int keyCode, @Nullable KeyEvent event) {
if (!mChannelTuner.isCurrentChannelPassthrough()) {
switch (keyCode) {
case KeyEvent.KEYCODE_CHANNEL_UP:
case KeyEvent.KEYCODE_DPAD_UP:
- if (event.getRepeatCount() == 0
+ if ((event == null || event.getRepeatCount() == 0)
&& mChannelTuner.getBrowsableChannelCount() > 0) {
// message sending should be done before moving channel, because we use the
// existence of message to decide if users are switching channel.
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHANNEL_UP_PRESSED,
- System.currentTimeMillis()), CHANNEL_CHANGE_INITIAL_DELAY_MILLIS);
+ if (event != null) {
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(
+ MSG_CHANNEL_UP_PRESSED, System.currentTimeMillis()),
+ CHANNEL_CHANGE_INITIAL_DELAY_MILLIS);
+ }
moveToAdjacentChannel(true, false);
mTracker.sendChannelUp();
}
return true;
case KeyEvent.KEYCODE_CHANNEL_DOWN:
case KeyEvent.KEYCODE_DPAD_DOWN:
- if (event.getRepeatCount() == 0
+ if ((event == null || event.getRepeatCount() == 0)
&& mChannelTuner.getBrowsableChannelCount() > 0) {
// message sending should be done before moving channel, because we use the
// existence of message to decide if users are switching channel.
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHANNEL_DOWN_PRESSED,
- System.currentTimeMillis()), CHANNEL_CHANGE_INITIAL_DELAY_MILLIS);
+ if (event != null) {
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(
+ MSG_CHANNEL_DOWN_PRESSED, System.currentTimeMillis()),
+ CHANNEL_CHANGE_INITIAL_DELAY_MILLIS);
+ }
moveToAdjacentChannel(false, false);
mTracker.sendChannelDown();
}
return true;
+ default: // fall out
}
}
- return super.onKeyDown(keyCode, event);
+ return false;
}
@Override
@@ -1969,7 +2182,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return false;
case KEY_EVENT_HANDLER_RESULT_PASSTHROUGH:
default:
- // pass through
+ // fall through
}
if (mSearchFragment.isVisible()) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
@@ -1999,6 +2212,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
case KeyEvent.KEYCODE_MENU:
showSettingsFragment();
return true;
+ default: // fall out
}
} else {
if (KeypadChannelSwitchView.isChannelNumberKey(keyCode)) {
@@ -2009,9 +2223,9 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!mTvView.isVideoOrAudioAvailable()
&& mTvView.getVideoUnavailableReason()
- == TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE) {
- DvrUiHelper.startSchedulesActivityForTuneConflict(this,
- mChannelTuner.getCurrentChannel());
+ == TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE) {
+ DvrUiHelper.startSchedulesActivityForTuneConflict(
+ this, mChannelTuner.getCurrentChannel());
return true;
}
if (!PermissionUtils.hasModifyParentalControls(this)) {
@@ -2019,16 +2233,18 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
PinDialogFragment dialog = null;
if (mTvView.isScreenBlocked()) {
- dialog = PinDialogFragment
- .create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_CHANNEL);
+ dialog =
+ PinDialogFragment.create(
+ PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_CHANNEL);
} else if (mTvView.isContentBlocked()) {
- dialog = PinDialogFragment
- .create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM,
+ dialog =
+ PinDialogFragment.create(
+ PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM,
mTvView.getBlockedContentRating().flattenToString());
}
if (dialog != null) {
- mOverlayManager.showDialogFragment(PinDialogFragment.DIALOG_TAG, dialog,
- false);
+ mOverlayManager.showDialogFragment(
+ PinDialogFragment.DIALOG_TAG, dialog, false);
}
return true;
case KeyEvent.KEYCODE_WINDOW:
@@ -2064,49 +2280,56 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
- // Pass through.
- case KeyEvent.KEYCODE_CAPTIONS: {
+ // fall through.
+ case KeyEvent.KEYCODE_CAPTIONS:
mOverlayManager.getSideFragmentManager().show(new ClosedCaptionFragment());
return true;
- }
case KeyEvent.KEYCODE_A:
if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
- // Pass through.
- case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+ // fall through.
+ case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
mOverlayManager.getSideFragmentManager().show(new MultiAudioFragment());
return true;
- }
- case KeyEvent.KEYCODE_INFO: {
+ case KeyEvent.KEYCODE_INFO:
mOverlayManager.showBanner();
return true;
- }
case KeyEvent.KEYCODE_MEDIA_RECORD:
- case KeyEvent.KEYCODE_V: {
+ case KeyEvent.KEYCODE_V:
Channel currentChannel = getCurrentChannel();
if (currentChannel != null && mDvrManager != null) {
boolean isRecording =
mDvrManager.getCurrentRecording(currentChannel.getId()) != null;
if (!isRecording) {
if (!mDvrManager.isChannelRecordable(currentChannel)) {
- Toast.makeText(this, R.string.dvr_msg_cannot_record_program,
- Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ this,
+ R.string.dvr_msg_cannot_record_program,
+ Toast.LENGTH_SHORT)
+ .show();
} else {
- Program program = mProgramDataManager
- .getCurrentProgram(currentChannel.getId());
- DvrUiHelper.checkStorageStatusAndShowErrorMessage(this,
- currentChannel.getInputId(), new Runnable() {
+ Program program =
+ mProgramDataManager.getCurrentProgram(
+ currentChannel.getId());
+ DvrUiHelper.checkStorageStatusAndShowErrorMessage(
+ this,
+ currentChannel.getInputId(),
+ new Runnable() {
@Override
public void run() {
DvrUiHelper.requestRecordingCurrentProgram(
MainActivity.this,
- currentChannel, program, false);
+ currentChannel,
+ program,
+ false);
}
});
}
} else {
- DvrUiHelper.showStopRecordingDialog(this, currentChannel.getId(),
+ DvrUiHelper.showStopRecordingDialog(
+ this,
+ currentChannel.getId(),
DvrStopRecordingFragment.REASON_USER_STOP,
new HalfSizedDialogFragment.OnActionClickListener() {
@Override
@@ -2124,7 +2347,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
}
return true;
- }
+ default: // fall out
}
}
if (keyCode == KeyEvent.KEYCODE_WINDOW) {
@@ -2162,6 +2385,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
case KeyEvent.KEYCODE_D:
mOverlayManager.getSideFragmentManager().show(new DeveloperOptionFragment());
return true;
+ default: // fall out
}
}
return super.onKeyUp(keyCode, event);
@@ -2196,13 +2420,19 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
// We need to hide overlay first, before moving the activity to PIP. If not, UI will
// be shown during PIP stack resizing, because UI and its animation is stuck during
// PIP resizing.
- mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- MainActivity.super.enterPictureInPictureMode();
- }
- });
+ mIsInPIPMode = true;
+ if (mOverlayManager.isOverlayOpened()) {
+ mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION);
+ mHandler.post(
+ new Runnable() {
+ @Override
+ public void run() {
+ MainActivity.super.enterPictureInPictureMode();
+ }
+ });
+ } else {
+ MainActivity.super.enterPictureInPictureMode();
+ }
}
@Override
@@ -2248,7 +2478,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
if (isKeyEventBlocked()) {
if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK
- || event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_B) && mNeedShowBackKeyGuide) {
+ || event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_B)
+ && mNeedShowBackKeyGuide) {
// KeyEvent.KEYCODE_BUTTON_B is also used like the back button.
Toast.makeText(this, R.string.msg_back_key_guide, Toast.LENGTH_SHORT).show();
mNeedShowBackKeyGuide = false;
@@ -2283,7 +2514,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
} else if (channel.equals(mTvView.getCurrentChannel())) {
mOverlayManager.updateChannelBannerAndShowIfNeeded(
TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
- } else if (channel == mChannelTuner.getCurrentChannel()) {
+ } else if (channel.equals(mChannelTuner.getCurrentChannel())) {
// Channel banner is already updated in moveToAdjacentChannel
tune(false);
} else if (mChannelTuner.moveToChannel(channel)) {
@@ -2296,24 +2527,23 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
/**
- * This method just moves the channel in the channel map and updates the channel banner,
- * but doesn't actually tune to the channel.
- * The caller of this method should call {@link #tune} in the end.
+ * This method just moves the channel in the channel map and updates the channel banner, but
+ * doesn't actually tune to the channel. The caller of this method should call {@link #tune} in
+ * the end.
*
* @param channelUp {@code true} for channel up, and {@code false} for channel down.
* @param fastTuning {@code true} if fast tuning is requested.
*/
private void moveToAdjacentChannel(boolean channelUp, boolean fastTuning) {
if (mChannelTuner.moveToAdjacentBrowsableChannel(channelUp)) {
- mOverlayManager.updateChannelBannerAndShowIfNeeded(fastTuning ?
- TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST
- : TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ fastTuning
+ ? TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST
+ : TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
}
}
- /**
- * Set the main TV view which holds HDMI-CEC active source based on the sound mode
- */
+ /** Set the main TV view which holds HDMI-CEC active source based on the sound mode */
private void restoreMainTvView() {
mTvView.setMain();
}
@@ -2355,8 +2585,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private void selectTrack(int type, TvTrackInfo track, int trackIndex) {
mTvView.selectTrack(type, track == null ? null : track.getId());
if (type == TvTrackInfo.TYPE_AUDIO) {
- mTvOptionsManager.onMultiAudioChanged(track == null ? null :
- Utils.getMultiAudioString(this, track, false));
+ mTvOptionsManager.onMultiAudioChanged(
+ track == null ? null : Utils.getMultiAudioString(this, track, false));
} else if (type == TvTrackInfo.TYPE_SUBTITLE) {
mTvOptionsManager.onClosedCaptionsChanged(track, trackIndex);
}
@@ -2414,7 +2644,8 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
private void updateAvailabilityToast() {
if (mTvView.isVideoAvailable()
- || mTvView.getCurrentChannel() != mChannelTuner.getCurrentChannel()) {
+ || !Objects.equals(
+ mTvView.getCurrentChannel(), mChannelTuner.getCurrentChannel())) {
return;
}
@@ -2428,50 +2659,38 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return;
case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
default:
- Toast.makeText(this, R.string.msg_channel_unavailable_unknown,
- Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, R.string.msg_channel_unavailable_unknown, Toast.LENGTH_SHORT)
+ .show();
break;
}
}
- /**
- * Returns {@code true} if some overlay UI will be shown when the activity is resumed.
- */
+ /** Returns {@code true} if some overlay UI will be shown when the activity is resumed. */
public boolean willShowOverlayUiWhenResume() {
return mInputToSetUp != null || mShowProgramGuide || mShowSelectInputView;
}
- /**
- * Returns the current parental control settings.
- */
+ /** Returns the current parental control settings. */
public ParentalControlSettings getParentalControlSettings() {
return mTvInputManagerHelper.getParentalControlSettings();
}
- /**
- * Returns a ContentRatingsManager instance.
- */
+ /** Returns a ContentRatingsManager instance. */
public ContentRatingsManager getContentRatingsManager() {
return mTvInputManagerHelper.getContentRatingsManager();
}
- /**
- * Returns the current captioning settings.
- */
+ /** Returns the current captioning settings. */
public CaptionSettings getCaptionSettings() {
return mCaptionSettings;
}
- /**
- * Adds the {@link OnActionClickListener}.
- */
+ /** Adds the {@link OnActionClickListener}. */
public void addOnActionClickListener(OnActionClickListener listener) {
mOnActionClickListeners.add(listener);
}
- /**
- * Removes the {@link OnActionClickListener}.
- */
+ /** Removes the {@link OnActionClickListener}. */
public void removeOnActionClickListener(OnActionClickListener listener) {
mOnActionClickListeners.remove(listener);
}
@@ -2490,7 +2709,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
// Initialize TV app for test. The setup process should be finished before the Live TV app is
// started. We only enable all the channels here.
private void initForTest() {
- if (!TvCommonUtils.isRunningInTest()) {
+ if (!CommonUtils.isRunningInTest()) {
return;
}
@@ -2505,16 +2724,18 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
}
mLazyInitialized = true;
// Running initialization.
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mActivityStarted) {
- initAnimations();
- initSideFragments();
- initMenuItemViews();
- }
- }
- }, LAZY_INITIALIZATION_DELAY);
+ mHandler.postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ if (mActivityStarted) {
+ initAnimations();
+ initSideFragments();
+ initMenuItemViews();
+ }
+ }
+ },
+ LAZY_INITIALIZATION_DELAY);
}
private void initAnimations() {
@@ -2560,6 +2781,7 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
sendMessageDelayed(Message.obtain(msg), getDelay(startTime));
mainActivity.moveToAdjacentChannel(true, true);
break;
+ default: // fall out
}
}
@@ -2594,17 +2816,19 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
if (mTvView.isFadedOut()) {
mTvView.removeFadeEffect();
}
- Toast.makeText(MainActivity.this, R.string.msg_channel_unavailable_unknown,
- Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ MainActivity.this,
+ R.string.msg_channel_unavailable_unknown,
+ Toast.LENGTH_SHORT)
+ .show();
}
@Override
public void onStreamInfoChanged(StreamInfo info) {
if (info.isVideoAvailable() && mTuneDurationTimer.isRunning()) {
- mTracker.sendChannelTuneTime(info.getCurrentChannel(),
- mTuneDurationTimer.reset());
+ mTracker.sendChannelTuneTime(info.getCurrentChannel(), mTuneDurationTimer.reset());
}
- if (info.isVideoOrAudioAvailable() && mChannel == getCurrentChannel()) {
+ if (info.isVideoOrAudioAvailable() && mChannel.equals(getCurrentChannel())) {
mOverlayManager.updateChannelBannerAndShowIfNeeded(
TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_STREAM_INFO);
}
@@ -2629,10 +2853,12 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
return;
}
Channel currentChannel =
- mChannelDataManager.getChannel(ContentUris.parseId(channel));
+ mChannelDataManager.getChannel(ContentUriUtils.safeParseId(channel));
if (currentChannel == null) {
- Log.e(TAG, "onChannelRetuned is called but can't find a channel with the URI "
- + channel);
+ Log.e(
+ TAG,
+ "onChannelRetuned is called but can't find a channel with the URI "
+ + channel);
return;
}
if (isChannelChangeKeyDownReceived()) {
@@ -2647,15 +2873,16 @@ public class MainActivity extends Activity implements OnActionClickListener, OnP
@Override
public void onContentBlocked() {
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
- "MainActivity.MyOnTuneListener.onContentBlocked removes timer");
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log("MainActivity.MyOnTuneListener.onContentBlocked removes timer");
Debug.removeTimer(Debug.TAG_START_UP_TIMER);
mTuneDurationTimer.reset();
TvContentRating rating = mTvView.getBlockedContentRating();
// When tuneTo was called while TV view was shrunken, if the channel id is the same
// with the channel watched before shrunken, we allow the rating which was allowed
// before.
- if (mWasUnderShrunkenTvView && mUnlockAllowedRatingBeforeShrunken
+ if (mWasUnderShrunkenTvView
+ && mUnlockAllowedRatingBeforeShrunken
&& mChannelBeforeShrunkenTvView.equals(mChannel)
&& rating.equals(mAllowedRatingBeforeShrunken)) {
mUnlockAllowedRatingBeforeShrunken = isUnderShrunkenTvView();