aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/dvr/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/dvr/ui')
-rw-r--r--src/com/android/tv/dvr/ui/ActionPresenterSelector.java (renamed from src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java)10
-rw-r--r--src/com/android/tv/dvr/ui/BigArguments.java54
-rw-r--r--src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java79
-rw-r--r--src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java59
-rw-r--r--src/com/android/tv/dvr/ui/DetailsContent.java (renamed from src/com/android/tv/dvr/ui/browse/DetailsContent.java)4
-rw-r--r--src/com/android/tv/dvr/ui/DetailsContentPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java)37
-rw-r--r--src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java (renamed from src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java)4
-rw-r--r--src/com/android/tv/dvr/ui/DvrActivity.java (renamed from src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java)6
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java5
-rw-r--r--src/com/android/tv/dvr/ui/DvrBrowseFragment.java (renamed from src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java)159
-rw-r--r--src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/DvrConflictFragment.java7
-rw-r--r--src/com/android/tv/dvr/ui/DvrDetailsActivity.java (renamed from src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java)2
-rw-r--r--src/com/android/tv/dvr/ui/DvrDetailsFragment.java (renamed from src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java)6
-rw-r--r--src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java87
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java50
-rw-r--r--src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java12
-rw-r--r--src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java84
-rw-r--r--src/com/android/tv/dvr/ui/DvrItemPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java)13
-rw-r--r--src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java50
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java (renamed from src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java)31
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java (renamed from src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java)106
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java (renamed from src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java)181
-rw-r--r--src/com/android/tv/dvr/ui/DvrScheduleFragment.java17
-rw-r--r--src/com/android/tv/dvr/ui/DvrSchedulesActivity.java (renamed from src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java)76
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java5
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java45
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java20
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java11
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java4
-rw-r--r--src/com/android/tv/dvr/ui/DvrUiHelper.java575
-rw-r--r--src/com/android/tv/dvr/ui/FadeBackground.java70
-rw-r--r--src/com/android/tv/dvr/ui/FullScheduleCardHolder.java (renamed from src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java)2
-rw-r--r--src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java)66
-rw-r--r--src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java117
-rw-r--r--src/com/android/tv/dvr/ui/PrioritySettingsFragment.java (renamed from src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java)7
-rw-r--r--src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java (renamed from src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java)6
-rw-r--r--src/com/android/tv/dvr/ui/RecordedProgramPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java)31
-rw-r--r--src/com/android/tv/dvr/ui/RecordingCardView.java (renamed from src/com/android/tv/dvr/ui/browse/RecordingCardView.java)113
-rw-r--r--src/com/android/tv/dvr/ui/RecordingDetailsFragment.java (renamed from src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java)4
-rw-r--r--src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java (renamed from src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java)4
-rw-r--r--src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java)21
-rw-r--r--src/com/android/tv/dvr/ui/SeriesDeletionFragment.java (renamed from src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java)11
-rw-r--r--src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java (renamed from src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java)24
-rw-r--r--src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java (renamed from src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java)11
-rw-r--r--src/com/android/tv/dvr/ui/SeriesSettingsFragment.java (renamed from src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java)209
-rw-r--r--src/com/android/tv/dvr/ui/SortedArrayAdapter.java90
-rw-r--r--src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java120
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java34
-rw-r--r--src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java5
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java72
-rw-r--r--src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java6
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRow.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java50
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java20
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java26
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java24
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java17
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java67
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java335
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java154
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlayer.java583
65 files changed, 898 insertions, 3216 deletions
diff --git a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java b/src/com/android/tv/dvr/ui/ActionPresenterSelector.java
index 38a78f5d..8b8cd5c5 100644
--- a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
+++ b/src/com/android/tv/dvr/ui/ActionPresenterSelector.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.graphics.drawable.Drawable;
import android.support.v17.leanback.R;
@@ -110,7 +110,11 @@ class ActionPresenterSelector extends PresenterSelector {
.getDimensionPixelSize(R.dimen.lb_action_padding_horizontal);
vh.view.setPaddingRelative(padding, 0, padding, 0);
}
- vh.mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
+ if (vh.mLayoutDirection == View.LAYOUT_DIRECTION_RTL) {
+ vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
+ } else {
+ vh.mButton.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
+ }
CharSequence line1 = action.getLabel1();
CharSequence line2 = action.getLabel2();
@@ -126,7 +130,7 @@ class ActionPresenterSelector extends PresenterSelector {
@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
ActionViewHolder vh = (ActionViewHolder) viewHolder;
- vh.mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null);
+ vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
vh.view.setPadding(0, 0, 0, 0);
vh.mAction = null;
}
diff --git a/src/com/android/tv/dvr/ui/BigArguments.java b/src/com/android/tv/dvr/ui/BigArguments.java
deleted file mode 100644
index ec3b5065..00000000
--- a/src/com/android/tv/dvr/ui/BigArguments.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui;
-
-import android.support.annotation.NonNull;
-
-import com.android.tv.common.SoftPreconditions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Stores the object to pass through activities/fragments.
- */
-public class BigArguments {
- private final static String TAG = "BigArguments";
- private static Map<String, Object> sBigArgumentMap = new HashMap<>();
-
- /**
- * Sets the argument.
- */
- public static void setArgument(String name, @NonNull Object value) {
- SoftPreconditions.checkState(value != null, TAG, "Set argument, but value is null");
- sBigArgumentMap.put(name, value);
- }
-
- /**
- * Returns the argument which is associated to the name.
- */
- public static Object getArgument(String name) {
- return sBigArgumentMap.get(name);
- }
-
- /**
- * Resets the arguments.
- */
- public static void reset() {
- sBigArgumentMap.clear();
- }
-}
diff --git a/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java b/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java
deleted file mode 100644
index cddece73..00000000
--- a/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.drawable.BitmapDrawable;
-import android.transition.ChangeImageTransform;
-import android.transition.TransitionValues;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-
-import com.android.tv.R;
-
-import java.util.Map;
-
-/**
- * TODO: Remove this class once b/32405620 is fixed.
- * This class is for the workaround of b/32405620 and only for the shared element transition between
- * {@link com.android.tv.dvr.ui.browse.RecordingCardView} and
- * {@link com.android.tv.dvr.ui.browse.DvrDetailsActivity}.
- */
-public class ChangeImageTransformWithScaledParent extends ChangeImageTransform {
- private static final String PROPNAME_MATRIX = "android:changeImageTransform:matrix";
-
- public ChangeImageTransformWithScaledParent(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void captureStartValues(TransitionValues transitionValues) {
- super.captureStartValues(transitionValues);
- applyParentScale(transitionValues);
- }
-
- @Override
- public void captureEndValues(TransitionValues transitionValues) {
- super.captureEndValues(transitionValues);
- applyParentScale(transitionValues);
- }
-
- private void applyParentScale(TransitionValues transitionValues) {
- View view = transitionValues.view;
- Map<String, Object> values = transitionValues.values;
- Matrix matrix = (Matrix) values.get(PROPNAME_MATRIX);
- if (matrix != null && view.getId() == R.id.details_overview_image
- && view instanceof ImageView) {
- ImageView imageView = (ImageView) view;
- if (imageView.getScaleType() == ScaleType.CENTER_INSIDE
- && imageView.getDrawable() instanceof BitmapDrawable) {
- Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
- if (bitmap.getWidth() < imageView.getWidth()
- && bitmap.getHeight() < imageView.getHeight()) {
- float scale = imageView.getContext().getResources().getFraction(
- R.fraction.lb_focus_zoom_factor_medium, 1, 1);
- matrix.postScale(scale, scale, imageView.getWidth() / 2,
- imageView.getHeight() / 2);
- }
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java
new file mode 100644
index 00000000..5d8e20ff
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.tv.dvr.ui;
+
+import android.content.res.Resources;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrManager;
+
+/**
+ * {@link RecordingDetailsFragment} for current recording in DVR.
+ */
+public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
+ private static final int ACTION_STOP_RECORDING = 1;
+
+ @Override
+ protected SparseArrayObjectAdapter onCreateActionsAdapter() {
+ SparseArrayObjectAdapter adapter =
+ new SparseArrayObjectAdapter(new ActionPresenterSelector());
+ Resources res = getResources();
+ adapter.set(ACTION_STOP_RECORDING, new Action(ACTION_STOP_RECORDING,
+ res.getString(R.string.epg_dvr_dialog_message_stop_recording), null,
+ res.getDrawable(R.drawable.lb_ic_stop)));
+ return adapter;
+ }
+
+ @Override
+ protected OnActionClickedListener onCreateOnActionClickedListener() {
+ return new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ if (action.getId() == ACTION_STOP_RECORDING) {
+ DvrManager dvrManager = TvApplication.getSingletons(getActivity())
+ .getDvrManager();
+ dvrManager.stopRecording(getRecording());
+ }
+ getActivity().finish();
+ }
+ };
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContent.java b/src/com/android/tv/dvr/ui/DetailsContent.java
index b43d1f12..19521fca 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContent.java
+++ b/src/com/android/tv/dvr/ui/DetailsContent.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.media.tv.TvContract;
import android.support.annotation.Nullable;
@@ -26,7 +26,7 @@ import com.android.tv.data.Channel;
/**
* A class for details content.
*/
-class DetailsContent {
+public class DetailsContent {
/** Constant for invalid time. */
public static final long INVALID_TIME = -1;
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/DetailsContentPresenter.java
index a2e3fe16..175f05bc 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
+++ b/src/com/android/tv/dvr/ui/DetailsContentPresenter.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.animation.Animator;
@@ -38,14 +38,13 @@ 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}.
+ * Typically this Presenter will be used in a {@link DetailsOverviewRowPresenter}.
* Most codes of this class is originated from
* {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
* The latter class are re-used to provide a customized version of
* {@link android.support.v17.leanback.widget.DetailsOverviewRow}.
*/
-class DetailsContentPresenter extends Presenter {
+public class DetailsContentPresenter extends Presenter {
/**
* The ViewHolder for the {@link DetailsContentPresenter}.
*/
@@ -114,20 +113,6 @@ class DetailsContentPresenter extends Presenter {
public ViewHolder(final View view) {
super(view);
- view.addOnAttachStateChangeListener(
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- // In case predraw listener was removed in detach, make sure
- // we have the proper layout.
- addPreDrawListener();
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- removePreDrawListener();
- }
- });
mTitle = (TextView) view.findViewById(R.id.dvr_details_description_title);
mSubtitle = (TextView) view.findViewById(R.id.dvr_details_description_subtitle);
mBody = (TextView) view.findViewById(R.id.dvr_details_description_body);
@@ -291,6 +276,22 @@ class DetailsContentPresenter extends Presenter {
@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { }
+ @Override
+ public void onViewAttachedToWindow(Presenter.ViewHolder holder) {
+ // In case predraw listener was removed in detach, make sure
+ // we have the proper layout.
+ ViewHolder vh = (ViewHolder) holder;
+ vh.addPreDrawListener();
+ super.onViewAttachedToWindow(holder);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(Presenter.ViewHolder holder) {
+ ViewHolder vh = (ViewHolder) holder;
+ vh.removePreDrawListener();
+ super.onViewDetachedFromWindow(holder);
+ }
+
private void setTopMargin(View view, int topMargin) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
lp.topMargin = topMargin;
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java b/src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java
index 82fe9ce3..6714ecd3 100644
--- a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
+++ b/src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
@@ -26,7 +26,7 @@ import android.support.v17.leanback.app.BackgroundManager;
/**
* The Background Helper.
*/
-class DetailsViewBackgroundHelper {
+public class DetailsViewBackgroundHelper {
// Background delay serves to avoid kicking off expensive bitmap loading
// in case multiple backgrounds are set in quick succession.
private static final int SET_BACKGROUND_DELAY_MS = 100;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java b/src/com/android/tv/dvr/ui/DvrActivity.java
index 2b3dcb25..45fb1cf1 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrActivity.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.os.Bundle;
@@ -25,11 +25,11 @@ import com.android.tv.TvApplication;
/**
* {@link android.app.Activity} for DVR UI.
*/
-public class DvrBrowseActivity extends Activity {
+public class DvrActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
TvApplication.setCurrentRunningProcess(this, true);
super.onCreate(savedInstanceState);
setContentView(R.layout.dvr_main);
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
index 936e9c31..9df228d1 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
@@ -28,9 +28,11 @@ import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.util.Utils;
import java.util.List;
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
index 3c73cb47..78f21784 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
@@ -25,12 +25,15 @@ import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
+import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.util.Utils;
import java.util.List;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
index 803d1017..a6dd31d1 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
@@ -14,9 +14,10 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.Context;
+import android.media.tv.TvInputManager.TvInputCallback;
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.app.BrowseFragment;
@@ -24,11 +25,11 @@ 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.ListRowPresenter;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.TitleViewAdapter;
+import android.text.TextUtils;
import android.util.Log;
-import android.view.View;
-import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
import com.android.tv.ApplicationSingletons;
import com.android.tv.R;
@@ -41,10 +42,9 @@ import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.ui.SortedArrayAdapter;
+import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import java.util.ArrayList;
import java.util.Arrays;
@@ -79,20 +79,6 @@ public class DvrBrowseFragment extends BrowseFragment implements
private ClassPresenterSelector mPresenterSelector;
private final HashMap<String, RecordedProgram> mSeriesId2LatestProgram = new HashMap<>();
private final Handler mHandler = new Handler();
- private final OnGlobalFocusChangeListener mOnGlobalFocusChangeListener =
- new OnGlobalFocusChangeListener() {
- @Override
- public void onGlobalFocusChanged(View oldFocus, View newFocus) {
- if (oldFocus instanceof RecordingCardView) {
- ((RecordingCardView) oldFocus).expandTitle(false, true);
- }
- if (newFocus instanceof RecordingCardView) {
- // If the header transition is ongoing, expand cards immediately without
- // animation to make a smooth transition.
- ((RecordingCardView) newFocus).expandTitle(true, !isInHeadersTransition());
- }
- }
- };
private final Comparator<Object> RECORDED_PROGRAM_COMPARATOR = new Comparator<Object>() {
@Override
@@ -142,7 +128,7 @@ public class DvrBrowseFragment extends BrowseFragment implements
public void onConflictStateChange(boolean conflict, ScheduledRecording... schedules) {
if (mScheduleAdapter != null) {
for (ScheduledRecording schedule : schedules) {
- onScheduledRecordingConflictStatusChanged(schedule);
+ onScheduledRecordingStatusChanged(schedule);
}
}
}
@@ -168,12 +154,16 @@ public class DvrBrowseFragment extends BrowseFragment implements
new ScheduledRecordingPresenter(context))
.addClassPresenter(RecordedProgram.class, new RecordedProgramPresenter(context))
.addClassPresenter(SeriesRecording.class, new SeriesRecordingPresenter(context))
- .addClassPresenter(FullScheduleCardHolder.class,
- new FullSchedulesCardPresenter(context));
+ .addClassPresenter(FullScheduleCardHolder.class, new FullSchedulesCardPresenter());
mGenreLabels = new ArrayList<>(Arrays.asList(GenreItems.getLabels(context)));
mGenreLabels.add(getString(R.string.dvr_main_others));
- prepareUiElements();
- if (!startBrowseIfDvrInitialized()) {
+ setupUiElements();
+ setupAdapters();
+ mDvrScheudleManager.addOnConflictStateChangeListener(mOnConflictStateChangeListener);
+ prepareEntranceTransition();
+ if (mDvrDataManager.isInitialized()) {
+ startEntranceTransition();
+ } else {
if (!mDvrDataManager.isDvrScheduleLoadFinished()) {
mDvrDataManager.addDvrScheduleLoadFinishedListener(this);
}
@@ -184,19 +174,6 @@ public class DvrBrowseFragment extends BrowseFragment implements
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- view.getViewTreeObserver().addOnGlobalFocusChangeListener(mOnGlobalFocusChangeListener);
- }
-
- @Override
- public void onDestroyView() {
- getView().getViewTreeObserver()
- .removeOnGlobalFocusChangeListener(mOnGlobalFocusChangeListener);
- super.onDestroyView();
- }
-
- @Override
public void onDestroy() {
if (DEBUG) Log.d(TAG, "onDestroy");
mHandler.removeCallbacks(mUpdateRowsRunnable);
@@ -218,13 +195,25 @@ public class DvrBrowseFragment extends BrowseFragment implements
@Override
public void onDvrScheduleLoadFinished() {
- startBrowseIfDvrInitialized();
+ List<ScheduledRecording> scheduledRecordings = mDvrDataManager.getAllScheduledRecordings();
+ onScheduledRecordingAdded(ScheduledRecording.toArray(scheduledRecordings));
+ List<SeriesRecording> seriesRecordings = mDvrDataManager.getSeriesRecordings();
+ onSeriesRecordingAdded(SeriesRecording.toArray(seriesRecordings));
+ if (mDvrDataManager.isInitialized()) {
+ startEntranceTransition();
+ }
mDvrDataManager.removeDvrScheduleLoadFinishedListener(this);
}
@Override
public void onRecordedProgramLoadFinished() {
- startBrowseIfDvrInitialized();
+ for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
+ handleRecordedProgramAdded(recordedProgram, true);
+ }
+ updateRows();
+ if (mDvrDataManager.isInitialized()) {
+ startEntranceTransition();
+ }
mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
}
@@ -281,18 +270,6 @@ public class DvrBrowseFragment extends BrowseFragment implements
}
}
- private void onScheduledRecordingConflictStatusChanged(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- if (needToShowScheduledRecording(schedule)) {
- if (mScheduleAdapter.contains(schedule)) {
- mScheduleAdapter.change(schedule);
- }
- } else {
- mScheduleAdapter.removeWithId(schedule);
- }
- }
- }
-
@Override
public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) {
handleSeriesRecordingsAdded(Arrays.asList(seriesRecordings));
@@ -318,53 +295,44 @@ public class DvrBrowseFragment extends BrowseFragment implements
super.showTitle(flags);
}
- private void prepareUiElements() {
+ private void setupUiElements() {
setBadgeDrawable(getActivity().getDrawable(R.drawable.ic_dvr_badge));
setHeadersState(HEADERS_ENABLED);
setHeadersTransitionOnBackEnabled(false);
setBrandColor(getResources().getColor(R.color.program_guide_side_panel_background, null));
- mRowsAdapter = new ArrayObjectAdapter(new DvrListRowPresenter(getContext()));
- setAdapter(mRowsAdapter);
- prepareEntranceTransition();
}
- private boolean startBrowseIfDvrInitialized() {
- if (mDvrDataManager.isInitialized()) {
- // Setup rows
- mRecentAdapter = new RecordedProgramAdapter(MAX_RECENT_ITEM_COUNT);
- mScheduleAdapter = new ScheduleAdapter(MAX_SCHEDULED_ITEM_COUNT);
- mSeriesAdapter = new SeriesAdapter();
- for (int i = 0; i < mGenreAdapters.length; i++) {
- mGenreAdapters[i] = new RecordedProgramAdapter();
- }
- // Schedule Recordings.
- List<ScheduledRecording> schedules = mDvrDataManager.getAllScheduledRecordings();
- onScheduledRecordingAdded(ScheduledRecording.toArray(schedules));
- mScheduleAdapter.addExtraItem(FullScheduleCardHolder.FULL_SCHEDULE_CARD_HOLDER);
- // Recorded Programs.
- for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
- handleRecordedProgramAdded(recordedProgram, false);
- }
- // Series Recordings. Series recordings should be added after recorded programs, because
- // we build series recordings' latest program information while adding recorded programs.
- List<SeriesRecording> recordings = mDvrDataManager.getSeriesRecordings();
- handleSeriesRecordingsAdded(recordings);
- mRecentRow = new ListRow(new HeaderItem(
- getString(R.string.dvr_main_recent)), mRecentAdapter);
- mRowsAdapter.add(new ListRow(new HeaderItem(
- getString(R.string.dvr_main_scheduled)), mScheduleAdapter));
- mSeriesRow = new ListRow(new HeaderItem(
- getString(R.string.dvr_main_series)), mSeriesAdapter);
- updateRows();
- // Initialize listeners
- mDvrDataManager.addRecordedProgramListener(this);
- mDvrDataManager.addScheduledRecordingListener(this);
- mDvrDataManager.addSeriesRecordingListener(this);
- mDvrScheudleManager.addOnConflictStateChangeListener(mOnConflictStateChangeListener);
- startEntranceTransition();
- return true;
- }
- return false;
+ private void setupAdapters() {
+ mRecentAdapter = new RecordedProgramAdapter(MAX_RECENT_ITEM_COUNT);
+ mScheduleAdapter = new ScheduleAdapter(MAX_SCHEDULED_ITEM_COUNT);
+ mSeriesAdapter = new SeriesAdapter();
+ for (int i = 0; i < mGenreAdapters.length; i++) {
+ mGenreAdapters[i] = new RecordedProgramAdapter();
+ }
+ // Schedule Recordings.
+ List<ScheduledRecording> schedules = mDvrDataManager.getAllScheduledRecordings();
+ onScheduledRecordingAdded(ScheduledRecording.toArray(schedules));
+ mScheduleAdapter.addExtraItem(FullScheduleCardHolder.FULL_SCHEDULE_CARD_HOLDER);
+ // Recorded Programs.
+ for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
+ handleRecordedProgramAdded(recordedProgram, false);
+ }
+ // Series Recordings. Series recordings should be added after recorded programs, because
+ // we build series recordings' latest program information while adding recorded programs.
+ List<SeriesRecording> recordings = mDvrDataManager.getSeriesRecordings();
+ handleSeriesRecordingsAdded(recordings);
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ mRecentRow = new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_recent)), mRecentAdapter);
+ mRowsAdapter.add(new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_scheduled)), mScheduleAdapter));
+ mSeriesRow = new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_series)), mSeriesAdapter);
+ updateRows();
+ mDvrDataManager.addRecordedProgramListener(this);
+ mDvrDataManager.addScheduledRecordingListener(this);
+ mDvrDataManager.addSeriesRecordingListener(this);
+ setAdapter(mRowsAdapter);
}
private void handleRecordedProgramAdded(RecordedProgram recordedProgram,
@@ -621,11 +589,10 @@ public class DvrBrowseFragment extends BrowseFragment implements
@Override
public long getId(Object item) {
- // We takes the inverse number for the ID of recorded programs to make the ID stable.
if (item instanceof SeriesRecording) {
return ((SeriesRecording) item).getId();
} else if (item instanceof RecordedProgram) {
- return -((RecordedProgram) item).getId() - 1;
+ return ((RecordedProgram) item).getId();
} else {
return -1;
}
diff --git a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
index 880dc8ac..837d8ab2 100644
--- a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
@@ -27,7 +27,7 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelRecordConflictFragment;
import java.util.ArrayList;
diff --git a/src/com/android/tv/dvr/ui/DvrConflictFragment.java b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
index 5985f56f..e7be4d0a 100644
--- a/src/com/android/tv/dvr/ui/DvrConflictFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
@@ -34,9 +34,10 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
-import com.android.tv.dvr.recorder.ConflictChecker;
-import com.android.tv.dvr.recorder.ConflictChecker.OnUpcomingConflictChangeListener;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ConflictChecker;
+import com.android.tv.dvr.ConflictChecker.OnUpcomingConflictChangeListener;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.ArrayList;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java b/src/com/android/tv/dvr/ui/DvrDetailsActivity.java
index 30c81e83..806c775c 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrDetailsActivity.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.os.Bundle;
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/DvrDetailsFragment.java
index 4d3698ef..21f9c4b4 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrDetailsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.Context;
import android.content.Intent;
@@ -48,8 +48,8 @@ import com.android.tv.data.BaseProgram;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.ui.playback.DvrPlaybackActivity;
+import com.android.tv.dvr.DvrPlaybackActivity;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.ImageLoader;
import com.android.tv.util.ToastUtils;
diff --git a/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java
new file mode 100644
index 00000000..73ddcdd0
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.dvr.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.text.TextUtils;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+
+import java.util.List;
+
+public class DvrForgetStorageErrorFragment extends DvrGuidedStepFragment {
+ private static final int ACTION_CANCEL = 1;
+ private static final int ACTION_FORGET_STORAGE = 2;
+ private String mInputId;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Bundle args = getArguments();
+ if (args != null) {
+ mInputId = args.getString(DvrHalfSizedDialogFragment.KEY_INPUT_ID);
+ }
+ SoftPreconditions.checkArgument(!TextUtils.isEmpty(mInputId));
+ super.onCreate(savedInstanceState);
+ }
+
+ @NonNull
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getResources().getString(R.string.dvr_error_forget_storage_title);
+ String description = getResources().getString(
+ R.string.dvr_error_forget_storage_description);
+ return new Guidance(title, description, null, null);
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
+ Activity activity = getActivity();
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_CANCEL)
+ .title(getResources().getString(R.string.dvr_action_error_cancel))
+ .build());
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_FORGET_STORAGE)
+ .title(getResources().getString(R.string.dvr_action_error_forget_storage))
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() != ACTION_FORGET_STORAGE) {
+ dismissDialog();
+ return;
+ }
+ DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
+ dvrManager.forgetStorage(mInputId);
+ Activity activity = getActivity();
+ if (activity instanceof DvrDetailsActivity) {
+ // Since we removed everything, just finish the activity.
+ activity.finish();
+ } else {
+ dismissDialog();
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
index 433588da..d26e6836 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
@@ -16,12 +16,10 @@
package com.android.tv.dvr.ui;
-import android.app.Activity;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
@@ -31,26 +29,11 @@ import android.view.ViewGroup;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dialog.HalfSizedDialogFragment.OnActionClickListener;
import com.android.tv.dialog.SafeDismissDialogFragment;
import com.android.tv.dvr.DvrManager;
-
-import java.util.List;
+import com.android.tv.dvr.ui.HalfSizedDialogFragment.OnActionClickListener;
public class DvrGuidedStepFragment extends GuidedStepFragment {
- /**
- * Action ID for "recording/scheduling the program anyway".
- */
- public static final int ACTION_RECORD_ANYWAY = 1;
- /**
- * Action ID for "deleting existed recordings".
- */
- public static final int ACTION_DELETE_RECORDINGS = 2;
- /**
- * Action ID for "cancelling current recording request".
- */
- public static final int ACTION_CANCEL_RECORDING = 3;
-
private DvrManager mDvrManager;
private OnActionClickListener mOnActionClickListener;
@@ -103,35 +86,4 @@ public class DvrGuidedStepFragment extends GuidedStepFragment {
protected void setOnActionClickListener(OnActionClickListener listener) {
mOnActionClickListener = listener;
}
-
- /**
- * The inner guided step fragment for
- * {@link com.android.tv.dvr.ui.DvrHalfSizedDialogFragment
- * .DvrNoFreeSpaceErrorDialogFragment}.
- */
- public static class DvrNoFreeSpaceErrorFragment
- extends DvrGuidedStepFragment {
- @Override
- public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
- return new GuidanceStylist.Guidance(getString(R.string.dvr_error_no_free_space_title),
- getString(R.string.dvr_error_no_free_space_description), null, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- Activity activity = getActivity();
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_RECORD_ANYWAY)
- .title(R.string.dvr_action_record_anyway)
- .build());
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_DELETE_RECORDINGS)
- .title(R.string.dvr_action_delete_recordings)
- .build());
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_CANCEL_RECORDING)
- .title(R.string.dvr_action_record_cancel)
- .build());
- }
- }
} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
index 9054dd03..2b132db8 100644
--- a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
@@ -29,7 +29,6 @@ import android.view.ViewGroup;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.dvr.DvrStorageStatusManager;
-import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelWatchConflictFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
import com.android.tv.guide.ProgramGuide;
@@ -167,17 +166,6 @@ public class DvrHalfSizedDialogFragment extends HalfSizedDialogFragment {
}
/**
- * A dialog fragment to show error message when there is no enough free space to record.
- */
- public static class DvrNoFreeSpaceErrorDialogFragment
- extends DvrGuidedStepDialogFragment {
- @Override
- protected DvrGuidedStepFragment onCreateGuidedStepFragment() {
- return new DvrGuidedStepFragment.DvrNoFreeSpaceErrorFragment();
- }
- }
-
- /**
* A dialog fragment to show error message when the current storage is too small to
* support DVR
*/
diff --git a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
index 3c5df1a6..3b1dbfa0 100644
--- a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
@@ -17,7 +17,6 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
@@ -25,67 +24,19 @@ import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
+import com.android.tv.dvr.DvrDataManager;
-import java.util.ArrayList;
import java.util.List;
public class DvrInsufficientSpaceErrorFragment extends DvrGuidedStepFragment {
- /**
- * Key for the failed scheduled recordings information.
- */
- public static final String FAILED_SCHEDULED_RECORDING_INFOS =
- "failed_scheduled_recording_infos";
-
- private static final String TAG = "DvrInsufficientSpaceErrorFragment";
-
- private static final int ACTION_VIEW_RECENT_RECORDINGS = 1;
-
- private ArrayList<String> mFailedScheduledRecordingInfos;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- Bundle args = getArguments();
- if (args != null) {
- mFailedScheduledRecordingInfos =
- args.getStringArrayList(FAILED_SCHEDULED_RECORDING_INFOS);
- }
- SoftPreconditions.checkState(
- mFailedScheduledRecordingInfos != null && !mFailedScheduledRecordingInfos.isEmpty(),
- TAG, "failed scheduled recording is null");
- }
+ private static final int ACTION_DONE = 1;
+ private static final int ACTION_OPEN_DVR = 2;
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title;
- String description;
- int failedScheduledRecordingSize = mFailedScheduledRecordingInfos.size();
- if (failedScheduledRecordingSize == 1) {
- title = getString(
- R.string.dvr_error_insufficient_space_title_one_recording,
- mFailedScheduledRecordingInfos.get(0));
- description = getString(
- R.string.dvr_error_insufficient_space_description_one_recording,
- mFailedScheduledRecordingInfos.get(0));
- } else if (failedScheduledRecordingSize == 2) {
- title = getString(
- R.string.dvr_error_insufficient_space_title_two_recordings,
- mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1));
- description = getString(
- R.string.dvr_error_insufficient_space_description_two_recordings,
- mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1));
- } else {
- title = getString(
- R.string.dvr_error_insufficient_space_title_three_or_more_recordings,
- mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1),
- mFailedScheduledRecordingInfos.get(2));
- description = getString(
- R.string.dvr_error_insufficient_space_description_three_or_more_recordings,
- mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1),
- mFailedScheduledRecordingInfos.get(2));
- }
+ String title = getResources().getString(R.string.dvr_error_insufficient_space_title);
+ String description = getResources()
+ .getString(R.string.dvr_error_insufficient_space_description);
return new Guidance(title, description, null, null);
}
@@ -93,21 +44,26 @@ public class DvrInsufficientSpaceErrorFragment extends DvrGuidedStepFragment {
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
Activity activity = getActivity();
actions.add(new GuidedAction.Builder(activity)
- .clickAction(GuidedAction.ACTION_ID_OK)
+ .id(ACTION_DONE)
+ .title(getResources().getString(R.string.dvr_action_error_done))
.build());
- if (TvApplication.getSingletons(getContext()).getDvrManager().hasValidItems()) {
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_VIEW_RECENT_RECORDINGS)
- .title(getResources().getString(
- R.string.dvr_error_insufficient_space_action_view_recent_recordings))
- .build());
+ DvrDataManager dvrDataManager = TvApplication.getSingletons(getContext())
+ .getDvrDataManager();
+ if (!(dvrDataManager.getRecordedPrograms().isEmpty()
+ && dvrDataManager.getStartedRecordings().isEmpty()
+ && dvrDataManager.getNonStartedScheduledRecordings().isEmpty()
+ && dvrDataManager.getSeriesRecordings().isEmpty())) {
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_OPEN_DVR)
+ .title(getResources().getString(R.string.dvr_action_error_open_dvr))
+ .build());
}
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() == ACTION_VIEW_RECENT_RECORDINGS) {
- Intent intent = new Intent(getActivity(), DvrBrowseActivity.class);
+ if (action.getId() == ACTION_OPEN_DVR) {
+ Intent intent = new Intent(getActivity(), DvrActivity.class);
getActivity().startActivity(intent);
}
dismissDialog();
diff --git a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java b/src/com/android/tv/dvr/ui/DvrItemPresenter.java
index 317b6af3..339e5d2f 100644
--- a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
+++ b/src/com/android/tv/dvr/ui/DvrItemPresenter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.support.annotation.CallSuper;
@@ -22,17 +22,16 @@ import android.support.v17.leanback.widget.Presenter;
import android.view.View;
import android.view.View.OnClickListener;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.DvrUiHelper;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
/**
* An abstract class to present DVR items in {@link RecordingCardView}, which is mainly used in
- * {@link DvrBrowseFragment}. DVR items might include:
- * {@link com.android.tv.dvr.data.ScheduledRecording},
- * {@link com.android.tv.dvr.data.RecordedProgram}, and
- * {@link com.android.tv.dvr.data.SeriesRecording}.
+ * {@link DvrBrowseFragment}. DVR items might include: {@link ScheduledRecording},
+ * {@link RecordedProgram}, and {@link SeriesRecording}.
*/
public abstract class DvrItemPresenter extends Presenter {
private final Set<ViewHolder> mBoundViewHolders = new HashSet<>();
@@ -50,8 +49,6 @@ public abstract class DvrItemPresenter extends Presenter {
@CallSuper
public void onUnbindViewHolder(ViewHolder viewHolder) {
mBoundViewHolders.remove(viewHolder);
- viewHolder.view.setTag(null);
- viewHolder.view.setOnClickListener(null);
}
/**
diff --git a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
index 8dc9eb4e..2e2c2849 100644
--- a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
@@ -17,27 +17,29 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
import android.os.Bundle;
-import android.provider.Settings;
+import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
-import android.util.Log;
+import android.text.TextUtils;
import com.android.tv.R;
-import com.android.tv.dvr.ui.browse.DvrDetailsActivity;
+import com.android.tv.common.SoftPreconditions;
import java.util.List;
public class DvrMissingStorageErrorFragment extends DvrGuidedStepFragment {
- private static String TAG = "DvrMissingStorageErrorFragment";
-
- private static final int ACTION_OK = 1;
- private static final int ACTION_OPEN_STORAGE_SETTINGS = 2;
+ private static final int ACTION_CANCEL = 1;
+ private static final int ACTION_FORGET_STORAGE = 2;
+ private String mInputId;
@Override
public void onCreate(Bundle savedInstanceState) {
+ Bundle args = getArguments();
+ if (args != null) {
+ mInputId = args.getString(DvrHalfSizedDialogFragment.KEY_INPUT_ID);
+ }
+ SoftPreconditions.checkArgument(!TextUtils.isEmpty(mInputId));
super.onCreate(savedInstanceState);
}
@@ -53,31 +55,25 @@ public class DvrMissingStorageErrorFragment extends DvrGuidedStepFragment {
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
Activity activity = getActivity();
actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_OK)
- .title(android.R.string.ok)
+ .id(ACTION_CANCEL)
+ .title(getResources().getString(R.string.dvr_action_error_cancel))
.build());
actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_OPEN_STORAGE_SETTINGS)
- .title(getResources().getString(R.string.dvr_action_error_storage_settings))
+ .id(ACTION_FORGET_STORAGE)
+ .title(getResources().getString(R.string.dvr_action_error_forget_storage))
.build());
}
@Override
public void onGuidedActionClicked(GuidedAction action) {
- Activity activity = getActivity();
- if (activity instanceof DvrDetailsActivity) {
- activity.finish();
- } else {
- dismissDialog();
- }
- if (action.getId() != ACTION_OPEN_STORAGE_SETTINGS) {
+ if (action.getId() == ACTION_FORGET_STORAGE) {
+ DvrForgetStorageErrorFragment fragment = new DvrForgetStorageErrorFragment();
+ Bundle args = new Bundle();
+ args.putString(DvrHalfSizedDialogFragment.KEY_INPUT_ID, mInputId);
+ fragment.setArguments(args);
+ GuidedStepFragment.add(getFragmentManager(), fragment, R.id.halfsized_dialog_host);
return;
}
- final Intent intent = new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
- try {
- getContext().startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "Can't start internal storage settings activity", e);
- }
+ dismissDialog();
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java b/src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java
index 4bd121b1..8c4c856c 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java
+++ b/src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.playback;
+package com.android.tv.dvr.ui;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -25,25 +26,22 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import com.android.tv.R;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.ui.browse.RecordedProgramPresenter;
-import com.android.tv.dvr.ui.browse.RecordingCardView;
+import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.DvrPlaybackActivity;
import com.android.tv.util.Utils;
/**
* This class is used to generate Views and bind Objects for related recordings in DVR playback.
*/
-class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
+public class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
private static final String TAG = "DvrPlaybackCardPresenter";
private static final boolean DEBUG = false;
private final int mRelatedRecordingCardWidth;
private final int mRelatedRecordingCardHeight;
- private final DvrPlaybackOverlayFragment mFragment;
- DvrPlaybackCardPresenter(Context context, DvrPlaybackOverlayFragment fragment) {
+ DvrPlaybackCardPresenter(Context context) {
super(context);
- mFragment = fragment;
mRelatedRecordingCardWidth =
context.getResources().getDimensionPixelSize(R.dimen.dvr_related_recordings_width);
mRelatedRecordingCardHeight =
@@ -52,8 +50,9 @@ class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ Resources res = parent.getResources();
RecordingCardView view = new RecordingCardView(
- getContext(), mRelatedRecordingCardWidth, mRelatedRecordingCardHeight, true);
+ getContext(), mRelatedRecordingCardWidth, mRelatedRecordingCardHeight);
return new ViewHolder(view);
}
@@ -62,10 +61,6 @@ class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
return new OnClickListener() {
@Override
public void onClick(View v) {
- // Disable fading of overlay fragment to prevent the layout blinking while updating
- // new playback states and info. The fading enabled status will be reset during
- // playback state changing, in DvrPlaybackControlHelper.onStateChanged().
- mFragment.setFadingEnabled(false);
long programId = ((RecordedProgram) v.getTag()).getId();
if (DEBUG) Log.d(TAG, "Play Related Recording:" + programId);
Intent intent = new Intent(getContext(), DvrPlaybackActivity.class);
@@ -74,4 +69,14 @@ class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
}
};
}
+
+ @Override
+ protected String getDescription(RecordedProgram program) {
+ String description = program.getDescription();
+ if (TextUtils.isEmpty(description)) {
+ description =
+ getContext().getResources().getString(R.string.dvr_msg_no_program_description);
+ }
+ return description;
+ }
} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java b/src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java
index 4658a328..0bc4ecb1 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
+++ b/src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java
@@ -14,26 +14,19 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.playback;
+package com.android.tv.dvr.ui;
import android.app.Activity;
-import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaController.TransportControls;
import android.media.session.PlaybackState;
-import android.media.tv.TvTrackInfo;
-import android.os.Bundle;
import android.support.v17.leanback.app.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.ControlButtonPresenterSelector;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
-import android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction;
import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
import android.support.v17.leanback.widget.RowPresenter;
import android.text.TextUtils;
@@ -44,18 +37,19 @@ import android.view.View;
import com.android.tv.R;
import com.android.tv.util.TimeShiftUtils;
-import java.util.ArrayList;
-
/**
* A helper class to assist {@link DvrPlaybackOverlayFragment} to manage its controls row and
* send command to the media controller. It also helps to update playback states displayed in the
* fragment according to information the media session provides.
*/
-class DvrPlaybackControlHelper extends PlaybackControlGlue {
+public class DvrPlaybackControlHelper extends PlaybackControlGlue {
private static final String TAG = "DvrPlaybackControlHelper";
private static final boolean DEBUG = false;
- private static final int AUDIO_ACTION_ID = 1001;
+ /**
+ * Indicates the ID of the media under playback is unknown.
+ */
+ public static int UNKNOWN_MEDIA_ID = -1;
private int mPlaybackState = PlaybackState.STATE_NONE;
private int mPlaybackSpeedLevel;
@@ -66,9 +60,6 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
private final MediaController.Callback mMediaControllerCallback = new MediaControllerCallback();
private final TransportControls mTransportControls;
private final int mExtraPaddingTopForNoDescription;
- private final ArrayObjectAdapter mSecondaryActionsAdapter;
- private final MultiAction mClosedCaptioningAction;
- private final MultiAction mMultiAudioAction;
public DvrPlaybackControlHelper(Activity activity, DvrPlaybackOverlayFragment overlayFragment) {
super(activity, overlayFragment, new int[TimeShiftUtils.MAX_SPEED_LEVEL + 1]);
@@ -77,15 +68,11 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
mTransportControls = mMediaController.getTransportControls();
mExtraPaddingTopForNoDescription = activity.getResources()
.getDimensionPixelOffset(R.dimen.dvr_playback_controls_extra_padding_top);
- mSecondaryActionsAdapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
- mClosedCaptioningAction = new ClosedCaptioningAction(activity);
- mMultiAudioAction = new MultiAudioAction(activity);
}
@Override
public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
- controlsRow.setSecondaryActionsAdapter(mSecondaryActionsAdapter);
setControlsRow(controlsRow);
AbstractDetailsDescriptionPresenter detailsPresenter =
new AbstractDetailsDescriptionPresenter() {
@@ -129,21 +116,7 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
@Override
public void onActionClicked(Action action) {
if (mReadyToControl) {
- int trackType;
- if (action.getId() == mClosedCaptioningAction.getId()) {
- trackType = TvTrackInfo.TYPE_SUBTITLE;
- } else if (action.getId() == AUDIO_ACTION_ID) {
- trackType = TvTrackInfo.TYPE_AUDIO;
- } else {
- DvrPlaybackControlHelper.super.onActionClicked(action);
- return;
- }
- ArrayList<TvTrackInfo> trackInfos =
- ((DvrPlaybackOverlayFragment) getFragment()).getTracks(trackType);
- if (!trackInfos.isEmpty()) {
- showSideFragment(trackInfos, ((DvrPlaybackOverlayFragment)
- getFragment()).getSelectedTrackId(trackType));
- }
+ DvrPlaybackControlHelper.super.onActionClicked(action);
}
}
});
@@ -185,10 +158,10 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
/**
* Returns the ID of the media under playback.
*/
- public String getMediaId() {
+ public long getMediaId() {
MediaMetadata mediaMetadata = mMediaController.getMetadata();
- return mediaMetadata == null ? null
- : mediaMetadata.getString(MediaMetadata.METADATA_KEY_MEDIA_ID);
+ return mediaMetadata == null ? UNKNOWN_MEDIA_ID
+ : mediaMetadata.getLong(MediaMetadata.METADATA_KEY_MEDIA_ID);
}
@Override
@@ -244,37 +217,6 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
mMediaController.unregisterCallback(mMediaControllerCallback);
}
- /**
- * Update the secondary controls row.
- * @param hasClosedCaption {@code true} to show the closed caption selection button,
- * {@code false} to hide it.
- * @param hasMultiAudio {@code true} to show the audio track selection button,
- * {@code false} to hide it.
- */
- public void updateSecondaryRow(boolean hasClosedCaption, boolean hasMultiAudio) {
- if (hasClosedCaption) {
- if (mSecondaryActionsAdapter.indexOf(mClosedCaptioningAction) < 0) {
- mSecondaryActionsAdapter.add(0, mClosedCaptioningAction);
- }
- } else {
- mSecondaryActionsAdapter.remove(mClosedCaptioningAction);
- }
- if (hasMultiAudio) {
- if (mSecondaryActionsAdapter.indexOf(mMultiAudioAction) < 0) {
- mSecondaryActionsAdapter.add(mMultiAudioAction);
- }
- } else {
- mSecondaryActionsAdapter.remove(mMultiAudioAction);
- }
- }
-
- /**
- * Returns if the secondary controls row has any buttons and thus should be shown.
- */
- public boolean hasSecondaryRow() {
- return mSecondaryActionsAdapter.size() != 0;
- }
-
@Override
protected void startPlayback(int speedId) {
if (getCurrentSpeedId() == speedId) {
@@ -309,14 +251,6 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
// Do nothing.
}
- /**
- * Notifies closed caption being enabled/disabled to update related UI.
- */
- void onSubtitleTrackStateChanged(boolean enabled) {
- mClosedCaptioningAction.setIndex(enabled ?
- ClosedCaptioningAction.ON : ClosedCaptioningAction.OFF);
- }
-
private void onStateChanged(int state, long positionMs, int speedLevel) {
if (DEBUG) Log.d(TAG, "onStateChanged");
getControlsRow().setCurrentTime((int) positionMs);
@@ -363,19 +297,6 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
onStateChanged();
}
- private void showSideFragment(ArrayList<TvTrackInfo> trackInfos, String selectedTrackId) {
- Bundle args = new Bundle();
- args.putParcelableArrayList(DvrPlaybackSideFragment.TRACK_INFOS, trackInfos);
- args.putString(DvrPlaybackSideFragment.SELECTED_TRACK_ID, selectedTrackId);
- DvrPlaybackSideFragment sideFragment = new DvrPlaybackSideFragment();
- sideFragment.setArguments(args);
- getFragment().getFragmentManager().beginTransaction()
- .hide(getFragment())
- .replace(R.id.dvr_playback_side_fragment, sideFragment)
- .addToBackStack(null)
- .commit();
- }
-
private class MediaControllerCallback extends MediaController.Callback {
@Override
public void onPlaybackStateChanged(PlaybackState state) {
@@ -389,11 +310,4 @@ class DvrPlaybackControlHelper extends PlaybackControlGlue {
((DvrPlaybackOverlayFragment) getFragment()).onMediaControllerUpdated();
}
}
-
- private static class MultiAudioAction extends MultiAction {
- MultiAudioAction(Context context) {
- super(AUDIO_ACTION_ID);
- setDrawables(new Drawable[]{context.getDrawable(R.drawable.ic_tvoption_multi_track)});
- }
- }
} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java b/src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java
index ff907182..51ec93b8 100644
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java
@@ -14,14 +14,13 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.playback;
+package com.android.tv.dvr.ui;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.media.tv.TvContentRating;
-import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.media.session.PlaybackState;
import android.media.tv.TvInputManager;
@@ -31,6 +30,7 @@ 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.ListRowPresenter;
import android.support.v17.leanback.widget.PlaybackControlsRow;
import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
import android.support.v17.leanback.widget.SinglePresenterSelector;
@@ -38,25 +38,20 @@ import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
+import android.text.TextUtils;
import android.util.Log;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.BaseProgram;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.ui.SortedArrayAdapter;
-import com.android.tv.dvr.ui.browse.DvrListRowPresenter;
+import com.android.tv.dvr.DvrPlayer;
+import com.android.tv.dvr.DvrPlaybackMediaSessionHelper;
import com.android.tv.parental.ContentRatingsManager;
-import com.android.tv.util.TvSettings;
-import com.android.tv.util.TvTrackInfoUtils;
import com.android.tv.util.Utils;
-import java.util.List;
-import java.util.ArrayList;
-
public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
// TODO: Handles audio focus. Deals with block and ratings.
private static final String TAG = "DvrPlaybackOverlayFragment";
@@ -67,7 +62,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
// mProgram is only used to store program from intent. Don't use it elsewhere.
private RecordedProgram mProgram;
- private DvrPlayer mDvrPlayer;
private DvrPlaybackMediaSessionHelper mMediaSessionHelper;
private DvrPlaybackControlHelper mPlaybackControlHelper;
private ArrayObjectAdapter mRowsAdapter;
@@ -78,30 +72,19 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
private TvView mTvView;
private View mBlockScreenView;
private ListRow mRelatedRecordingsRow;
- private int mPaddingWithoutRelatedRow;
- private int mPaddingWithoutSecondaryRow;
+ private int mExtraPaddingNoRelatedRow;
private int mWindowWidth;
private int mWindowHeight;
private float mAppliedAspectRatio;
private float mWindowAspectRatio;
private boolean mPinChecked;
- private DvrPlayer.OnTrackSelectedListener mOnSubtitleTrackSelectedListener =
- new DvrPlayer.OnTrackSelectedListener() {
- @Override
- public void onTrackSelected(String selectedTrackId) {
- mPlaybackControlHelper.onSubtitleTrackStateChanged(selectedTrackId != null);
- mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
- }
- };
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
- mPaddingWithoutRelatedRow = getActivity().getResources()
- .getDimensionPixelOffset(R.dimen.dvr_playback_overlay_padding_top_no_related_row);
- mPaddingWithoutSecondaryRow = getActivity().getResources()
- .getDimensionPixelOffset(R.dimen.dvr_playback_overlay_padding_top_no_secondary_row);
+ mExtraPaddingNoRelatedRow = getActivity().getResources()
+ .getDimensionPixelOffset(R.dimen.dvr_playback_fragment_extra_padding_top);
mDvrDataManager = TvApplication.getSingletons(getActivity()).getDvrDataManager();
mContentRatingsManager = TvApplication.getSingletons(getContext())
.getTvInputManagerHelper().getContentRatingsManager();
@@ -127,31 +110,13 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
super.onActivityCreated(savedInstanceState);
mTvView = (TvView) getActivity().findViewById(R.id.dvr_tv_view);
mBlockScreenView = getActivity().findViewById(R.id.block_screen);
- mDvrPlayer = new DvrPlayer(mTvView);
mMediaSessionHelper = new DvrPlaybackMediaSessionHelper(
- getActivity(), MEDIA_SESSION_TAG, mDvrPlayer, this);
+ getActivity(), MEDIA_SESSION_TAG, new DvrPlayer(mTvView), this);
mPlaybackControlHelper = new DvrPlaybackControlHelper(getActivity(), this);
setUpRows();
- mDvrPlayer.setOnTracksAvailabilityChangedListener(
- new DvrPlayer.OnTracksAvailabilityChangedListener() {
- @Override
- public void onTracksAvailabilityChanged(boolean hasClosedCaption,
- boolean hasMultiAudio) {
- mPlaybackControlHelper.updateSecondaryRow(hasClosedCaption, hasMultiAudio);
- if (hasClosedCaption) {
- mDvrPlayer.setOnTrackSelectedListener(TvTrackInfo.TYPE_SUBTITLE,
- mOnSubtitleTrackSelectedListener);
- selectBestMatchedTrack(TvTrackInfo.TYPE_SUBTITLE);
- } else {
- mDvrPlayer.setOnTrackSelectedListener(TvTrackInfo.TYPE_SUBTITLE, null);
- }
- if (hasMultiAudio) {
- selectBestMatchedTrack(TvTrackInfo.TYPE_AUDIO);
- }
- onMediaControllerUpdated();
- }
- });
- mDvrPlayer.setOnAspectRatioChangedListener(new DvrPlayer.OnAspectRatioChangedListener() {
+ preparePlayback(getActivity().getIntent());
+ DvrPlayer dvrPlayer = mMediaSessionHelper.getDvrPlayer();
+ dvrPlayer.setAspectRatioChangedListener(new DvrPlayer.AspectRatioChangedListener() {
@Override
public void onAspectRatioChanged(float videoAspectRatio) {
updateAspectRatio(videoAspectRatio);
@@ -159,7 +124,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
});
mPinChecked = getActivity().getIntent()
.getBooleanExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED, false);
- mDvrPlayer.setOnContentBlockedListener(new DvrPlayer.OnContentBlockedListener() {
+ dvrPlayer.setContentBlockedListener(new DvrPlayer.ContentBlockedListener() {
@Override
public void onContentBlocked(TvContentRating rating) {
if (mPinChecked) {
@@ -184,7 +149,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
.show(getActivity().getFragmentManager(), PinDialogFragment.DIALOG_TAG);
}
});
- preparePlayback(getActivity().getIntent());
}
@Override
@@ -236,9 +200,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
updateAspectRatio(mAppliedAspectRatio);
}
- /**
- * Returns next recorded episode in the same series as now playing program.
- */
public RecordedProgram getNextEpisode(RecordedProgram program) {
int position = mRelatedRecordingsRowAdapter.findInsertPosition(program);
if (position == mRelatedRecordingsRowAdapter.size()) {
@@ -248,92 +209,16 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
}
}
- /**
- * Returns the tracks of the give type of the current playback.
-
- * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
- * or {@link TvTrackInfo#TYPE_AUDIO}. Or returns {@code null}.
- */
- public ArrayList<TvTrackInfo> getTracks(int trackType) {
- if (trackType == TvTrackInfo.TYPE_AUDIO) {
- return mDvrPlayer.getAudioTracks();
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- return mDvrPlayer.getSubtitleTracks();
- }
- return null;
- }
-
- /**
- * Returns the ID of the selected track of the given type.
- */
- public String getSelectedTrackId(int trackType) {
- return mDvrPlayer.getSelectedTrackId(trackType);
- }
-
- /**
- * Returns the language setting of the given track type.
-
- * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
- * or {@link TvTrackInfo#TYPE_AUDIO}.
- * @return {@code null} if no language has been set for the given track type.
- */
- TvTrackInfo getTrackSetting(int trackType) {
- return TvSettings.getDvrPlaybackTrackSettings(getContext(), trackType);
- }
-
- /**
- * Selects the given audio or subtitle track for DVR playback.
- * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
- * or {@link TvTrackInfo#TYPE_AUDIO}.
- * @param selectedTrack {@code null} to disable the audio or subtitle track according to
- * trackType.
- */
- void selectTrack(int trackType, TvTrackInfo selectedTrack) {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.selectTrack(trackType, selectedTrack);
- }
- }
-
- /**
- * Notifies the content of controls row or related recordings row is changed and the UI should
- * be updated according to the change.
- */
void onMediaControllerUpdated() {
- updateVerticalPosition();
- mRowsAdapter.notifyArrayItemRangeChanged(0, 2);
- }
-
- private void selectBestMatchedTrack(int trackType) {
- TvTrackInfo selectedTrack = getTrackSetting(trackType);
- if (selectedTrack != null) {
- TvTrackInfo bestMatchedTrack = TvTrackInfoUtils.getBestTrackInfo(getTracks(trackType),
- selectedTrack.getId(), selectedTrack.getLanguage(),
- trackType == TvTrackInfo.TYPE_AUDIO ? selectedTrack.getAudioChannelCount() : 0);
- if (bestMatchedTrack != null && (trackType == TvTrackInfo.TYPE_AUDIO || Utils
- .isEqualLanguage(bestMatchedTrack.getLanguage(),
- selectedTrack.getLanguage()))) {
- selectTrack(trackType, bestMatchedTrack);
- return;
- }
- }
- if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- // Disables closed captioning if there's no matched language.
- selectTrack(TvTrackInfo.TYPE_SUBTITLE, null);
- }
+ mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
}
private void updateAspectRatio(float videoAspectRatio) {
- if (videoAspectRatio <= 0) {
- // We don't have video's width or height information, use window's aspect ratio.
- videoAspectRatio = mWindowAspectRatio;
- }
if (Math.abs(mAppliedAspectRatio - videoAspectRatio) < DISPLAY_ASPECT_RATIO_EPSILON) {
// No need to change
return;
}
- if (Math.abs(mWindowAspectRatio - videoAspectRatio) < DISPLAY_ASPECT_RATIO_EPSILON) {
- ((ViewGroup) mTvView.getParent()).setPadding(0, 0, 0, 0);
- } else if (videoAspectRatio < mWindowAspectRatio) {
+ if (videoAspectRatio < mWindowAspectRatio) {
int newPadding = (mWindowWidth - Math.round(mWindowHeight * videoAspectRatio)) / 2;
((ViewGroup) mTvView.getParent()).setPadding(newPadding, 0, newPadding, 0);
} else {
@@ -345,7 +230,6 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
private void preparePlayback(Intent intent) {
mMediaSessionHelper.setupPlayback(mProgram, getSeekTimeFromIntent(intent));
- mPlaybackControlHelper.updateSecondaryRow(false, false);
getActivity().getMediaController().getTransportControls().prepare();
updateRelatedRecordingsRow();
}
@@ -355,35 +239,24 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
mRelatedRecordingsRowAdapter.clear();
long programId = mProgram.getId();
String seriesId = mProgram.getSeriesId();
- SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
- if (seriesRecording != null) {
+ if (!TextUtils.isEmpty(seriesId)) {
if (DEBUG) Log.d(TAG, "Update related recordings with:" + seriesId);
- List<RecordedProgram> relatedPrograms =
- mDvrDataManager.getRecordedPrograms(seriesRecording.getId());
- for (RecordedProgram program : relatedPrograms) {
- if (programId != program.getId()) {
+ for (RecordedProgram program : mDvrDataManager.getRecordedPrograms()) {
+ if (seriesId.equals(program.getSeriesId()) && programId != program.getId()) {
mRelatedRecordingsRowAdapter.add(program);
}
}
}
+ View view = getView();
if (mRelatedRecordingsRowAdapter.size() == 0) {
mRowsAdapter.remove(mRelatedRecordingsRow);
+ view.setPadding(view.getPaddingLeft(), mExtraPaddingNoRelatedRow,
+ view.getPaddingRight(), view.getPaddingBottom());
} else if (wasEmpty){
mRowsAdapter.add(mRelatedRecordingsRow);
+ view.setPadding(view.getPaddingLeft(), 0,
+ view.getPaddingRight(), view.getPaddingBottom());
}
- onMediaControllerUpdated();
- }
-
- private void updateVerticalPosition() {
- int verticalPadding = 0;
- verticalPadding +=
- mRelatedRecordingsRowAdapter.size() == 0 ? mPaddingWithoutRelatedRow : 0;
- verticalPadding +=
- mPlaybackControlHelper.hasSecondaryRow() ? 0 : mPaddingWithoutSecondaryRow;
- if (DEBUG) Log.d(TAG, "New controls padding: " + verticalPadding);
- View view = getView();
- view.setPadding(view.getPaddingLeft(), verticalPadding,
- view.getPaddingRight(), view.getPaddingBottom());
}
private void setUpRows() {
@@ -392,7 +265,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
ClassPresenterSelector selector = new ClassPresenterSelector();
selector.addClassPresenter(PlaybackControlsRow.class, controlsRowPresenter);
- selector.addClassPresenter(ListRow.class, new DvrListRowPresenter(getContext()));
+ selector.addClassPresenter(ListRow.class, new ListRowPresenter());
mRowsAdapter = new ArrayObjectAdapter(selector);
mRowsAdapter.add(mPlaybackControlHelper.getControlsRow());
@@ -401,7 +274,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
}
private ListRow getRelatedRecordingsRow() {
- mRelatedRecordingCardPresenter = new DvrPlaybackCardPresenter(getActivity(), this);
+ mRelatedRecordingCardPresenter = new DvrPlaybackCardPresenter(getActivity());
mRelatedRecordingsRowAdapter = new RelatedRecordingsAdapter(mRelatedRecordingCardPresenter);
HeaderItem header = new HeaderItem(0,
getActivity().getString(R.string.dvr_playback_related_recordings));
@@ -424,7 +297,7 @@ public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
}
@Override
- public long getId(BaseProgram item) {
+ long getId(BaseProgram item) {
return item.getId();
}
}
diff --git a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
index d6008315..da6d1637 100644
--- a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
@@ -32,8 +32,9 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
import com.android.tv.util.Utils;
@@ -47,26 +48,18 @@ import java.util.List;
*/
@TargetApi(Build.VERSION_CODES.N)
public class DvrScheduleFragment extends DvrGuidedStepFragment {
- /**
- * Key for the whether to add the current program to series.
- * Type: boolean
- */
- public static final String KEY_ADD_CURRENT_PROGRAM_TO_SERIES = "add_current_program_to_series";
-
private static final String TAG = "DvrScheduleFragment";
private static final int ACTION_RECORD_EPISODE = 1;
private static final int ACTION_RECORD_SERIES = 2;
private Program mProgram;
- private boolean mAddCurrentProgramToSeries;
@Override
public void onCreate(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
mProgram = args.getParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM);
- mAddCurrentProgramToSeries = args.getBoolean(KEY_ADD_CURRENT_PROGRAM_TO_SERIES, false);
}
DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
SoftPreconditions.checkArgument(mProgram != null && mProgram.isEpisodic(), TAG,
@@ -146,10 +139,8 @@ public class DvrScheduleFragment extends DvrGuidedStepFragment {
.build();
getDvrManager().updateSeriesRecording(seriesRecording);
}
-
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- seriesRecording.getId(), null, true, true, true,
- mAddCurrentProgramToSeries ? mProgram : null);
+ seriesRecording.getId(), null, true, true, true);
dismissDialog();
}
}
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java b/src/com/android/tv/dvr/ui/DvrSchedulesActivity.java
index a0410bb3..f6e6ac26 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSchedulesActivity.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.list;
+package com.android.tv.dvr.ui;
import android.app.Activity;
import android.app.ProgressDialog;
@@ -24,13 +24,15 @@ import android.support.annotation.IntDef;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.Program;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
-import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-import com.android.tv.dvr.ui.BigArguments;
+import com.android.tv.dvr.EpisodicProgramLoadTask;
+import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.SeriesRecordingScheduler;
+import com.android.tv.dvr.ui.list.DvrSchedulesFragment;
+import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -70,47 +72,33 @@ public class DvrSchedulesActivity extends Activity {
getFragmentManager().beginTransaction().add(
R.id.fragment_container, schedulesFragment).commit();
} else if (scheduleType == TYPE_SERIES_SCHEDULE) {
- if (BigArguments.getArgument(DvrSeriesSchedulesFragment
- .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS) != null) {
- // The programs will be passed to the DvrSeriesSchedulesFragment, so don't need
- // to reset the BigArguments.
- showDvrSeriesSchedulesFragment(getIntent().getExtras());
- } else {
- final ProgressDialog dialog = ProgressDialog.show(this, null, getString(
- R.string.dvr_series_progress_message_reading_programs));
- SeriesRecording seriesRecording = getIntent().getExtras()
- .getParcelable(DvrSeriesSchedulesFragment
- .SERIES_SCHEDULES_KEY_SERIES_RECORDING);
- // To get programs faster, hold the update of the series schedules.
- SeriesRecordingScheduler.getInstance(this).pauseUpdate();
- new EpisodicProgramLoadTask(this, Collections.singletonList(seriesRecording)) {
- @Override
- protected void onPostExecute(List<Program> programs) {
- SeriesRecordingScheduler.getInstance(DvrSchedulesActivity.this)
- .resumeUpdate();
- dialog.dismiss();
- Bundle args = getIntent().getExtras();
- BigArguments.reset();
- BigArguments.setArgument(
- DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_PROGRAMS,
- programs == null ? Collections.EMPTY_LIST : programs);
- showDvrSeriesSchedulesFragment(args);
- }
- }.setLoadCurrentProgram(true)
- .setLoadDisallowedProgram(true)
- .setLoadScheduledEpisode(true)
- .setIgnoreChannelOption(true)
- .execute();
- }
+ final ProgressDialog dialog = ProgressDialog.show(this, null, getString(
+ R.string.dvr_series_schedules_progress_message_reading_programs));
+ SeriesRecording seriesRecording = getIntent().getExtras()
+ .getParcelable(DvrSeriesSchedulesFragment
+ .SERIES_SCHEDULES_KEY_SERIES_RECORDING);
+ // To get programs faster, hold the update of the series schedules.
+ SeriesRecordingScheduler.getInstance(this).pauseUpdate();
+ new EpisodicProgramLoadTask(this, Collections.singletonList(seriesRecording)) {
+ @Override
+ protected void onPostExecute(List<Program> programs) {
+ SeriesRecordingScheduler.getInstance(DvrSchedulesActivity.this).resumeUpdate();
+ dialog.dismiss();
+ Bundle args = getIntent().getExtras();
+ args.putParcelableArrayList(DvrSeriesSchedulesFragment
+ .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS, new ArrayList<>(programs));
+ DvrSeriesSchedulesFragment schedulesFragment = new DvrSeriesSchedulesFragment();
+ schedulesFragment.setArguments(args);
+ getFragmentManager().beginTransaction().add(
+ R.id.fragment_container, schedulesFragment).commit();
+ }
+ }.setLoadCurrentProgram(true)
+ .setLoadDisallowedProgram(true)
+ .setLoadScheduledEpisode(true)
+ .setIgnoreChannelOption(true)
+ .execute();
} else {
finish();
}
}
-
- private void showDvrSeriesSchedulesFragment(Bundle args) {
- DvrSeriesSchedulesFragment schedulesFragment = new DvrSeriesSchedulesFragment();
- schedulesFragment.setArguments(args);
- getFragmentManager().beginTransaction().add(
- R.id.fragment_container, schedulesFragment).commit();
- }
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
index 667af34a..f57e4b05 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
@@ -22,6 +22,9 @@ import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.ui.SeriesDeletionFragment;
+import com.android.tv.ui.sidepanel.SettingsFragment;
/**
* Activity to show details view in DVR.
@@ -39,7 +42,7 @@ public class DvrSeriesDeletionActivity extends Activity {
setContentView(R.layout.activity_dvr_series_settings);
// Check savedInstanceState to prevent that activity is being showed with animation.
if (savedInstanceState == null) {
- DvrSeriesDeletionFragment deletionFragment = new DvrSeriesDeletionFragment();
+ SeriesDeletionFragment deletionFragment = new SeriesDeletionFragment();
deletionFragment.setArguments(getIntent().getExtras());
GuidedStepFragment.addAsRoot(this, deletionFragment, R.id.dvr_settings_view_frame);
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
index 8f880f16..1173df46 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
@@ -25,29 +25,22 @@ import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
import java.util.List;
public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
- /**
- * The key for program list which will be passed to {@link DvrSeriesSchedulesFragment}.
- * Type: List<{@link Program}>
- */
- public static final String SERIES_SCHEDULED_KEY_PROGRAMS = "series_scheduled_key_programs";
-
private final static long SERIES_RECORDING_ID_NOT_SET = -1;
private final static int ACTION_VIEW_SCHEDULES = 1;
+ private DvrScheduleManager mDvrScheduleManager;
private SeriesRecording mSeriesRecording;
private boolean mShowViewScheduleOption;
- private List<Program> mPrograms;
private int mSchedulesAddedCount = 0;
private boolean mHasConflict = false;
@@ -65,25 +58,22 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
}
mShowViewScheduleOption = getArguments().getBoolean(
DvrSeriesScheduledDialogActivity.SHOW_VIEW_SCHEDULE_OPTION);
+ mDvrScheduleManager = TvApplication.getSingletons(context).getDvrScheduleManager();
mSeriesRecording = TvApplication.getSingletons(context).getDvrDataManager()
.getSeriesRecording(seriesRecordingId);
if (mSeriesRecording == null) {
getActivity().finish();
return;
}
- mPrograms = (List<Program>) BigArguments.getArgument(SERIES_SCHEDULED_KEY_PROGRAMS);
- BigArguments.reset();
mSchedulesAddedCount = TvApplication.getSingletons(getContext()).getDvrManager()
.getAvailableScheduledRecording(mSeriesRecording.getId()).size();
- DvrScheduleManager dvrScheduleManager =
- TvApplication.getSingletons(context).getDvrScheduleManager();
List<ScheduledRecording> conflictingRecordings =
- dvrScheduleManager.getConflictingSchedules(mSeriesRecording);
+ mDvrScheduleManager.getConflictingSchedules(mSeriesRecording);
mHasConflict = !conflictingRecordings.isEmpty();
for (ScheduledRecording recording : conflictingRecordings) {
if (recording.getSeriesRecordingId() == mSeriesRecording.getId()) {
++mInThisSeriesConflictCount;
- } else if (recording.getPriority() < mSeriesRecording.getPriority()) {
+ } else {
++mOutThisSeriesConflictCount;
}
}
@@ -123,9 +113,6 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
.TYPE_SERIES_SCHEDULE);
intent.putExtra(DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_RECORDING,
mSeriesRecording);
- BigArguments.reset();
- BigArguments.setArgument(DvrSeriesSchedulesFragment
- .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS, mPrograms);
startActivity(intent);
}
getActivity().finish();
@@ -134,30 +121,30 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
private String getDescription() {
if (!mHasConflict) {
return getResources().getQuantityString(
- R.plurals.dvr_series_scheduled_no_conflict, mSchedulesAddedCount,
+ R.plurals.dvr_series_recording_scheduled_no_conflict, mSchedulesAddedCount,
mSchedulesAddedCount, mSeriesRecording.getTitle());
} else {
// mInThisSeriesConflictCount equals 0 and mOutThisSeriesConflictCount equals 0 means
// mHasConflict is false. So we don't need to check that case.
if (mInThisSeriesConflictCount != 0 && mOutThisSeriesConflictCount != 0) {
- return getResources().getQuantityString(
- R.plurals.dvr_series_scheduled_this_and_other_series_conflict,
+ return getResources().getQuantityString(R.plurals
+ .dvr_series_recording_scheduled_this_and_other_series_conflict,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mInThisSeriesConflictCount + mOutThisSeriesConflictCount);
} else if (mInThisSeriesConflictCount != 0) {
- return getResources().getQuantityString(
- R.plurals.dvr_series_recording_scheduled_only_this_series_conflict,
+ return getResources().getQuantityString(R.plurals
+ .dvr_series_recording_scheduled_only_this_series_conflict,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mInThisSeriesConflictCount);
} else {
if (mOutThisSeriesConflictCount == 1) {
- return getResources().getQuantityString(
- R.plurals.dvr_series_scheduled_only_other_series_one_conflict,
+ return getResources().getQuantityString(R.plurals
+ .dvr_series_recording_scheduled_only_other_series_one_conflict,
mSchedulesAddedCount, mSchedulesAddedCount,
mSeriesRecording.getTitle());
} else {
- return getResources().getQuantityString(
- R.plurals.dvr_series_scheduled_only_other_series_many_conflicts,
+ return getResources().getQuantityString(R.plurals
+ .dvr_series_recording_scheduled_only_other_series_conflict,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mOutThisSeriesConflictCount);
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
index 6dd20b3a..3f7671b3 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
@@ -17,6 +17,7 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
+import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
@@ -37,34 +38,25 @@ public class DvrSeriesSettingsActivity extends Activity {
/**
* Name of the boolean flag to decide if the series recording with empty schedule and recording
* will be removed.
- * Type: boolean
*/
public static final String REMOVE_EMPTY_SERIES_RECORDING = "remove_empty_series_recording";
/**
* Name of the boolean flag to decide if the setting fragment should be translucent.
- * Type: boolean
*/
public static final String IS_WINDOW_TRANSLUCENT = "windows_translucent";
/**
- * Name of the program list. The list contains the programs which belong to the series.
- * Type: List<{@link com.android.tv.data.Program}>
+ * Name of the channel id list. If the channel list is given, we show the channels
+ * from the values in channel option.
+ * Type: Long array
*/
- public static final String PROGRAM_LIST = "program_list";
+ public static final String CHANNEL_ID_LIST = "channel_id_list";
/**
* Name of the boolean flag to check if the confirm dialog should show view schedule option.
- * Type: boolean
*/
public static final String SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG =
"show_view_schedule_option_in_dialog";
- /**
- * Name of the current program added to series. The current program will be recorded only when
- * the series recording is initialized from media controller. But for other case, the current
- * program won't be recorded.
- */
- public static final String CURRENT_PROGRAM = "current_program";
-
@Override
public void onCreate(Bundle savedInstanceState) {
TvApplication.setCurrentRunningProcess(this, true);
@@ -74,7 +66,7 @@ public class DvrSeriesSettingsActivity extends Activity {
SoftPreconditions.checkArgument(seriesRecordingId != -1);
if (savedInstanceState == null) {
- DvrSeriesSettingsFragment settingFragment = new DvrSeriesSettingsFragment();
+ SeriesSettingsFragment settingFragment = new SeriesSettingsFragment();
settingFragment.setArguments(getIntent().getExtras());
GuidedStepFragment.addAsRoot(this, settingFragment, R.id.dvr_settings_view_frame);
}
diff --git a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
index b476fff7..c3867886 100644
--- a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
@@ -33,7 +33,7 @@ import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -131,8 +131,15 @@ public class DvrStopRecordingFragment extends DvrGuidedStepFragment {
String title = getString(R.string.dvr_stop_recording_dialog_title);
String description;
if (mStopReason == REASON_ON_CONFLICT) {
+ String programTitle = mSchedule.getProgramTitle();
+ if (TextUtils.isEmpty(programTitle)) {
+ ChannelDataManager channelDataManager =
+ TvApplication.getSingletons(getActivity()).getChannelDataManager();
+ Channel channel = channelDataManager.getChannel(mSchedule.getChannelId());
+ programTitle = channel.getDisplayName();
+ }
description = getString(R.string.dvr_stop_recording_dialog_description_on_conflict,
- mSchedule.getProgramDisplayTitle(getContext()));
+ mSchedule.getProgramTitle());
} else {
description = getString(R.string.dvr_stop_recording_dialog_description);
}
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
index fe3a4a60..feaa2357 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
@@ -31,8 +31,8 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/tv/dvr/ui/DvrUiHelper.java b/src/com/android/tv/dvr/ui/DvrUiHelper.java
deleted file mode 100644
index 507db6e7..00000000
--- a/src/com/android/tv/dvr/ui/DvrUiHelper.java
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.media.tv.TvInputManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.MainThread;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityOptionsCompat;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Channel;
-import com.android.tv.data.Program;
-import com.android.tv.dialog.HalfSizedDialogFragment;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrStorageStatusManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyRecordedDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyScheduledDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelRecordDurationOptionDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelWatchConflictDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrInsufficientSpaceErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrMissingStorageErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrNoFreeSpaceErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrProgramConflictDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrScheduleDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrSmallSizedStorageErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrStopRecordingDialogFragment;
-import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
-import com.android.tv.dvr.ui.browse.DvrDetailsActivity;
-import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
-import com.android.tv.dvr.ui.list.DvrSchedulesFragment;
-import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
-import com.android.tv.util.ToastUtils;
-import com.android.tv.util.Utils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A helper class for DVR UI.
- */
-@MainThread
-@TargetApi(Build.VERSION_CODES.N)
-public class DvrUiHelper {
- private static String TAG = "DvrUiHelper";
-
- private static ProgressDialog sProgressDialog = null;
-
- /**
- * Checks if the storage status is good for recording and shows error messages if needed.
- *
- * @param recordingRequestRunnable if the storage status is OK to record or users choose to
- * perform the operation anyway, this Runnable will run.
- */
- public static void checkStorageStatusAndShowErrorMessage(Activity activity, String inputId,
- Runnable recordingRequestRunnable) {
- if (Utils.isBundledInput(inputId)) {
- switch (TvApplication.getSingletons(activity).getDvrStorageStatusManager()
- .getDvrStorageStatus()) {
- case DvrStorageStatusManager.STORAGE_STATUS_TOTAL_CAPACITY_TOO_SMALL:
- showDvrSmallSizedStorageErrorDialog(activity);
- return;
- case DvrStorageStatusManager.STORAGE_STATUS_MISSING:
- showDvrMissingStorageErrorDialog(activity);
- return;
- case DvrStorageStatusManager.STORAGE_STATUS_FREE_SPACE_INSUFFICIENT:
- showDvrNoFreeSpaceErrorDialog(activity, recordingRequestRunnable);
- return;
- }
- }
- recordingRequestRunnable.run();
- }
-
- /**
- * Shows the schedule dialog.
- */
- public static void showScheduleDialog(Activity activity, Program program,
- boolean addCurrentProgramToSeries) {
- if (SoftPreconditions.checkNotNull(program) == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- args.putBoolean(DvrScheduleFragment.KEY_ADD_CURRENT_PROGRAM_TO_SERIES,
- addCurrentProgramToSeries);
- showDialogFragment(activity, new DvrScheduleDialogFragment(), args, true, true);
- }
-
- /**
- * Shows the recording duration options dialog.
- */
- public static void showChannelRecordDurationOptions(Activity activity, Channel channel) {
- if (SoftPreconditions.checkNotNull(channel) == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
- showDialogFragment(activity, new DvrChannelRecordDurationOptionDialogFragment(), args);
- }
-
- /**
- * Shows the dialog which says that the new schedule conflicts with others.
- */
- public static void showScheduleConflictDialog(Activity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrProgramConflictDialogFragment(), args, false, true);
- }
-
- /**
- * Shows the conflict dialog for the channel watching.
- */
- public static void showChannelWatchConflictDialog(MainActivity activity, Channel channel) {
- if (channel == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
- showDialogFragment(activity, new DvrChannelWatchConflictDialogFragment(), args);
- }
-
- /**
- * Shows DVR insufficient space error dialog.
- */
- public static void showDvrInsufficientSpaceErrorDialog(MainActivity activity,
- Set<String> failedScheduledRecordingInfoSet) {
- Bundle args = new Bundle();
- ArrayList<String> failedScheduledRecordingInfoArray =
- new ArrayList<>(failedScheduledRecordingInfoSet);
- args.putStringArrayList(DvrInsufficientSpaceErrorFragment.FAILED_SCHEDULED_RECORDING_INFOS,
- failedScheduledRecordingInfoArray);
- showDialogFragment(activity, new DvrInsufficientSpaceErrorDialogFragment(), args);
- Utils.clearRecordingFailedReason(activity,
- TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
- Utils.clearFailedScheduledRecordingInfoSet(activity);
- }
-
- /**
- * Shows DVR no free space error dialog.
- *
- * @param recordingRequestRunnable the recording request to be executed when users choose
- * {@link DvrGuidedStepFragment#ACTION_RECORD_ANYWAY}.
- */
- public static void showDvrNoFreeSpaceErrorDialog(Activity activity,
- Runnable recordingRequestRunnable) {
- DvrHalfSizedDialogFragment fragment = new DvrNoFreeSpaceErrorDialogFragment();
- fragment.setOnActionClickListener(new HalfSizedDialogFragment.OnActionClickListener() {
- @Override
- public void onActionClick(long actionId) {
- if (actionId == DvrGuidedStepFragment.ACTION_RECORD_ANYWAY) {
- recordingRequestRunnable.run();
- } else if (actionId == DvrGuidedStepFragment.ACTION_DELETE_RECORDINGS) {
- Intent intent = new Intent(activity, DvrBrowseActivity.class);
- activity.startActivity(intent);
- }
- }
- });
- showDialogFragment(activity, fragment, null);
- }
-
- /**
- * Shows DVR missing storage error dialog.
- */
- private static void showDvrMissingStorageErrorDialog(Activity activity) {
- showDialogFragment(activity, new DvrMissingStorageErrorDialogFragment(), null);
- }
-
- /**
- * Shows DVR small sized storage error dialog.
- */
- public static void showDvrSmallSizedStorageErrorDialog(Activity activity) {
- showDialogFragment(activity, new DvrSmallSizedStorageErrorDialogFragment(), null);
- }
-
- /**
- * Shows stop recording dialog.
- */
- public static void showStopRecordingDialog(Activity activity, long channelId, int reason,
- HalfSizedDialogFragment.OnActionClickListener listener) {
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channelId);
- args.putInt(DvrStopRecordingFragment.KEY_REASON, reason);
- DvrHalfSizedDialogFragment fragment = new DvrStopRecordingDialogFragment();
- fragment.setOnActionClickListener(listener);
- showDialogFragment(activity, fragment, args);
- }
-
- /**
- * Shows "already scheduled" dialog.
- */
- public static void showAlreadyScheduleDialog(Activity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrAlreadyScheduledDialogFragment(), args, false, true);
- }
-
- /**
- * Shows "already recorded" dialog.
- */
- public static void showAlreadyRecordedDialog(Activity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrAlreadyRecordedDialogFragment(), args, false, true);
- }
-
- /**
- * Handle the request of recording a current program. It will handle creating schedules and
- * shows the proper dialog and toast message respectively for timed-recording and program
- * recording cases.
- *
- * @param addProgramToSeries denotes whether the program to be recorded should be added into
- * the series recording when users choose to record the entire series.
- */
- public static void requestRecordingCurrentProgram(Activity activity,
- Channel channel, Program program, boolean addProgramToSeries) {
- if (program == null) {
- DvrUiHelper.showChannelRecordDurationOptions(activity, channel);
- } else if (DvrUiHelper.handleCreateSchedule(activity, program, addProgramToSeries)) {
- String msg = activity.getString(R.string.dvr_msg_current_program_scheduled,
- program.getTitle(), Utils.toTimeString(program.getEndTimeUtcMillis(), false));
- Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
- }
- }
-
- /**
- * Handle the request of recording a future program. It will handle creating schedules and
- * shows the proper toast message.
- *
- * @param addProgramToSeries denotes whether the program to be recorded should be added into
- * the series recording when users choose to record the entire series.
- */
- public static void requestRecordingFutureProgram(Activity activity,
- Program program, boolean addProgramToSeries) {
- if (DvrUiHelper.handleCreateSchedule(activity, program, addProgramToSeries)) {
- String msg = activity.getString(
- R.string.dvr_msg_program_scheduled, program.getTitle());
- ToastUtils.show(activity, msg, Toast.LENGTH_SHORT);
- }
- }
-
- /**
- * Handles the action to create the new schedule. It returns {@code true} if the schedule is
- * added and there's no additional UI, otherwise {@code false}.
- */
- private static boolean handleCreateSchedule(Activity activity, Program program,
- boolean addProgramToSeries) {
- if (program == null) {
- return false;
- }
- DvrManager dvrManager = TvApplication.getSingletons(activity).getDvrManager();
- if (!program.isEpisodic()) {
- // One time recording.
- dvrManager.addSchedule(program);
- if (!dvrManager.getConflictingSchedules(program).isEmpty()) {
- DvrUiHelper.showScheduleConflictDialog(activity, program);
- return false;
- }
- } else {
- // Show recorded program rather than the schedule.
- RecordedProgram recordedProgram = dvrManager.getRecordedProgram(program.getTitle(),
- program.getSeasonNumber(), program.getEpisodeNumber());
- if (recordedProgram != null) {
- DvrUiHelper.showAlreadyRecordedDialog(activity, program);
- return false;
- }
- ScheduledRecording duplicate = dvrManager.getScheduledRecording(program.getTitle(),
- program.getSeasonNumber(), program.getEpisodeNumber());
- if (duplicate != null
- && (duplicate.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
- || duplicate.getState()
- == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
- DvrUiHelper.showAlreadyScheduleDialog(activity, program);
- return false;
- }
- SeriesRecording seriesRecording = dvrManager.getSeriesRecording(program);
- if (seriesRecording == null || seriesRecording.isStopped()) {
- DvrUiHelper.showScheduleDialog(activity, program, addProgramToSeries);
- return false;
- } else {
- // Just add the schedule.
- dvrManager.addSchedule(program);
- }
- }
- return true;
- }
-
- private static void showDialogFragment(Activity activity,
- DvrHalfSizedDialogFragment dialogFragment, Bundle args) {
- showDialogFragment(activity, dialogFragment, args, false, false);
- }
-
- private static void showDialogFragment(Activity activity,
- DvrHalfSizedDialogFragment dialogFragment, Bundle args, boolean keepSidePanelHistory,
- boolean keepProgramGuide) {
- dialogFragment.setArguments(args);
- if (activity instanceof MainActivity) {
- ((MainActivity) activity).getOverlayManager()
- .showDialogFragment(DvrHalfSizedDialogFragment.DIALOG_TAG, dialogFragment,
- keepSidePanelHistory, keepProgramGuide);
- } else {
- dialogFragment.show(activity.getFragmentManager(),
- DvrHalfSizedDialogFragment.DIALOG_TAG);
- }
- }
-
- /**
- * Checks whether channel watch conflict dialog is open or not.
- */
- public static boolean isChannelWatchConflictDialogShown(MainActivity activity) {
- return activity.getOverlayManager().getCurrentDialog() instanceof
- DvrChannelWatchConflictDialogFragment;
- }
-
- private static ScheduledRecording getEarliestScheduledRecording(List<ScheduledRecording>
- recordings) {
- ScheduledRecording earlistScheduledRecording = null;
- if (!recordings.isEmpty()) {
- Collections.sort(recordings,
- ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR);
- earlistScheduledRecording = recordings.get(0);
- }
- return earlistScheduledRecording;
- }
-
- /**
- * Shows the schedules activity to resolve the tune conflict.
- */
- public static void startSchedulesActivityForTuneConflict(Context context, Channel channel) {
- if (channel == null) {
- return;
- }
- List<ScheduledRecording> conflicts = TvApplication.getSingletons(context).getDvrManager()
- .getConflictingSchedulesForTune(channel.getId());
- startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
- }
-
- /**
- * Shows the schedules activity to resolve the one time recording conflict.
- */
- public static void startSchedulesActivityForOneTimeRecordingConflict(Context context,
- List<ScheduledRecording> conflicts) {
- startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
- }
-
- /**
- * Shows the schedules activity with full schedule.
- */
- public static void startSchedulesActivity(Context context, ScheduledRecording
- focusedScheduledRecording) {
- Intent intent = new Intent(context, DvrSchedulesActivity.class);
- intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
- DvrSchedulesActivity.TYPE_FULL_SCHEDULE);
- if (focusedScheduledRecording != null) {
- intent.putExtra(DvrSchedulesFragment.SCHEDULES_KEY_SCHEDULED_RECORDING,
- focusedScheduledRecording);
- }
- context.startActivity(intent);
- }
-
- /**
- * Shows the schedules activity for series recording.
- */
- public static void startSchedulesActivityForSeries(Context context,
- SeriesRecording seriesRecording) {
- Intent intent = new Intent(context, DvrSchedulesActivity.class);
- intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
- DvrSchedulesActivity.TYPE_SERIES_SCHEDULE);
- intent.putExtra(DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_RECORDING,
- seriesRecording);
- context.startActivity(intent);
- }
-
- /**
- * Shows the series settings activity.
- *
- * @param programs list of programs which belong to the series.
- */
- public static void startSeriesSettingsActivity(Context context, long seriesRecordingId,
- @Nullable List<Program> programs, boolean removeEmptySeriesSchedule,
- boolean isWindowTranslucent, boolean showViewScheduleOptionInDialog,
- Program currentProgram) {
- SeriesRecording series = TvApplication.getSingletons(context).getDvrDataManager()
- .getSeriesRecording(seriesRecordingId);
- if (series == null) {
- return;
- }
- if (programs != null) {
- startSeriesSettingsActivityInternal(context, seriesRecordingId, programs,
- removeEmptySeriesSchedule, isWindowTranslucent,
- showViewScheduleOptionInDialog, currentProgram);
- } else {
- EpisodicProgramLoadTask episodicProgramLoadTask =
- new EpisodicProgramLoadTask(context, series) {
- @Override
- protected void onPostExecute(List<Program> loadedPrograms) {
- sProgressDialog.dismiss();
- sProgressDialog = null;
- startSeriesSettingsActivityInternal(context, seriesRecordingId,
- loadedPrograms == null ? Collections.EMPTY_LIST : loadedPrograms,
- removeEmptySeriesSchedule, isWindowTranslucent,
- showViewScheduleOptionInDialog, currentProgram);
- }
- }.setLoadCurrentProgram(true)
- .setLoadDisallowedProgram(true)
- .setLoadScheduledEpisode(true)
- .setIgnoreChannelOption(true);
- sProgressDialog = ProgressDialog.show(context, null, context.getString(
- R.string.dvr_series_progress_message_reading_programs), true, true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialogInterface) {
- episodicProgramLoadTask.cancel(true);
- sProgressDialog = null;
- }
- });
- episodicProgramLoadTask.execute();
- }
- }
-
- private static void startSeriesSettingsActivityInternal(Context context, long seriesRecordingId,
- @NonNull List<Program> programs, boolean removeEmptySeriesSchedule,
- boolean isWindowTranslucent, boolean showViewScheduleOptionInDialog,
- Program currentProgram) {
- SoftPreconditions.checkState(programs != null,
- TAG, "Start series settings activity but programs is null");
- Intent intent = new Intent(context, DvrSeriesSettingsActivity.class);
- intent.putExtra(DvrSeriesSettingsActivity.SERIES_RECORDING_ID, seriesRecordingId);
- BigArguments.reset();
- BigArguments.setArgument(DvrSeriesSettingsActivity.PROGRAM_LIST, programs);
- intent.putExtra(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING,
- removeEmptySeriesSchedule);
- intent.putExtra(DvrSeriesSettingsActivity.IS_WINDOW_TRANSLUCENT, isWindowTranslucent);
- intent.putExtra(DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG,
- showViewScheduleOptionInDialog);
- intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram);
- context.startActivity(intent);
- }
-
- /**
- * Shows "series recording scheduled" dialog activity.
- */
- public static void StartSeriesScheduledDialogActivity(Context context,
- SeriesRecording seriesRecording, boolean showViewScheduleOptionInDialog,
- List<Program> programs) {
- if (seriesRecording == null) {
- return;
- }
- Intent intent = new Intent(context, DvrSeriesScheduledDialogActivity.class);
- intent.putExtra(DvrSeriesScheduledDialogActivity.SERIES_RECORDING_ID,
- seriesRecording.getId());
- intent.putExtra(DvrSeriesScheduledDialogActivity.SHOW_VIEW_SCHEDULE_OPTION,
- showViewScheduleOptionInDialog);
- BigArguments.reset();
- BigArguments.setArgument(DvrSeriesScheduledFragment.SERIES_SCHEDULED_KEY_PROGRAMS,
- programs);
- context.startActivity(intent);
- }
-
- /**
- * Shows the details activity for the DVR items. The type of DVR items may be
- * {@link ScheduledRecording}, {@link RecordedProgram}, or {@link SeriesRecording}.
- */
- public static void startDetailsActivity(Activity activity, Object dvrItem,
- @Nullable ImageView imageView, boolean hideViewSchedule) {
- if (dvrItem == null) {
- return;
- }
- Intent intent = new Intent(activity, DvrDetailsActivity.class);
- long recordingId;
- int viewType;
- if (dvrItem instanceof ScheduledRecording) {
- ScheduledRecording schedule = (ScheduledRecording) dvrItem;
- recordingId = schedule.getId();
- if (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
- viewType = DvrDetailsActivity.SCHEDULED_RECORDING_VIEW;
- } else if (schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
- viewType = DvrDetailsActivity.CURRENT_RECORDING_VIEW;
- } else {
- return;
- }
- } else if (dvrItem instanceof RecordedProgram) {
- recordingId = ((RecordedProgram) dvrItem).getId();
- viewType = DvrDetailsActivity.RECORDED_PROGRAM_VIEW;
- } else if (dvrItem instanceof SeriesRecording) {
- recordingId = ((SeriesRecording) dvrItem).getId();
- viewType = DvrDetailsActivity.SERIES_RECORDING_VIEW;
- } else {
- return;
- }
- intent.putExtra(DvrDetailsActivity.RECORDING_ID, recordingId);
- intent.putExtra(DvrDetailsActivity.DETAILS_VIEW_TYPE, viewType);
- intent.putExtra(DvrDetailsActivity.HIDE_VIEW_SCHEDULE, hideViewSchedule);
- Bundle bundle = null;
- if (imageView != null) {
- bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView,
- DvrDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
- }
- activity.startActivity(intent, bundle);
- }
-
- /**
- * Shows the cancel all dialog for series schedules list.
- */
- public static void showCancelAllSeriesRecordingDialog(DvrSchedulesActivity activity,
- SeriesRecording seriesRecording) {
- DvrStopSeriesRecordingDialogFragment dvrStopSeriesRecordingDialogFragment =
- new DvrStopSeriesRecordingDialogFragment();
- Bundle arguments = new Bundle();
- arguments.putParcelable(DvrStopSeriesRecordingFragment.KEY_SERIES_RECORDING,
- seriesRecording);
- dvrStopSeriesRecordingDialogFragment.setArguments(arguments);
- dvrStopSeriesRecordingDialogFragment.show(activity.getFragmentManager(),
- DvrStopSeriesRecordingDialogFragment.DIALOG_TAG);
- }
-
- /**
- * Shows the series deletion activity.
- */
- public static void startSeriesDeletionActivity(Context context, long seriesRecordingId) {
- Intent intent = new Intent(context, DvrSeriesDeletionActivity.class);
- intent.putExtra(DvrSeriesDeletionActivity.SERIES_RECORDING_ID, seriesRecordingId);
- context.startActivity(intent);
- }
-
- public static void showAddScheduleToast(Context context,
- String title, long startTimeMs, long endTimeMs) {
- String msg = (startTimeMs > System.currentTimeMillis()) ?
- context.getString(R.string.dvr_msg_program_scheduled, title)
- : context.getString(R.string.dvr_msg_current_program_scheduled, title,
- Utils.toTimeString(endTimeMs, false));
- Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/FadeBackground.java b/src/com/android/tv/dvr/ui/FadeBackground.java
deleted file mode 100644
index 4f06ebcf..00000000
--- a/src/com/android/tv/dvr/ui/FadeBackground.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.transition.Transition;
-import android.transition.TransitionValues;
-import android.transition.Visibility;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-
-/**
- * This transition fades in/out of the background of the view by changing the background color.
- */
-public class FadeBackground extends Transition {
- private final int mMode;
-
- public FadeBackground(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadeBackground);
- mMode = a.getInt(R.styleable.FadeBackground_fadingMode, Visibility.MODE_IN);
- a.recycle();
- }
-
- @Override
- public void captureStartValues(TransitionValues transitionValues) { }
-
- @Override
- public void captureEndValues(TransitionValues transitionValues) { }
-
- @Override
- public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null) {
- return null;
- }
- Drawable background = endValues.view.getBackground();
- if (background instanceof ColorDrawable) {
- int color = ((ColorDrawable) background).getColor();
- int transparentColor = Color.argb(0, Color.red(color), Color.green(color),
- Color.blue(color));
- return mMode == Visibility.MODE_OUT
- ? ObjectAnimator.ofArgb(background, "color", transparentColor)
- : ObjectAnimator.ofArgb(background, "color", transparentColor, color);
- }
- return null;
- }
-}
diff --git a/src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java b/src/com/android/tv/dvr/ui/FullScheduleCardHolder.java
index 311137a9..d4d4d8ab 100644
--- a/src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java
+++ b/src/com/android/tv/dvr/ui/FullScheduleCardHolder.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
/**
* Special object for schedule preview;
diff --git a/src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java b/src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java
index 6d4763d4..7dd85f45 100644
--- a/src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java
+++ b/src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.Context;
-import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.widget.Presenter;
import android.view.View;
import android.view.ViewGroup;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.Collections;
@@ -33,31 +33,23 @@ import java.util.List;
/**
* Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
*/
-class FullSchedulesCardPresenter extends DvrItemPresenter {
- private Context mContext;
- private final Drawable mIconDrawable;
- private final String mCardTitleText;
-
- public FullSchedulesCardPresenter(Context context) {
- mContext = context;
- mIconDrawable = mContext.getDrawable(R.drawable.dvr_full_schedule);
- mCardTitleText = mContext.getString(R.string.dvr_full_schedule_card_view_title);
- }
-
+public class FullSchedulesCardPresenter extends Presenter {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
Context context = parent.getContext();
RecordingCardView view = new RecordingCardView(context);
- return new ViewHolder(view);
+ return new ScheduledRecordingViewHolder(view);
}
@Override
- public void onBindViewHolder(ViewHolder vh, Object o) {
- final RecordingCardView cardView = (RecordingCardView) vh.view;
+ public void onBindViewHolder(ViewHolder baseHolder, Object o) {
+ final ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
+ final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
+ final Context context = viewHolder.view.getContext();
- cardView.setImage(mIconDrawable);
- cardView.setTitle(mCardTitleText);
- List<ScheduledRecording> scheduledRecordings = TvApplication.getSingletons(mContext)
+ cardView.setImage(context.getDrawable(R.drawable.dvr_full_schedule));
+ cardView.setTitle(context.getString(R.string.dvr_full_schedule_card_view_title));
+ List<ScheduledRecording> scheduledRecordings = TvApplication.getSingletons(context)
.getDvrDataManager().getAvailableScheduledRecordings();
int fullDays = 0;
if (!scheduledRecordings.isEmpty()) {
@@ -65,24 +57,28 @@ class FullSchedulesCardPresenter extends DvrItemPresenter {
Collections.max(scheduledRecordings, ScheduledRecording.START_TIME_COMPARATOR)
.getStartTimeMs()) + 1;
}
- cardView.setContent(mContext.getResources().getQuantityString(
+ cardView.setContent(context.getResources().getQuantityString(
R.plurals.dvr_full_schedule_card_view_content, fullDays, fullDays), null);
- super.onBindViewHolder(vh, o);
+
+ View.OnClickListener clickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ DvrUiHelper.startSchedulesActivity(context, null);
+ }
+ };
+ baseHolder.view.setOnClickListener(clickListener);
}
@Override
- public void onUnbindViewHolder(ViewHolder vh) {
- ((RecordingCardView) vh.view).reset();
- super.onUnbindViewHolder(vh);
+ public void onUnbindViewHolder(ViewHolder baseHolder) {
+ ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
+ final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
+ cardView.reset();
}
- @Override
- protected View.OnClickListener onCreateOnClickListener() {
- return new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- DvrUiHelper.startSchedulesActivity(mContext, null);
- }
- };
+ private static final class ScheduledRecordingViewHolder extends ViewHolder {
+ ScheduledRecordingViewHolder(RecordingCardView view) {
+ super(view);
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java
new file mode 100644
index 00000000..d320816e
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.dvr.ui;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+import com.android.tv.dialog.SafeDismissDialogFragment;
+
+import java.util.concurrent.TimeUnit;
+
+public class HalfSizedDialogFragment extends SafeDismissDialogFragment {
+ public static final String DIALOG_TAG = HalfSizedDialogFragment.class.getSimpleName();
+ public static final String TRACKER_LABEL = "Half sized dialog";
+
+ private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
+
+ private OnActionClickListener mOnActionClickListener;
+
+ private Handler mHandler = new Handler();
+ private Runnable mAutoDismisser = new Runnable() {
+ @Override
+ public void run() {
+ dismiss();
+ }
+ };
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.halfsized_dialog, container, false);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
+ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent keyEvent) {
+ mHandler.removeCallbacks(mAutoDismisser);
+ mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
+ return false;
+ }
+ });
+ mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mOnActionClickListener != null) {
+ // Dismisses the dialog to prevent the callback being forgotten during
+ // fragment re-creating.
+ dismiss();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mHandler.removeCallbacks(mAutoDismisser);
+ }
+
+ @Override
+ public int getTheme() {
+ return R.style.Theme_TV_dialog_HalfSizedDialog;
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return TRACKER_LABEL;
+ }
+
+ /**
+ * Sets {@link OnActionClickListener} for the dialog fragment. If listener is set, the dialog
+ * will be automatically closed when it's paused to prevent the fragment being re-created by
+ * the framework, which will result the listener being forgotten.
+ */
+ public void setOnActionClickListener(OnActionClickListener listener) {
+ mOnActionClickListener = listener;
+ }
+
+ /**
+ * Returns {@link OnActionClickListener} for sub-classes or any inner fragments.
+ */
+ protected OnActionClickListener getOnActionClickListener() {
+ return mOnActionClickListener;
+ }
+
+ /**
+ * An interface to provide callbacks for half-sized dialogs. Subclasses or inner fragments
+ * should invoke {@link OnActionClickListener#onActionClick(long)} and provide the identifier
+ * of the action user clicked.
+ */
+ public interface OnActionClickListener {
+ void onActionClick(long actionId);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java b/src/com/android/tv/dvr/ui/PrioritySettingsFragment.java
index 562898a3..158bd824 100644
--- a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/PrioritySettingsFragment.java
@@ -33,7 +33,7 @@ import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.SeriesRecording;
import java.util.ArrayList;
import java.util.List;
@@ -41,7 +41,7 @@ import java.util.List;
/**
* Fragment for DVR series recording settings.
*/
-public class DvrPrioritySettingsFragment extends GuidedStepFragment {
+public class PrioritySettingsFragment extends GuidedStepFragment {
/**
* Name of series recording id starting the fragment.
* Type: Long
@@ -162,6 +162,7 @@ public class DvrPrioritySettingsFragment extends GuidedStepFragment {
return;
}
if (action.getId() < 0) {
+ int selectedPosition = mSeriesRecordings.indexOf(mSelectedRecording);
mSelectedRecording = null;
for (int i = 0; i < mSeriesRecordings.size(); ++i) {
updateItem(i);
@@ -247,4 +248,4 @@ public class DvrPrioritySettingsFragment extends GuidedStepFragment {
titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java b/src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java
index fe9b9de5..e698b8a2 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.res.Resources;
import android.media.tv.TvInputManager;
@@ -30,10 +30,10 @@ import com.android.tv.data.Channel;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.RecordedProgram;
/**
- * {@link android.support.v17.leanback.app.DetailsFragment} for recorded program in DVR.
+ * {@link DetailsFragment} for recorded program in DVR.
*/
public class RecordedProgramDetailsFragment extends DvrDetailsFragment
implements DvrDataManager.RecordedProgramListener {
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java b/src/com/android/tv/dvr/ui/RecordedProgramPresenter.java
index ee978797..1bf34310 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java
+++ b/src/com/android/tv/dvr/ui/RecordedProgramPresenter.java
@@ -14,26 +14,31 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
+import android.app.Activity;
import android.content.Context;
import android.media.tv.TvContract;
import android.media.tv.TvInputManager;
+import android.net.Uri;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
+import android.view.View;
import android.view.ViewGroup;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
-import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.util.Utils;
+import java.util.concurrent.TimeUnit;
+
/**
* Presents a {@link RecordedProgram} in the {@link DvrBrowseFragment}.
*/
@@ -45,7 +50,6 @@ public class RecordedProgramPresenter extends DvrItemPresenter {
private String mYesterdayString;
private final int mProgressBarColor;
private final boolean mShowEpisodeTitle;
- private final boolean mExpandTitleWhenFocused;
private static final class RecordedProgramViewHolder extends ViewHolder
implements WatchedPositionChangedListener {
@@ -75,27 +79,25 @@ public class RecordedProgramPresenter extends DvrItemPresenter {
}
}
- public RecordedProgramPresenter(Context context, boolean showEpisodeTitle,
- boolean expandTitleWhenFocused) {
+ public RecordedProgramPresenter(Context context, boolean showEpisodeTitle) {
mContext = context;
- mChannelDataManager = TvApplication.getSingletons(mContext).getChannelDataManager();
- mTodayString = mContext.getString(R.string.dvr_date_today);
- mYesterdayString = mContext.getString(R.string.dvr_date_yesterday);
+ mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
+ mTodayString = context.getString(R.string.dvr_date_today);
+ mYesterdayString = context.getString(R.string.dvr_date_yesterday);
mDvrWatchedPositionManager =
- TvApplication.getSingletons(mContext).getDvrWatchedPositionManager();
- mProgressBarColor = mContext.getResources()
+ TvApplication.getSingletons(context).getDvrWatchedPositionManager();
+ mProgressBarColor = context.getResources()
.getColor(R.color.play_controls_progress_bar_watched);
mShowEpisodeTitle = showEpisodeTitle;
- mExpandTitleWhenFocused = expandTitleWhenFocused;
}
public RecordedProgramPresenter(Context context) {
- this(context, false, false);
+ this(context, false);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
- RecordingCardView view = new RecordingCardView(mContext, mExpandTitleWhenFocused);
+ RecordingCardView view = new RecordingCardView(mContext);
return new RecordedProgramViewHolder(view, mProgressBarColor);
}
@@ -130,7 +132,8 @@ public class RecordedProgramPresenter extends DvrItemPresenter {
isChannelLogo = true;
}
cardView.setImageUri(imageUri, isChannelLogo);
- int durationMinutes = Math.max(1, Utils.getRoundOffMinsFromMs(program.getDurationMillis()));
+ int durationMinutes =
+ Math.max(1, (int) TimeUnit.MILLISECONDS.toMinutes(program.getDurationMillis()));
String durationString = getContext().getResources().getQuantityString(
R.plurals.dvr_program_duration, durationMinutes, durationMinutes);
cardView.setContent(getDescription(program), durationString);
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java b/src/com/android/tv/dvr/ui/RecordingCardView.java
index 7b0a8cb9..51c3b03b 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
+++ b/src/com/android/tv/dvr/ui/RecordingCardView.java
@@ -14,69 +14,51 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.v17.leanback.widget.BaseCardView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.tv.R;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.ui.ViewUtils;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.util.ImageLoader;
/**
- * A CardView for displaying info about a {@link com.android.tv.dvr.data.ScheduledRecording}
- * or {@link RecordedProgram} or {@link com.android.tv.dvr.data.SeriesRecording}.
+ * A CardView for displaying info about a {@link com.android.tv.dvr.ScheduledRecording} or
+ * {@link RecordedProgram} or
+ * {@link com.android.tv.dvr.SeriesRecording}.
*/
-public class RecordingCardView extends BaseCardView {
- // This value should be the same with
- // android.support.v17.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
- private final static int ANIMATION_DURATION = 150;
+class RecordingCardView extends BaseCardView {
private final ImageView mImageView;
private final int mImageWidth;
private final int mImageHeight;
private String mImageUri;
+ private final TextView mTitleView;
private final TextView mMajorContentView;
private final TextView mMinorContentView;
private final ProgressBar mProgressBar;
private final View mAffiliatedIconContainer;
private final ImageView mAffiliatedIcon;
private final Drawable mDefaultImage;
- private final FrameLayout mTitleArea;
- private final TextView mFoldedTitleView;
- private final TextView mExpandedTitleView;
- private final ValueAnimator mExpandTitleAnimator;
- private final int mFoldedTitleHeight;
- private final int mExpandedTitleHeight;
- private final boolean mExpandTitleWhenFocused;
- private boolean mExpanded;
- public RecordingCardView(Context context) {
- this(context, false);
+ RecordingCardView(Context context) {
+ this(context,
+ context.getResources().getDimensionPixelSize(R.dimen.dvr_card_image_layout_width),
+ context.getResources().getDimensionPixelSize(R.dimen.dvr_card_image_layout_height));
}
- public RecordingCardView(Context context, boolean expandTitleWhenFocused) {
- this(context, context.getResources().getDimensionPixelSize(
- R.dimen.dvr_library_card_image_layout_width), context.getResources()
- .getDimensionPixelSize(R.dimen.dvr_library_card_image_layout_height),
- expandTitleWhenFocused);
- }
-
- public RecordingCardView(Context context, int imageWidth, int imageHeight,
- boolean expandTitleWhenFocused) {
+ RecordingCardView(Context context, int imageWidth, int imageHeight) {
super(context);
//TODO(dvr): move these to the layout XML.
setCardType(BaseCardView.CARD_TYPE_INFO_UNDER_WITH_EXTRA);
@@ -93,73 +75,13 @@ public class RecordingCardView extends BaseCardView {
mProgressBar = (ProgressBar) findViewById(R.id.recording_progress);
mAffiliatedIconContainer = findViewById(R.id.affiliated_icon_container);
mAffiliatedIcon = (ImageView) findViewById(R.id.affiliated_icon);
+ mTitleView = (TextView) findViewById(R.id.title);
mMajorContentView = (TextView) findViewById(R.id.content_major);
mMinorContentView = (TextView) findViewById(R.id.content_minor);
- mTitleArea = (FrameLayout) findViewById(R.id.title_area);
- mFoldedTitleView = (TextView) findViewById(R.id.title_one_line);
- mExpandedTitleView = (TextView) findViewById(R.id.title_two_lines);
- mFoldedTitleHeight = getResources()
- .getDimensionPixelSize(R.dimen.dvr_library_card_folded_title_height);
- mExpandedTitleHeight = getResources()
- .getDimensionPixelSize(R.dimen.dvr_library_card_expanded_title_height);
- mExpandTitleAnimator = ValueAnimator.ofFloat(0.0f, 1.0f).setDuration(ANIMATION_DURATION);
- mExpandTitleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- float value = (Float) valueAnimator.getAnimatedValue();
- mExpandedTitleView.setAlpha(value);
- mFoldedTitleView.setAlpha(1.0f - value);
- ViewUtils.setLayoutHeight(mTitleArea, (int) (mFoldedTitleHeight
- + (mExpandedTitleHeight - mFoldedTitleHeight) * value));
- }
- });
- mExpandTitleWhenFocused = expandTitleWhenFocused;
- }
-
- @Override
- protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
- super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- if (mExpandTitleWhenFocused) {
- if (gainFocus) {
- expandTitle(true, true);
- } else {
- expandTitle(false, true);
- }
- }
- }
-
- /**
- * Expands/folds the title area to show program title with two/one lines.
- *
- * @param expand {@code true} to expand the title area, or {@code false} to fold it.
- * @param withAnimation {@code true} to expand/fold with animation.
- */
- public void expandTitle(boolean expand, boolean withAnimation) {
- if (expand != mExpanded && mFoldedTitleView.getLayout().getEllipsisCount(0) > 0) {
- if (withAnimation) {
- if (expand) {
- mExpandTitleAnimator.start();
- } else {
- mExpandTitleAnimator.reverse();
- }
- } else {
- if (expand) {
- mFoldedTitleView.setAlpha(0.0f);
- mExpandedTitleView.setAlpha(1.0f);
- ViewUtils.setLayoutHeight(mTitleArea, mExpandedTitleHeight);
- } else {
- mFoldedTitleView.setAlpha(1.0f);
- mExpandedTitleView.setAlpha(0.0f);
- ViewUtils.setLayoutHeight(mTitleArea, mFoldedTitleHeight);
- }
- }
- mExpanded = expand;
- }
}
void setTitle(CharSequence title) {
- mFoldedTitleView.setText(title);
- mExpandedTitleView.setText(title);
+ mTitleView.setText(title);
}
void setContent(CharSequence majorContent, CharSequence minorContent) {
@@ -256,9 +178,8 @@ public class RecordingCardView extends BaseCardView {
}
public void reset() {
- mFoldedTitleView.setText(null);
- mExpandedTitleView.setText(null);
+ mTitleView.setText(null);
setContent(null, null);
mImageView.setImageDrawable(mDefaultImage);
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/RecordingDetailsFragment.java
index a877e05f..4e19ec3f 100644
--- a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/RecordingDetailsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.os.Bundle;
import android.support.v17.leanback.app.DetailsFragment;
@@ -26,7 +26,7 @@ import android.text.style.TextAppearanceSpan;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.Channel;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
/**
* {@link DetailsFragment} for recordings in DVR.
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java
index eb0f4f0d..60816bb5 100644
--- a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.res.Resources;
import android.os.Bundle;
@@ -26,7 +26,7 @@ import android.text.TextUtils;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.DvrUiHelper;
/**
* {@link RecordingDetailsFragment} for scheduled recording in DVR.
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java b/src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java
index efc8785a..5f447f13 100644
--- a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java
+++ b/src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
+import android.app.Activity;
import android.content.Context;
import android.media.tv.TvContract;
import android.os.Handler;
@@ -31,7 +32,7 @@ import com.android.tv.TvApplication;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.concurrent.TimeUnit;
@@ -39,7 +40,7 @@ import java.util.concurrent.TimeUnit;
/**
* Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
*/
-class ScheduledRecordingPresenter extends DvrItemPresenter {
+public class ScheduledRecordingPresenter extends DvrItemPresenter {
private static final long PROGRESS_UPDATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(5);
private final ChannelDataManager mChannelDataManager;
@@ -91,17 +92,18 @@ class ScheduledRecordingPresenter extends DvrItemPresenter {
}
public ScheduledRecordingPresenter(Context context) {
- mContext = context;
- ApplicationSingletons singletons = TvApplication.getSingletons(mContext);
+ ApplicationSingletons singletons = TvApplication.getSingletons(context);
mChannelDataManager = singletons.getChannelDataManager();
mDvrManager = singletons.getDvrManager();
- mProgressBarColor = mContext.getResources()
+ mContext = context;
+ mProgressBarColor = context.getResources()
.getColor(R.color.play_controls_recording_icon_color_on_focus);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
- RecordingCardView view = new RecordingCardView(mContext);
+ Context context = parent.getContext();
+ RecordingCardView view = new RecordingCardView(context);
return new ScheduledRecordingViewHolder(view, mProgressBarColor);
}
@@ -142,8 +144,9 @@ class ScheduledRecordingPresenter extends DvrItemPresenter {
public void onUnbindViewHolder(ViewHolder baseHolder) {
ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
viewHolder.stopUpdateProgressBar();
+ final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
viewHolder.mScheduledRecording = null;
- ((RecordingCardView) viewHolder.view).reset();
+ cardView.reset();
super.onUnbindViewHolder(viewHolder);
}
@@ -171,4 +174,4 @@ class ScheduledRecordingPresenter extends DvrItemPresenter {
cardView.setTitle(title);
cardView.setImageUri(imageUri, isChannelLogo);
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java b/src/com/android/tv/dvr/ui/SeriesDeletionFragment.java
index 8bf8560f..36e3cfc1 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
+++ b/src/com/android/tv/dvr/ui/SeriesDeletionFragment.java
@@ -33,10 +33,9 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.SeriesRecording;
import com.android.tv.ui.GuidedActionsStylistWithDivider;
-import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.Collections;
@@ -48,7 +47,7 @@ import java.util.concurrent.TimeUnit;
/**
* Fragment for DVR series recording settings.
*/
-public class DvrSeriesDeletionFragment extends GuidedStepFragment {
+public class SeriesDeletionFragment extends GuidedStepFragment {
private static final long WATCHED_TIME_UNIT_THRESHOLD = TimeUnit.MINUTES.toMillis(2);
// Since recordings' IDs are used as its check actions' IDs, which are random positive numbers,
@@ -219,8 +218,8 @@ public class DvrSeriesDeletionFragment extends GuidedStepFragment {
private String getWatchedString(long watchedPositionMs, long durationMs) {
if (durationMs > WATCHED_TIME_UNIT_THRESHOLD) {
return getResources().getString(R.string.dvr_series_watched_info_minutes,
- Math.max(1, Utils.getRoundOffMinsFromMs(watchedPositionMs)),
- Utils.getRoundOffMinsFromMs(durationMs));
+ Math.max(1, TimeUnit.MILLISECONDS.toMinutes(watchedPositionMs)),
+ TimeUnit.MILLISECONDS.toMinutes(durationMs));
} else {
return getResources().getString(R.string.dvr_series_watched_info_seconds,
Math.max(1, TimeUnit.MILLISECONDS.toSeconds(watchedPositionMs)),
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java
index f7b60b50..e9e391d4 100644
--- a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
+++ b/src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -28,6 +28,7 @@ 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.ListRowPresenter;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.PresenterSelector;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
@@ -38,11 +39,12 @@ import com.android.tv.TvApplication;
import com.android.tv.data.BaseProgram;
import com.android.tv.data.Channel;
import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrUiHelper;
import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.ui.DvrUiHelper;
-import com.android.tv.dvr.ui.SortedArrayAdapter;
+import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import java.util.Collections;
import java.util.Comparator;
@@ -83,7 +85,7 @@ public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implement
mWatchLabel = getString(R.string.dvr_detail_watch);
mResumeLabel = getString(R.string.dvr_detail_series_resume);
mWatchDrawable = getResources().getDrawable(R.drawable.lb_ic_play, null);
- mRecordedProgramPresenter = new RecordedProgramPresenter(getContext(), true, true);
+ mRecordedProgramPresenter = new RecordedProgramPresenter(getContext(), true);
super.onCreate(savedInstanceState);
}
@@ -156,7 +158,7 @@ public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implement
DetailsOverviewRowPresenter rowPresenter) {
ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
- presenterSelector.addClassPresenter(ListRow.class, new DvrListRowPresenter(getContext()));
+ presenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
return presenterSelector;
}
@@ -201,7 +203,10 @@ public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implement
mDvrDataManager.removeSeriesRecordingListener(this);
mDvrDataManager.removeRecordedProgramListener(this);
if (mSeries != null) {
- mDvrDataManager.checkAndRemoveEmptySeriesRecording(mSeries.getId());
+ DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
+ if (dvrManager.canRemoveSeriesRecording(mSeries.getId())) {
+ dvrManager.removeSeriesRecording(mSeries.getId());
+ }
}
mRecordedProgramPresenter.unbindAllViewHolders();
}
@@ -260,6 +265,7 @@ public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implement
public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
for (SeriesRecording series : seriesRecordings) {
if (series.getId() == mSeries.getId()) {
+ mSeries = null;
getActivity().finish();
return;
}
@@ -366,4 +372,4 @@ public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implement
return program.getId();
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java b/src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java
index af6ecc19..c2c0f596 100644
--- a/src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java
+++ b/src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package com.android.tv.dvr.ui.browse;
+package com.android.tv.dvr.ui;
+import android.app.Activity;
import android.content.Context;
import android.media.tv.TvContract;
import android.media.tv.TvInputManager;
@@ -33,16 +34,16 @@ import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import java.util.List;
/**
* Presents a {@link SeriesRecording} in {@link DvrBrowseFragment}.
*/
-class SeriesRecordingPresenter extends DvrItemPresenter {
+public class SeriesRecordingPresenter extends DvrItemPresenter {
private final ChannelDataManager mChannelDataManager;
private final DvrDataManager mDvrDataManager;
private final DvrManager mDvrManager;
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/SeriesSettingsFragment.java
index f28382da..6c05c9c6 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
+++ b/src/com/android/tv/dvr/ui/SeriesSettingsFragment.java
@@ -17,13 +17,19 @@
package com.android.tv.dvr.ui;
import android.app.FragmentManager;
+import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.util.Log;
import android.util.LongSparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ProgressBar;
import com.android.tv.R;
import com.android.tv.TvApplication;
@@ -32,14 +38,14 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeasonEpisodeNumber;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.data.SeriesRecording.ChannelOption;
-import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.EpisodicProgramLoadTask;
+import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.SeriesRecording.ChannelOption;
+import com.android.tv.dvr.SeriesRecordingScheduler;
+import com.android.tv.dvr.SeriesRecordingScheduler.OnSeriesRecordingUpdatedListener;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -47,7 +53,7 @@ import java.util.Set;
/**
* Fragment for DVR series recording settings.
*/
-public class DvrSeriesSettingsFragment extends GuidedStepFragment
+public class SeriesSettingsFragment extends GuidedStepFragment
implements DvrDataManager.SeriesRecordingListener {
private static final String TAG = "SeriesSettingsFragment";
private static final boolean DEBUG = false;
@@ -60,13 +66,15 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
private static final long SUB_ACTION_ID_CHANNEL_ONE_BASE = 500;
private DvrDataManager mDvrDataManager;
+ private ChannelDataManager mChannelDataManager;
+ private DvrManager mDvrManager;
private SeriesRecording mSeriesRecording;
private long mSeriesRecordingId;
@ChannelOption int mChannelOption;
+ private Comparator<Channel> mChannelComparator;
private long mSelectedChannelId;
private int mBackStackCount;
private boolean mShowViewScheduleOptionInDialog;
- private Program mCurrentProgram;
private String mFragmentTitle;
private String mProrityActionTitle;
@@ -76,7 +84,7 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
private String mChannelsActionAllText;
private LongSparseArray<Channel> mId2Channel = new LongSparseArray<>();
private List<Channel> mChannels = new ArrayList<>();
- private List<Program> mPrograms;
+ private EpisodicProgramLoadTask mEpisodicProgramLoadTask;
private GuidedAction mPriorityGuidedAction;
private GuidedAction mChannelsGuidedAction;
@@ -92,24 +100,22 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
getActivity().finish();
return;
}
+ mDvrManager = TvApplication.getSingletons(context).getDvrManager();
mShowViewScheduleOptionInDialog = getArguments().getBoolean(
DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG);
- mCurrentProgram = getArguments().getParcelable(DvrSeriesSettingsActivity.CURRENT_PROGRAM);
mDvrDataManager.addSeriesRecordingListener(this);
- mPrograms = (List<Program>) BigArguments.getArgument(
- DvrSeriesSettingsActivity.PROGRAM_LIST);
- BigArguments.reset();
- if (mPrograms == null) {
- getActivity().finish();
- return;
- }
- Set<Long> channelIds = new HashSet<>();
- ChannelDataManager channelDataManager =
- TvApplication.getSingletons(context).getChannelDataManager();
- for (Program program : mPrograms) {
- long channelId = program.getChannelId();
- if (channelIds.add(channelId)) {
- Channel channel = channelDataManager.getChannel(channelId);
+ long[] channelIds = getArguments().getLongArray(DvrSeriesSettingsActivity.CHANNEL_ID_LIST);
+ mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
+ if (channelIds == null) {
+ Channel channel = mChannelDataManager.getChannel(mSeriesRecording.getChannelId());
+ if (channel != null) {
+ mId2Channel.put(channel.getId(), channel);
+ mChannels.add(channel);
+ }
+ collectChannelsInBackground();
+ } else {
+ for (long channelId : channelIds) {
+ Channel channel = mChannelDataManager.getChannel(channelId);
if (channel != null) {
mId2Channel.put(channel.getId(), channel);
mChannels.add(channel);
@@ -119,14 +125,16 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
mChannelOption = mSeriesRecording.getChannelOption();
mSelectedChannelId = Channel.INVALID_ID;
if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE) {
- Channel channel = channelDataManager.getChannel(mSeriesRecording.getChannelId());
+ Channel channel = mChannelDataManager.getChannel(mSeriesRecording.getChannelId());
if (channel != null) {
mSelectedChannelId = channel.getId();
} else {
mChannelOption = SeriesRecording.OPTION_CHANNEL_ALL;
}
}
- mChannels.sort(Channel.CHANNEL_NUMBER_COMPARATOR);
+ mChannelComparator = new Channel.DefaultComparator(context,
+ TvApplication.getSingletons(context).getTvInputManagerHelper());
+ mChannels.sort(mChannelComparator);
mFragmentTitle = getString(R.string.dvr_series_settings_title);
mProrityActionTitle = getString(R.string.dvr_series_settings_priority);
mProrityActionHighestText = getString(R.string.dvr_series_settings_priority_highest);
@@ -136,23 +144,23 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
}
@Override
- public void onResume() {
- super.onResume();
- // To avoid the order of series's priority has changed, but series doesn't get update.
- updatePriorityGuidedAction();
- }
-
- @Override
public void onDetach() {
super.onDetach();
mDvrDataManager.removeSeriesRecordingListener(this);
+ if (mEpisodicProgramLoadTask != null) {
+ mEpisodicProgramLoadTask.cancel(true);
+ mEpisodicProgramLoadTask = null;
+ }
}
@Override
public void onDestroy() {
- if (getFragmentManager().getBackStackEntryCount() == mBackStackCount && getArguments()
- .getBoolean(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING)) {
- mDvrDataManager.checkAndRemoveEmptySeriesRecording(mSeriesRecordingId);
+ DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
+ if (getFragmentManager().getBackStackEntryCount() == mBackStackCount
+ && getArguments()
+ .getBoolean(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING)
+ && dvrManager.canRemoveSeriesRecording(mSeriesRecordingId)) {
+ dvrManager.removeSeriesRecording(mSeriesRecordingId);
}
super.onDestroy();
}
@@ -170,6 +178,7 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
.id(ACTION_ID_PRIORITY)
.title(mProrityActionTitle)
.build();
+ updatePriorityGuidedAction(false);
actions.add(mPriorityGuidedAction);
mChannelsGuidedAction = new GuidedAction.Builder(getActivity())
@@ -195,6 +204,10 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
public void onGuidedActionClicked(GuidedAction action) {
long actionId = action.getId();
if (actionId == GuidedAction.ACTION_ID_OK) {
+ if (mEpisodicProgramLoadTask != null) {
+ mEpisodicProgramLoadTask.cancel(true);
+ mEpisodicProgramLoadTask = null;
+ }
if (mChannelOption != mSeriesRecording.getChannelOption()
|| mSeriesRecording.isStopped()
|| (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE
@@ -205,14 +218,28 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
if (mSelectedChannelId != Channel.INVALID_ID) {
builder.setChannelId(mSelectedChannelId);
}
- DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
- dvrManager.updateSeriesRecording(builder.build());
- if (mCurrentProgram != null && (mChannelOption == SeriesRecording.OPTION_CHANNEL_ALL
- || mSelectedChannelId == mCurrentProgram.getChannelId())) {
- dvrManager.addSchedule(mCurrentProgram);
- }
- updateSchedulesToSeries();
- showConfirmDialog();
+ TvApplication.getSingletons(getContext()).getDvrManager()
+ .updateSeriesRecording(builder.build());
+ SeriesRecordingScheduler scheduler =
+ SeriesRecordingScheduler.getInstance(getContext());
+ // Since dialog is used even after the fragment is closed, we should
+ // use application context.
+ ProgressDialog dialog = ProgressDialog.show(getContext(), null, getString(
+ R.string.dvr_series_schedules_progress_message_updating_programs));
+ scheduler.addOnSeriesRecordingUpdatedListener(
+ new OnSeriesRecordingUpdatedListener() {
+ @Override
+ public void onSeriesRecordingUpdated(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ if (seriesRecording.getId() == mSeriesRecordingId) {
+ dialog.dismiss();
+ scheduler.removeOnSeriesRecordingUpdatedListener(this);
+ showConfirmDialog();
+ return;
+ }
+ }
+ }
+ });
} else {
showConfirmDialog();
}
@@ -220,9 +247,9 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
finishGuidedStepFragments();
} else if (actionId == ACTION_ID_PRIORITY) {
FragmentManager fragmentManager = getFragmentManager();
- DvrPrioritySettingsFragment fragment = new DvrPrioritySettingsFragment();
+ PrioritySettingsFragment fragment = new PrioritySettingsFragment();
Bundle args = new Bundle();
- args.putLong(DvrPrioritySettingsFragment.COME_FROM_SERIES_RECORDING_ID,
+ args.putLong(PrioritySettingsFragment.COME_FROM_SERIES_RECORDING_ID,
mSeriesRecording.getId());
fragment.setArguments(args);
GuidedStepFragment.add(fragmentManager, fragment, R.id.dvr_settings_view_frame);
@@ -254,7 +281,7 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
private void updateChannelsGuidedAction(boolean notifyActionChanged) {
if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ALL) {
mChannelsGuidedAction.setDescription(mChannelsActionAllText);
- } else if (mId2Channel.get(mSelectedChannelId) != null){
+ } else {
mChannelsGuidedAction.setDescription(mId2Channel.get(mSelectedChannelId)
.getDisplayText());
}
@@ -263,7 +290,7 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
}
}
- private void updatePriorityGuidedAction() {
+ private void updatePriorityGuidedAction(boolean notifyActionChanged) {
int totalSeriesCount = 0;
int priorityOrder = 0;
for (SeriesRecording seriesRecording : mDvrDataManager.getSeriesRecordings()) {
@@ -285,38 +312,49 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
mPriorityGuidedAction.setDescription(getString(
R.string.dvr_series_settings_priority_rank, priorityOrder + 1));
}
- notifyActionChanged(findActionPositionById(ACTION_ID_PRIORITY));
+ if (notifyActionChanged) {
+ notifyActionChanged(findActionPositionById(ACTION_ID_PRIORITY));
+ }
}
- private void updateSchedulesToSeries() {
- List<Program> recordingCandidates = new ArrayList<>();
- Set<SeasonEpisodeNumber> scheduledEpisodes = new HashSet<>();
- for (ScheduledRecording r : mDvrDataManager.getScheduledRecordings(mSeriesRecordingId)) {
- if (r.getState() != ScheduledRecording.STATE_RECORDING_FAILED
- && r.getState() != ScheduledRecording.STATE_RECORDING_CLIPPED) {
- scheduledEpisodes.add(new SeasonEpisodeNumber(
- r.getSeriesRecordingId(), r.getSeasonNumber(), r.getEpisodeNumber()));
- }
+ private void collectChannelsInBackground() {
+ if (mEpisodicProgramLoadTask != null) {
+ mEpisodicProgramLoadTask.cancel(true);
}
- for (Program program : mPrograms) {
- // Removes current programs and scheduled episodes out, matches the channel option.
- if (program.getStartTimeUtcMillis() >= System.currentTimeMillis()
- && mSeriesRecording.matchProgram(program)
- && !scheduledEpisodes.contains(new SeasonEpisodeNumber(
- mSeriesRecordingId, program.getSeasonNumber(), program.getEpisodeNumber()))) {
- recordingCandidates.add(program);
+ mEpisodicProgramLoadTask = new EpisodicProgramLoadTask(getContext(), mSeriesRecording) {
+ @Override
+ protected void onPostExecute(List<Program> programs) {
+ mEpisodicProgramLoadTask = null;
+ Set<Long> channelIds = new HashSet<>();
+ for (Program program : programs) {
+ channelIds.add(program.getChannelId());
+ }
+ boolean channelAdded = false;
+ for (Long channelId : channelIds) {
+ if (mId2Channel.get(channelId) != null) {
+ continue;
+ }
+ Channel channel = mChannelDataManager.getChannel(channelId);
+ if (channel != null) {
+ channelAdded = true;
+ mId2Channel.put(channelId, channel);
+ mChannels.add(channel);
+ if (DEBUG) Log.d(TAG, "Added channel: " + channel);
+ }
+ }
+ if (!channelAdded) {
+ return;
+ }
+ mChannels.sort(mChannelComparator);
+ mChannelsGuidedAction.setSubActions(buildChannelSubAction());
+ notifyActionChanged(findActionPositionById(ACTION_ID_CHANNEL));
+ if (DEBUG) Log.d(TAG, "Complete EpisodicProgramLoadTask");
}
- }
- if (recordingCandidates.isEmpty()) {
- return;
- }
- List<Program> programsToSchedule = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDvrDataManager, Collections.singletonList(mSeriesRecording), recordingCandidates)
- .get(mSeriesRecordingId);
- if (!programsToSchedule.isEmpty()) {
- TvApplication.getSingletons(getContext()).getDvrManager()
- .addScheduleToSeriesRecording(mSeriesRecording, programsToSchedule);
- }
+ }.setLoadCurrentProgram(true)
+ .setLoadDisallowedProgram(true)
+ .setLoadScheduledEpisode(true)
+ .setIgnoreChannelOption(true);
+ mEpisodicProgramLoadTask.execute();
}
private List<GuidedAction> buildChannelSubAction() {
@@ -335,8 +373,8 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
}
private void showConfirmDialog() {
- DvrUiHelper.StartSeriesScheduledDialogActivity(getContext(), mSeriesRecording,
- mShowViewScheduleOptionInDialog, mPrograms);
+ DvrUiHelper.StartSeriesScheduledDialogActivity(
+ getContext(), mSeriesRecording, mShowViewScheduleOptionInDialog);
finishGuidedStepFragments();
}
@@ -344,23 +382,16 @@ public class DvrSeriesSettingsFragment extends GuidedStepFragment
public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
@Override
- public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
- for (SeriesRecording series : seriesRecordings) {
- if (series.getId() == mSeriesRecording.getId()) {
- finishGuidedStepFragments();
- return;
- }
- }
- }
+ public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) { }
@Override
public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
for (SeriesRecording seriesRecording : seriesRecordings) {
if (seriesRecording.getId() == mSeriesRecordingId) {
mSeriesRecording = seriesRecording;
- updatePriorityGuidedAction();
+ updatePriorityGuidedAction(true);
return;
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
index 8c0af9ed..393a5ff3 100644
--- a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
+++ b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
@@ -20,15 +20,11 @@ import android.support.annotation.VisibleForTesting;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.PresenterSelector;
-import com.android.tv.common.SoftPreconditions;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* Keeps a set of items sorted
@@ -39,18 +35,16 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
private final Comparator<T> mComparator;
private final int mMaxItemCount;
private int mExtraItemCount;
- private final Set<Long> mIds = new HashSet<>();
- public SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator) {
+ SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator) {
this(presenterSelector, comparator, Integer.MAX_VALUE);
}
- public SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator,
+ SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator,
int maxItemCount) {
super(presenterSelector);
mComparator = comparator;
mMaxItemCount = maxItemCount;
- setHasStableIds(true);
}
/**
@@ -62,12 +56,7 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
final void setInitialItems(List<T> items) {
List<T> itemsCopy = new ArrayList<>(items);
Collections.sort(itemsCopy, mComparator);
- for (T item : itemsCopy) {
- add(item, true);
- if (size() == mMaxItemCount) {
- break;
- }
- }
+ addAll(0, itemsCopy.subList(0, Math.min(mMaxItemCount, itemsCopy.size())));
}
/**
@@ -93,9 +82,6 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
* the end to save search time.
*/
public final void add(T item, boolean insertToEnd) {
- long newItemId = getId(item);
- SoftPreconditions.checkState(!mIds.contains(newItemId));
- mIds.add(newItemId);
int i;
if (insertToEnd) {
i = findInsertPosition(item);
@@ -103,9 +89,8 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
i = findInsertPositionBinary(item);
}
super.add(i, item);
- if (mMaxItemCount < Integer.MAX_VALUE && size() > mMaxItemCount + mExtraItemCount) {
- Object removedItem = get(mMaxItemCount);
- remove(removedItem);
+ if (size() > mMaxItemCount + mExtraItemCount) {
+ removeItems(mMaxItemCount, size() - mMaxItemCount - mExtraItemCount);
}
}
@@ -115,97 +100,48 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
* They will be presented in their insertion order.
*/
public int addExtraItem(T item) {
- long newItemId = getId(item);
- SoftPreconditions.checkState(!mIds.contains(newItemId));
- mIds.add(newItemId);
super.add(item);
return ++mExtraItemCount;
}
- @Override
- public boolean remove(Object item) {
- return removeWithId((T) item);
- }
-
/**
* Removes an item which has the same ID as {@code item}.
*/
public boolean removeWithId(T item) {
- int index = indexWithId(item);
- return index >= 0 && index < size() && removeItems(index, 1) == 1;
- }
-
- @Override
- public int removeItems(int position, int count) {
- int upperBound = Math.min(position + count, size());
- for (int i = position; i < upperBound; i++) {
- mIds.remove(getId((T) get(i)));
- }
- if (upperBound > size() - mExtraItemCount) {
- mExtraItemCount -= upperBound - Math.max(size() - mExtraItemCount, position);
- }
- return super.removeItems(position, count);
- }
-
- @Override
- public void replace(int position, Object item) {
- boolean wasExtra = position >= size() - mExtraItemCount;
- removeItems(position, 1);
- if (!wasExtra) {
- add(item);
- } else {
- addExtraItem((T) item);
- }
- }
-
- @Override
- public void clear() {
- mIds.clear();
- super.clear();
+ int index = indexWithTypeAndId(item);
+ return index >= 0 && index < size() && remove(get(index));
}
/**
- * Changes an item in the list.
+ * Change an item in the list.
* @param item The item to change.
*/
public final void change(T item) {
- int oldIndex = indexWithId(item);
+ int oldIndex = indexWithTypeAndId(item);
if (oldIndex != -1) {
T old = (T) get(oldIndex);
if (mComparator.compare(old, item) == 0) {
replace(oldIndex, item);
return;
}
- remove(old);
+ removeItems(oldIndex, 1);
}
add(item);
}
/**
- * Checks whether the item is in the list.
- */
- public final boolean contains(T item) {
- return indexWithId(item) != -1;
- }
-
- @Override
- public long getId(int position) {
- return getId((T) get(position));
- }
-
- /**
* Returns the id of the the given {@code item}, which will be used in {@link #change} to
* decide if the given item is already existed in the adapter.
*
* The id must be stable.
*/
- protected abstract long getId(T item);
+ abstract long getId(T item);
- private int indexWithId(T item) {
+ private int indexWithTypeAndId(T item) {
long id = getId(item);
for (int i = 0; i < size() - mExtraItemCount; i++) {
T r = (T) get(i);
- if (getId(r) == id) {
+ if (r.getClass() == item.getClass() && getId(r) == id) {
return i;
}
}
diff --git a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
deleted file mode 100644
index c8f6a03f..00000000
--- a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.ui.browse;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dialog.HalfSizedDialogFragment;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.DvrUiHelper;
-
-/**
- * {@link RecordingDetailsFragment} for current recording in DVR.
- */
-public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
- private static final int ACTION_STOP_RECORDING = 1;
-
- private DvrDataManager mDvrDataManger;
- private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
- new DvrDataManager.ScheduledRecordingListener() {
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... schedules) { }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- if (schedule.getId() == getRecording().getId()) {
- getActivity().finish();
- return;
- }
- }
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- if (schedule.getId() == getRecording().getId()
- && schedule.getState()
- != ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
- getActivity().finish();
- return;
- }
- }
- }
- };
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mDvrDataManger = TvApplication.getSingletons(context).getDvrDataManager();
- mDvrDataManger.addScheduledRecordingListener(mScheduledRecordingListener);
- }
-
- @Override
- protected SparseArrayObjectAdapter onCreateActionsAdapter() {
- SparseArrayObjectAdapter adapter =
- new SparseArrayObjectAdapter(new ActionPresenterSelector());
- Resources res = getResources();
- adapter.set(ACTION_STOP_RECORDING, new Action(ACTION_STOP_RECORDING,
- res.getString(R.string.epg_dvr_dialog_message_stop_recording), null,
- res.getDrawable(R.drawable.lb_ic_stop)));
- return adapter;
- }
-
- @Override
- protected OnActionClickedListener onCreateOnActionClickedListener() {
- return new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == ACTION_STOP_RECORDING) {
- DvrUiHelper.showStopRecordingDialog(getActivity(),
- getRecording().getChannelId(),
- DvrStopRecordingFragment.REASON_USER_STOP,
- new HalfSizedDialogFragment.OnActionClickListener() {
- @Override
- public void onActionClick(long actionId) {
- if (actionId == DvrStopRecordingFragment.ACTION_STOP) {
- DvrManager dvrManager =
- TvApplication.getSingletons(getContext())
- .getDvrManager();
- dvrManager.stopRecording(getRecording());
- getActivity().finish();
- }
- }
- });
- }
- }
- };
- }
-
- @Override
- public void onDetach() {
- if (mDvrDataManger != null) {
- mDvrDataManger.removeScheduledRecordingListener(mScheduledRecordingListener);
- }
- super.onDetach();
- }
-}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
deleted file mode 100644
index 37a72eaf..00000000
--- a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.ui.browse;
-
-import android.content.Context;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-
-/** A list row presenter to display expand/fold card views list. */
-public class DvrListRowPresenter extends ListRowPresenter {
- public DvrListRowPresenter(Context context) {
- super();
- setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
- setExpandedRowHeight(
- context.getResources()
- .getDimensionPixelSize(R.dimen.dvr_library_expanded_row_height));
- }
-}
diff --git a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
index 5abd52a1..d28f026c 100644
--- a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
@@ -29,7 +29,7 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
/**
* A base fragment to show the list of schedule recordings.
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
index 3cbb500a..722c9b6e 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
@@ -18,9 +18,12 @@ package com.android.tv.dvr.ui.list;
import android.os.Bundle;
import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import com.android.tv.R;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.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 57e7a88f..42a1e72b 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
@@ -17,7 +17,6 @@
package com.android.tv.dvr.ui.list;
import android.annotation.TargetApi;
-import android.content.Context;
import android.database.ContentObserver;
import android.media.tv.TvContract.Programs;
import android.net.Uri;
@@ -36,13 +35,11 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
-import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
-import com.android.tv.dvr.ui.BigArguments;
+import com.android.tv.dvr.EpisodicProgramLoadTask;
+import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.SeriesRecordingHeaderRowPresenter;
-import java.util.Collections;
import java.util.List;
/**
@@ -50,22 +47,20 @@ import java.util.List;
*/
@TargetApi(Build.VERSION_CODES.N)
public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
+ private static final String TAG = "DvrSeriesSchedulesFragment";
/**
* The key for series recording whose scheduled recording list will be displayed.
- * Type: {@link SeriesRecording}
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_RECORDING =
"series_schedules_key_series_recording";
/**
- * The key for programs which belong to the series recording whose scheduled recording list
- * will be displayed.
- * Type: List<{@link Program}>
+ * The key for programs belong to the series recording whose scheduled recording
+ * list will be displayed.
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_PROGRAMS =
"series_schedules_key_series_programs";
private ChannelDataManager mChannelDataManager;
- private DvrDataManager mDvrDataManager;
private SeriesRecording mSeriesRecording;
private List<Program> mPrograms;
private EpisodicProgramLoadTask mProgramLoadTask;
@@ -92,22 +87,20 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
&& getRowsAdapter() instanceof SeriesScheduleRowAdapter) {
((SeriesScheduleRowAdapter) getRowsAdapter())
.onSeriesRecordingUpdated(r);
- mSeriesRecording = r;
- updateEmptyMessage();
return;
}
}
}
};
- private final Handler mHandler = new Handler(Looper.getMainLooper());
- private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- executeProgramLoadingTask();
- }
- };
+ private final ContentObserver mContentObserver =
+ new ContentObserver(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ executeProgramLoadingTask();
+ }
+ };
private final ChannelDataManager.Listener mChannelListener = new ChannelDataManager.Listener() {
@Override
@@ -127,28 +120,17 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
}
@Override
- public void onAttach(Context context) {
- super.onAttach(context);
+ public void onCreate(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
mSeriesRecording = args.getParcelable(SERIES_SCHEDULES_KEY_SERIES_RECORDING);
- mPrograms = (List<Program>) BigArguments.getArgument(
- SERIES_SCHEDULES_KEY_SERIES_PROGRAMS);
- BigArguments.reset();
+ mPrograms = args.getParcelableArrayList(SERIES_SCHEDULES_KEY_SERIES_PROGRAMS);
}
- if (args == null || mPrograms == null) {
- getActivity().finish();
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ApplicationSingletons singletons = TvApplication.getSingletons(getContext());
+ singletons.getDvrDataManager().addSeriesRecordingListener(mSeriesRecordingListener);
mChannelDataManager = singletons.getChannelDataManager();
mChannelDataManager.addListener(mChannelListener);
- mDvrDataManager = singletons.getDvrDataManager();
- mDvrDataManager.addSeriesRecordingListener(mSeriesRecordingListener);
getContext().getContentResolver().registerContentObserver(Programs.CONTENT_URI, true,
mContentObserver);
}
@@ -162,16 +144,8 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
private void onProgramsUpdated() {
((SeriesScheduleRowAdapter) getRowsAdapter()).setPrograms(mPrograms);
- updateEmptyMessage();
- }
-
- private void updateEmptyMessage() {
if (mPrograms == null || mPrograms.isEmpty()) {
- if (mSeriesRecording.getState() == SeriesRecording.STATE_SERIES_STOPPED) {
- showEmptyMessage(R.string.dvr_series_schedules_stopped_empty_state);
- } else {
- showEmptyMessage(R.string.dvr_series_schedules_empty_state);
- }
+ showEmptyMessage(R.string.dvr_series_schedules_empty_state);
} else {
hideEmptyMessage();
}
@@ -184,15 +158,15 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
mProgramLoadTask = null;
}
getContext().getContentResolver().unregisterContentObserver(mContentObserver);
- mHandler.removeCallbacksAndMessages(null);
mChannelDataManager.removeListener(mChannelListener);
- mDvrDataManager.removeSeriesRecordingListener(mSeriesRecordingListener);
+ TvApplication.getSingletons(getContext()).getDvrDataManager()
+ .removeSeriesRecordingListener(mSeriesRecordingListener);
super.onDestroy();
}
@Override
public SchedulesHeaderRowPresenter onCreateHeaderRowPresenter() {
- return new SchedulesHeaderRowPresenter.SeriesRecordingHeaderRowPresenter(getContext());
+ return new SeriesRecordingHeaderRowPresenter(getContext());
}
@Override
@@ -221,7 +195,7 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
mProgramLoadTask = new EpisodicProgramLoadTask(getContext(), mSeriesRecording) {
@Override
protected void onPostExecute(List<Program> programs) {
- mPrograms = programs == null ? Collections.EMPTY_LIST : programs;
+ mPrograms = programs;
onProgramsUpdated();
}
};
@@ -231,4 +205,4 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
.setIgnoreChannelOption(true)
.execute();
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
index 9b0ad105..23aebf59 100644
--- a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
+++ b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
@@ -19,13 +19,13 @@ package com.android.tv.dvr.ui.list;
import android.content.Context;
import com.android.tv.data.Program;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.ScheduledRecording.Builder;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording.Builder;
/**
* A class for the episodic program.
*/
-class EpisodicProgramRow extends ScheduleRow {
+public class EpisodicProgramRow extends ScheduleRow {
private final String mInputId;
private final Program mProgram;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRow.java b/src/com/android/tv/dvr/ui/list/ScheduleRow.java
index 66e96f94..3fc92e8a 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRow.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRow.java
@@ -20,12 +20,12 @@ import android.content.Context;
import android.support.annotation.Nullable;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ScheduledRecording;
/**
* A class for schedule recording row.
*/
-class ScheduleRow {
+public class ScheduleRow {
private final SchedulesHeaderRow mHeaderRow;
@Nullable private ScheduledRecording mSchedule;
private boolean mStopRecordingRequested;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
index 97d60473..9cc82653 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
@@ -30,8 +30,8 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow;
-import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.ArrayList;
@@ -43,7 +43,7 @@ import java.util.concurrent.TimeUnit;
/**
* An adapter for {@link ScheduleRow}.
*/
-class ScheduleRowAdapter extends ArrayObjectAdapter {
+public class ScheduleRowAdapter extends ArrayObjectAdapter {
private static final String TAG = "ScheduleRowAdapter";
private static final boolean DEBUG = false;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
index dc4e3c41..1257e725 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
@@ -42,24 +42,25 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
-import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.ui.HalfSizedDialogFragment;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
* A RowPresenter for {@link ScheduleRow}.
*/
@TargetApi(Build.VERSION_CODES.N)
-class ScheduleRowPresenter extends RowPresenter {
+public class ScheduleRowPresenter extends RowPresenter {
private static final String TAG = "ScheduleRowPresenter";
@Retention(RetentionPolicy.SOURCE)
@@ -344,9 +345,7 @@ class ScheduleRowPresenter extends RowPresenter {
viewHolder.mInfoContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- if (isInfoClickable(row)) {
- onInfoClicked(row);
- }
+ onInfoClicked(row);
}
});
@@ -367,7 +366,8 @@ class ScheduleRowPresenter extends RowPresenter {
viewHolder.mTimeView.setText(onGetRecordingTimeText(row));
String programInfoText = onGetProgramInfoText(row);
if (TextUtils.isEmpty(programInfoText)) {
- int durationMins = Math.max(1, Utils.getRoundOffMinsFromMs(row.getDuration()));
+ int durationMins =
+ Math.max((int) TimeUnit.MILLISECONDS.toMinutes(row.getDuration()), 1);
programInfoText = mContext.getResources().getQuantityString(
R.plurals.dvr_schedules_recording_duration, durationMins, durationMins);
}
@@ -403,7 +403,6 @@ class ScheduleRowPresenter extends RowPresenter {
} else {
viewHolder.whiteBackInfo();
}
- viewHolder.mInfoContainer.setFocusable(isInfoClickable(row));
updateActionContainer(viewHolder, viewHolder.isSelected());
}
@@ -455,13 +454,11 @@ class ScheduleRowPresenter extends RowPresenter {
/**
* Called when user click Info in {@link ScheduleRow}.
*/
- protected void onInfoClicked(ScheduleRow row) {
- DvrUiHelper.startDetailsActivity((Activity) mContext, row.getSchedule(), null, true);
- }
-
- private boolean isInfoClickable(ScheduleRow row) {
- return row.getSchedule() != null
- && (row.getSchedule().isNotStarted() || row.getSchedule().isInProgress());
+ protected void onInfoClicked(ScheduleRow scheduleRow) {
+ ScheduledRecording schedule = scheduleRow.getSchedule();
+ if (schedule != null) {
+ DvrUiHelper.startDetailsActivity((Activity) mContext, schedule, null, true);
+ }
}
/**
@@ -548,7 +545,7 @@ class ScheduleRowPresenter extends RowPresenter {
// This row has been deleted.
return;
}
- if (row.isRecordingInProgress() && !row.isStopRecordingRequested()) {
+ if (row.isOnAir() && row.isRecordingInProgress() && !row.isStopRecordingRequested()) {
row.setStopRecordingRequested(true);
mDvrManager.stopRecording(row.getSchedule());
CharSequence deletedInfo = onGetProgramInfoText(row);
@@ -673,9 +670,10 @@ class ScheduleRowPresenter extends RowPresenter {
hideActionView(viewHolder.mFirstActionContainer, View.GONE);
}
};
- mLastFocusedViewId = R.id.info_container;
- SoftPreconditions.checkState(viewHolder.mInfoContainer.isFocusable(), TAG,
- "No focusable view in this row: " + viewHolder);
+ if (mLastFocusedViewId == R.id.action_first_container
+ || mLastFocusedViewId == R.id.action_second_container) {
+ mLastFocusedViewId = R.id.info_container;
+ }
break;
}
View view = viewHolder.view.findViewById(mLastFocusedViewId);
@@ -685,10 +683,8 @@ class ScheduleRowPresenter extends RowPresenter {
// requestFocus() explicitly.
if (view.hasFocus()) {
viewHolder.mPendingAnimationRunnable.run();
- } else if (view.isFocusable()){
- view.requestFocus();
} else {
- viewHolder.view.requestFocus();
+ view.requestFocus();
}
}
} else {
@@ -741,10 +737,10 @@ class ScheduleRowPresenter extends RowPresenter {
@ScheduleRowAction
protected int[] getAvailableActions(ScheduleRow row) {
if (row.getSchedule() != null) {
- if (row.isRecordingInProgress()) {
- return new int[]{ACTION_STOP_RECORDING};
- } else if (row.isOnAir()) {
- if (row.isRecordingNotStarted()) {
+ if (row.isOnAir()) {
+ if (row.isRecordingInProgress()) {
+ return new int[] {ACTION_STOP_RECORDING};
+ } else if (row.isRecordingNotStarted()) {
if (canResolveConflict()) {
// The "START" action can change the conflict states.
return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_START_RECORDING};
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
index 715ecb8c..0fb0924d 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
@@ -16,15 +16,12 @@
package com.android.tv.dvr.ui.list;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.data.SeriesRecording;
-
-import java.util.List;
+import com.android.tv.dvr.SeriesRecording;
/**
* A base class for the rows for schedules' header.
*/
-abstract class SchedulesHeaderRow {
+public abstract class SchedulesHeaderRow {
private String mTitle;
private String mDescription;
private int mItemCount;
@@ -101,20 +98,11 @@ abstract class SchedulesHeaderRow {
*/
public static class SeriesRecordingHeaderRow extends SchedulesHeaderRow {
private SeriesRecording mSeriesRecording;
- private List<Program> mPrograms;
public SeriesRecordingHeaderRow(String title, String description, int itemCount,
- SeriesRecording series, List<Program> programs) {
+ SeriesRecording series) {
super(title, description, itemCount);
mSeriesRecording = series;
- mPrograms = programs;
- }
-
- /**
- * Returns the list of programs which belong to the series.
- */
- public List<Program> getPrograms() {
- return mPrograms;
}
/**
@@ -131,4 +119,4 @@ abstract class SchedulesHeaderRow {
mSeriesRecording = seriesRecording;
}
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
index fe2033ba..69c33a96 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
@@ -30,14 +30,15 @@ import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.ui.DvrSchedulesActivity;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
/**
* A base class for RowPresenter for {@link SchedulesHeaderRow}
*/
-abstract class SchedulesHeaderRowPresenter extends RowPresenter {
+public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
private Context mContext;
public SchedulesHeaderRowPresenter(Context context) {
@@ -78,7 +79,7 @@ abstract class SchedulesHeaderRowPresenter extends RowPresenter {
}
/**
- * A presenter for {@link SchedulesHeaderRow.DateHeaderRow}.
+ * A presenter for {@link com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowPresenter extends SchedulesHeaderRowPresenter {
public DateHeaderRowPresenter(Context context) {
@@ -92,7 +93,7 @@ abstract class SchedulesHeaderRowPresenter extends RowPresenter {
/**
* A ViewHolder for
- * {@link SchedulesHeaderRow.DateHeaderRow}.
+ * {@link com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowViewHolder extends SchedulesHeaderRowViewHolder {
public DateHeaderRowViewHolder(Context context, ViewGroup parent) {
@@ -151,9 +152,9 @@ abstract class SchedulesHeaderRowPresenter extends RowPresenter {
headerViewHolder.mSeriesSettingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
+ // TODO: pass channel list for settings.
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- header.getSeriesRecording().getId(),
- header.getPrograms(), false, false, false, null);
+ header.getSeriesRecording().getId(), null, false, false, false);
}
});
headerViewHolder.mToggleStartStopButton.setOnClickListener(new OnClickListener() {
@@ -168,9 +169,9 @@ abstract class SchedulesHeaderRowPresenter extends RowPresenter {
.build();
TvApplication.getSingletons(getContext()).getDvrManager()
.updateSeriesRecording(seriesRecording);
+ // TODO: pass channel list for settings.
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- header.getSeriesRecording().getId(),
- header.getPrograms(), false, false, false, null);
+ header.getSeriesRecording().getId(), null, false, false, false);
} else {
DvrUiHelper.showCancelAllSeriesRecordingDialog(
(DvrSchedulesActivity) view.getContext(),
@@ -181,8 +182,11 @@ abstract class SchedulesHeaderRowPresenter extends RowPresenter {
}
private void setTextDrawable(TextView textView, Drawable drawableStart) {
- textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, null, null,
- null);
+ if (mLtr) {
+ textView.setCompoundDrawablesWithIntrinsicBounds(drawableStart, null, null, null);
+ } else {
+ textView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawableStart, null);
+ }
}
/**
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
index 6b6de8b8..3b493774 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
@@ -31,8 +31,8 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.SeriesRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
import com.android.tv.util.Utils;
@@ -46,7 +46,7 @@ import java.util.Map;
* An adapter for series schedule row.
*/
@TargetApi(Build.VERSION_CODES.N)
-class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
+public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
private static final String TAG = "SeriesRowAdapter";
private static final boolean DEBUG = false;
@@ -96,7 +96,7 @@ class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
Collections.sort(sortedPrograms);
List<EpisodicProgramRow> rows = new ArrayList<>();
mHeaderRow = new SeriesRecordingHeaderRow(mSeriesRecording.getTitle(),
- null, sortedPrograms.size(), mSeriesRecording, programs);
+ null, sortedPrograms.size(), mSeriesRecording);
for (Program program : sortedPrograms) {
ScheduledRecording schedule =
mDataManager.getScheduledRecordingForProgramId(program.getId());
@@ -145,7 +145,7 @@ class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
if (index != -1) {
EpisodicProgramRow row = (EpisodicProgramRow) get(index);
if (!row.isStartRecordingRequested()) {
- setScheduleToRow(row, schedule);
+ row.setSchedule(schedule);
notifyArrayItemRangeChanged(index, 1);
}
}
@@ -195,10 +195,12 @@ class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
if (!isStartOrStopRequested()) {
executePendingUpdate();
}
- setScheduleToRow(row, schedule);
+ row.setSchedule(schedule);
}
+ } else if (willBeKept(schedule)) {
+ row.setSchedule(schedule);
} else {
- setScheduleToRow(row, schedule);
+ row.setSchedule(null);
}
notifyArrayItemRangeChanged(index, 1);
}
@@ -211,14 +213,6 @@ class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
}
}
- private void setScheduleToRow(ScheduleRow row, ScheduledRecording schedule) {
- if (schedule != null && willBeKept(schedule)) {
- row.setSchedule(schedule);
- } else {
- row.setSchedule(null);
- }
- }
-
private int findRowIndexByProgramId(long programId) {
for (int i = 0; i < size(); i++) {
Object item = get(i);
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
index c8503e0d..5d88579a 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
@@ -22,13 +22,13 @@ import android.view.ViewGroup;
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.DvrUiHelper;
import com.android.tv.util.Utils;
/**
* A RowPresenter for series schedule row.
*/
-class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
+public class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
private static final String TAG = "SeriesRowPresenter";
private boolean mLtr;
@@ -74,8 +74,13 @@ class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
viewHolder.getProgramTitleView().setCompoundDrawablePadding(getContext()
.getResources().getDimensionPixelOffset(
R.dimen.dvr_schedules_warning_icon_padding));
- viewHolder.getProgramTitleView().setCompoundDrawablesRelativeWithIntrinsicBounds(
- R.drawable.ic_warning_gray600_36dp, 0, 0, 0);
+ if (mLtr) {
+ viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.ic_warning_gray600_36dp, 0, 0, 0);
+ } else {
+ viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(
+ 0, 0, R.drawable.ic_warning_gray600_36dp, 0);
+ }
} else {
viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
@@ -83,7 +88,9 @@ class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
@Override
protected void onInfoClicked(ScheduleRow row) {
- DvrUiHelper.startSchedulesActivity(getContext(), row.getSchedule());
+ if (row.getSchedule() != null) {
+ DvrUiHelper.startSchedulesActivity(getContext(), row.getSchedule());
+ }
}
@Override
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
deleted file mode 100644
index 2437d1f5..00000000
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.ui.playback;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.data.RecordedProgram;
-
-/**
- * Activity to play a {@link RecordedProgram}.
- */
-public class DvrPlaybackActivity extends Activity {
- private static final String TAG = "DvrPlaybackActivity";
- private static final boolean DEBUG = false;
-
- private DvrPlaybackOverlayFragment mOverlayFragment;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- TvApplication.setCurrentRunningProcess(this, true);
- if (DEBUG) Log.d(TAG, "onCreate");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dvr_playback);
- mOverlayFragment = (DvrPlaybackOverlayFragment) getFragmentManager()
- .findFragmentById(R.id.dvr_playback_controls_fragment);
- }
-
- @Override
- public void onVisibleBehindCanceled() {
- if (DEBUG) Log.d(TAG, "onVisibleBehindCanceled");
- super.onVisibleBehindCanceled();
- finish();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- mOverlayFragment.onNewIntent(intent);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- float density = getResources().getDisplayMetrics().density;
- mOverlayFragment.onWindowSizeChanged((int) (newConfig.screenWidthDp * density),
- (int) (newConfig.screenHeightDp * density));
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java
deleted file mode 100644
index 843d2dbe..00000000
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.ui.playback;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.media.tv.TvContract;
-import android.os.AsyncTask;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.data.RecordedProgram;
-import com.android.tv.util.ImageLoader;
-import com.android.tv.util.TimeShiftUtils;
-import com.android.tv.util.Utils;
-
-class DvrPlaybackMediaSessionHelper {
- private static final String TAG = "DvrPlaybackMediaSessionHelper";
- private static final boolean DEBUG = false;
-
- private int mNowPlayingCardWidth;
- private int mNowPlayingCardHeight;
- private int mSpeedLevel;
- private long mProgramDurationMs;
-
- private Activity mActivity;
- private DvrPlayer mDvrPlayer;
- private MediaSession mMediaSession;
- private final DvrWatchedPositionManager mDvrWatchedPositionManager;
- private final ChannelDataManager mChannelDataManager;
-
- public DvrPlaybackMediaSessionHelper(Activity activity, String mediaSessionTag,
- DvrPlayer dvrPlayer, DvrPlaybackOverlayFragment overlayFragment) {
- mActivity = activity;
- mDvrPlayer = dvrPlayer;
- mDvrWatchedPositionManager =
- TvApplication.getSingletons(activity).getDvrWatchedPositionManager();
- mChannelDataManager = TvApplication.getSingletons(activity).getChannelDataManager();
- mDvrPlayer.setCallback(new DvrPlayer.DvrPlayerCallback() {
- @Override
- public void onPlaybackStateChanged(int playbackState, int playbackSpeed) {
- updateMediaSessionPlaybackState();
- }
-
- @Override
- public void onPlaybackPositionChanged(long positionMs) {
- updateMediaSessionPlaybackState();
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrWatchedPositionManager
- .setWatchedPosition(mDvrPlayer.getProgram().getId(), positionMs);
- }
- }
-
- @Override
- public void onPlaybackEnded() {
- // TODO: Deal with watched over recordings in DVR library
- RecordedProgram nextEpisode =
- overlayFragment.getNextEpisode(mDvrPlayer.getProgram());
- if (nextEpisode == null) {
- mDvrPlayer.reset();
- mActivity.finish();
- } else {
- Intent intent = new Intent(activity, DvrPlaybackActivity.class);
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, nextEpisode.getId());
- mActivity.startActivity(intent);
- }
- }
- });
- initializeMediaSession(mediaSessionTag);
- }
-
- /**
- * Stops DVR player and release media session.
- */
- public void release() {
- if (mDvrPlayer != null) {
- mDvrPlayer.reset();
- }
- if (mMediaSession != null) {
- mMediaSession.release();
- mMediaSession = null;
- }
- }
-
- /**
- * Updates media session's playback state and speed.
- */
- public void updateMediaSessionPlaybackState() {
- mMediaSession.setPlaybackState(new PlaybackState.Builder()
- .setState(mDvrPlayer.getPlaybackState(), mDvrPlayer.getPlaybackPosition(),
- mSpeedLevel).build());
- }
-
- /**
- * Sets the recorded program for playback.
- *
- * @param program The recorded program to play. {@code null} to reset the DVR player.
- */
- public void setupPlayback(RecordedProgram program, long seekPositionMs) {
- if (program != null) {
- mDvrPlayer.setProgram(program, seekPositionMs);
- setupMediaSession(program);
- } else {
- mDvrPlayer.reset();
- mMediaSession.setActive(false);
- }
- }
-
- /**
- * Returns the recorded program now playing.
- */
- public RecordedProgram getProgram() {
- return mDvrPlayer.getProgram();
- }
-
- /**
- * Checks if the recorded program is the same as now playing one.
- */
- public boolean isCurrentProgram(RecordedProgram program) {
- return program != null && program.equals(getProgram());
- }
-
- /**
- * Returns playback state.
- */
- public int getPlaybackState() {
- return mDvrPlayer.getPlaybackState();
- }
-
- /**
- * Returns the underlying DVR player.
- */
- public DvrPlayer getDvrPlayer() {
- return mDvrPlayer;
- }
-
- private void initializeMediaSession(String mediaSessionTag) {
- mMediaSession = new MediaSession(mActivity, mediaSessionTag);
- mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS
- | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
- mNowPlayingCardWidth = mActivity.getResources()
- .getDimensionPixelSize(R.dimen.notif_card_img_max_width);
- mNowPlayingCardHeight = mActivity.getResources()
- .getDimensionPixelSize(R.dimen.notif_card_img_height);
- mMediaSession.setCallback(new MediaSessionCallback());
- mActivity.setMediaController(
- new MediaController(mActivity, mMediaSession.getSessionToken()));
- updateMediaSessionPlaybackState();
- }
-
- private void setupMediaSession(RecordedProgram program) {
- mProgramDurationMs = program.getDurationMillis();
- String cardTitleText = program.getTitle();
- if (TextUtils.isEmpty(cardTitleText)) {
- Channel channel = mChannelDataManager.getChannel(program.getChannelId());
- cardTitleText = (channel != null) ? channel.getDisplayName()
- : mActivity.getString(R.string.no_program_information);
- }
- final MediaMetadata currentMetadata = updateMetadataTextInfo(program.getId(), cardTitleText,
- program.getDescription(), mProgramDurationMs);
- String posterArtUri = program.getPosterArtUri();
- if (posterArtUri == null) {
- posterArtUri = TvContract.buildChannelLogoUri(program.getChannelId()).toString();
- }
- updatePosterArt(program, currentMetadata, null, posterArtUri);
- mMediaSession.setActive(true);
- }
-
- private void updatePosterArt(RecordedProgram program, MediaMetadata currentMetadata,
- @Nullable Bitmap posterArt, @Nullable String posterArtUri) {
- if (posterArt != null) {
- updateMetadataImageInfo(program, currentMetadata, posterArt, 0);
- } else if (posterArtUri != null) {
- ImageLoader.loadBitmap(mActivity, posterArtUri, mNowPlayingCardWidth,
- mNowPlayingCardHeight,
- new ProgramPosterArtCallback(mActivity, program, currentMetadata));
- } else {
- updateMetadataImageInfo(program, currentMetadata, null, R.drawable.default_now_card);
- }
- }
-
- private class ProgramPosterArtCallback extends
- ImageLoader.ImageLoaderCallback<Activity> {
- private final RecordedProgram mRecordedProgram;
- private final MediaMetadata mCurrentMetadata;
-
- public ProgramPosterArtCallback(Activity activity, RecordedProgram program,
- MediaMetadata metadata) {
- super(activity);
- mRecordedProgram = program;
- mCurrentMetadata = metadata;
- }
-
- @Override
- public void onBitmapLoaded(Activity activity, @Nullable Bitmap posterArt) {
- if (isCurrentProgram(mRecordedProgram)) {
- updatePosterArt(mRecordedProgram, mCurrentMetadata, posterArt, null);
- }
- }
- }
-
- private MediaMetadata updateMetadataTextInfo(final long programId, final String title,
- final String subtitle, final long duration) {
- MediaMetadata.Builder builder = new MediaMetadata.Builder();
- builder.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, Long.toString(programId))
- .putString(MediaMetadata.METADATA_KEY_TITLE, title)
- .putLong(MediaMetadata.METADATA_KEY_DURATION, duration);
- if (subtitle != null) {
- builder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
- }
- MediaMetadata metadata = builder.build();
- mMediaSession.setMetadata(metadata);
- return metadata;
- }
-
- private void updateMetadataImageInfo(final RecordedProgram program,
- final MediaMetadata currentMetadata, final Bitmap posterArt, final int imageResId) {
- if (mMediaSession != null && (posterArt != null || imageResId != 0)) {
- MediaMetadata.Builder builder = new MediaMetadata.Builder(currentMetadata);
- if (posterArt != null) {
- builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
- mMediaSession.setMetadata(builder.build());
- } else {
- new AsyncTask<Void, Void, Bitmap>() {
- @Override
- protected Bitmap doInBackground(Void... arg0) {
- return BitmapFactory.decodeResource(mActivity.getResources(), imageResId);
- }
-
- @Override
- protected void onPostExecute(Bitmap programPosterArt) {
- if (mMediaSession != null && programPosterArt != null
- && isCurrentProgram(program)) {
- builder.putBitmap(MediaMetadata.METADATA_KEY_ART, programPosterArt);
- mMediaSession.setMetadata(builder.build());
- }
- }
- }.execute();
- }
- }
- }
-
- // An event was triggered by MediaController.TransportControls and must be handled here.
- // Here we update the media itself to act on the event that was triggered.
- private class MediaSessionCallback extends MediaSession.Callback {
- @Override
- public void onPrepare() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.prepare(true);
- }
- }
-
- @Override
- public void onPlay() {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.play();
- }
- }
-
- @Override
- public void onPause() {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.pause();
- }
- }
-
- @Override
- public void onFastForward() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- return;
- }
- if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING) {
- if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
- mSpeedLevel++;
- } else {
- return;
- }
- } else {
- mSpeedLevel = 0;
- }
- mDvrPlayer.fastForward(
- TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
- }
-
- @Override
- public void onRewind() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- return;
- }
- if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_REWINDING) {
- if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
- mSpeedLevel++;
- } else {
- return;
- }
- } else {
- mSpeedLevel = 0;
- }
- mDvrPlayer.rewind(TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
- }
-
- @Override
- public void onSeekTo(long positionMs) {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.seekTo(positionMs);
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
deleted file mode 100644
index e49870f1..00000000
--- a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.dvr.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 android.text.TextUtils;
-import android.transition.Transition;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.util.TvSettings;
-
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Fragment for DVR playback closed-caption/multi-audio settings.
- */
-public class DvrPlaybackSideFragment extends GuidedStepFragment {
- /**
- * The tag for passing track infos to side fragments.
- */
- public static final String TRACK_INFOS = "dvr_key_track_infos";
- /**
- * The tag for passing selected track's ID to side fragments.
- */
- public static final String SELECTED_TRACK_ID = "dvr_key_selected_track_id";
-
- private static final int ACTION_ID_NO_SUBTITLE = -1;
- private static final int CHECK_SET_ID = 1;
-
- private List<TvTrackInfo> mTrackInfos;
- private String mSelectedTrackId;
- private TvTrackInfo mSelectedTrack;
- private int mTrackType;
- private DvrPlaybackOverlayFragment mOverlayFragment;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- mTrackInfos = getArguments().getParcelableArrayList(TRACK_INFOS);
- mTrackType = mTrackInfos.get(0).getType();
- mSelectedTrackId = getArguments().getString(SELECTED_TRACK_ID);
- mOverlayFragment = ((DvrPlaybackOverlayFragment) getFragmentManager()
- .findFragmentById(R.id.dvr_playback_controls_fragment));
- super.onCreate(savedInstanceState);
- }
-
- @Override
- public View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View backgroundView = super.onCreateBackgroundView(inflater, container, savedInstanceState);
- backgroundView.setBackgroundColor(getResources()
- .getColor(R.color.lb_playback_controls_background_light));
- return backgroundView;
- }
-
- @Override
- public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
- if (mTrackType == TvTrackInfo.TYPE_SUBTITLE) {
- actions.add(new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_NO_SUBTITLE)
- .title(getString(R.string.closed_caption_option_item_off))
- .checkSetId(CHECK_SET_ID)
- .checked(mSelectedTrackId == null)
- .build());
- }
- for (int i = 0; i < mTrackInfos.size(); i++) {
- TvTrackInfo info = mTrackInfos.get(i);
- boolean checked = TextUtils.equals(info.getId(), mSelectedTrackId);
- GuidedAction action = new GuidedAction.Builder(getActivity())
- .id(i)
- .title(getTrackLabel(info, i))
- .checkSetId(CHECK_SET_ID)
- .checked(checked)
- .build();
- actions.add(action);
- if (checked) {
- mSelectedTrack = info;
- }
- }
- }
-
- @Override
- public void onGuidedActionFocused(GuidedAction action) {
- int actionId = (int) action.getId();
- mOverlayFragment.selectTrack(mTrackType, actionId < 0 ? null : mTrackInfos.get(actionId));
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- int actionId = (int) action.getId();
- mSelectedTrack = actionId < 0 ? null : mTrackInfos.get(actionId);
- TvSettings.setDvrPlaybackTrackSettings(getContext(), mTrackType, mSelectedTrack);
- getFragmentManager().popBackStack();
- }
-
- @Override
- public void onStart() {
- super.onStart();
- // Workaround: when overlay fragment is faded out, any focus will lost due to overlay
- // fragment's implementation. So we disable overlay fragment's fading here to prevent
- // losing focus while users are interacting with the side fragment.
- mOverlayFragment.setFadingEnabled(false);
- }
-
- @Override
- public void onStop() {
- super.onStop();
- // We disable fading of overlay fragment to prevent side fragment from losing focus,
- // therefore we should resume it here.
- mOverlayFragment.setFadingEnabled(true);
- mOverlayFragment.selectTrack(mTrackType, mSelectedTrack);
- }
-
- private String getTrackLabel(TvTrackInfo track, int trackIndex) {
- if (track.getLanguage() != null) {
- return new Locale(track.getLanguage()).getDisplayName();
- }
- return track.getType() == TvTrackInfo.TYPE_SUBTITLE ?
- getString(R.string.closed_caption_unknown_language, trackIndex + 1)
- : getString(R.string.multi_audio_unknown_language);
- }
-
- @Override
- protected void onProvideFragmentTransitions() {
- super.onProvideFragmentTransitions();
- // Excludes the background scrim from transition to prevent the blinking caused by
- // hiding the overlay fragment and sliding in the side fragment at the same time.
- Transition t = getEnterTransition();
- if (t != null) {
- t.excludeTarget(R.id.guidedstep_background, true);
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
deleted file mode 100644
index 780bfb2f..00000000
--- a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.dvr.ui.playback;
-
-import android.media.PlaybackParams;
-import android.media.tv.TvContentRating;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvTrackInfo;
-import android.media.tv.TvView;
-import android.media.session.PlaybackState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.tv.dvr.data.RecordedProgram;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-class DvrPlayer {
- private static final String TAG = "DvrPlayer";
- private static final boolean DEBUG = false;
-
- /**
- * The max rewinding speed supported by DVR player.
- */
- public static final int MAX_REWIND_SPEED = 256;
- /**
- * The max fast-forwarding speed supported by DVR player.
- */
- public static final int MAX_FAST_FORWARD_SPEED = 256;
-
- private static final long SEEK_POSITION_MARGIN_MS = TimeUnit.SECONDS.toMillis(2);
- private static final long REWIND_POSITION_MARGIN_MS = 32; // Workaround value. b/29994826
-
- private RecordedProgram mProgram;
- private long mInitialSeekPositionMs;
- private final TvView mTvView;
- private DvrPlayerCallback mCallback;
- private OnAspectRatioChangedListener mOnAspectRatioChangedListener;
- private OnContentBlockedListener mOnContentBlockedListener;
- private OnTracksAvailabilityChangedListener mOnTracksAvailabilityChangedListener;
- private OnTrackSelectedListener mOnAudioTrackSelectedListener;
- private OnTrackSelectedListener mOnSubtitleTrackSelectedListener;
- private String mSelectedAudioTrackId;
- private String mSelectedSubtitleTrackId;
- private float mAspectRatio = Float.NaN;
- private int mPlaybackState = PlaybackState.STATE_NONE;
- private long mTimeShiftCurrentPositionMs;
- private boolean mPauseOnPrepared;
- private boolean mHasClosedCaption;
- private boolean mHasMultiAudio;
- private final PlaybackParams mPlaybackParams = new PlaybackParams();
- private final DvrPlayerCallback mEmptyCallback = new DvrPlayerCallback();
- private long mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- private boolean mTimeShiftPlayAvailable;
-
- public static class DvrPlayerCallback {
- /**
- * Called when the playback position is changed. The normal updating frequency is
- * around 1 sec., which is restricted to the implementation of
- * {@link android.media.tv.TvInputService}.
- */
- public void onPlaybackPositionChanged(long positionMs) { }
- /**
- * Called when the playback state or the playback speed is changed.
- */
- public void onPlaybackStateChanged(int playbackState, int playbackSpeed) { }
- /**
- * Called when the playback toward the end.
- */
- public void onPlaybackEnded() { }
- }
-
- public interface OnAspectRatioChangedListener {
- /**
- * Called when the Video's aspect ratio is changed.
- *
- * @param videoAspectRatio The aspect ratio of video. 0 stands for unknown ratios.
- * Listeners should handle it carefully.
- */
- void onAspectRatioChanged(float videoAspectRatio);
- }
-
- public interface OnContentBlockedListener {
- /**
- * Called when the Video's aspect ratio is changed.
- */
- void onContentBlocked(TvContentRating rating);
- }
-
- public interface OnTracksAvailabilityChangedListener {
- /**
- * Called when the Video's subtitle or audio tracks are changed.
- */
- void onTracksAvailabilityChanged(boolean hasClosedCaption, boolean hasMultiAudio);
- }
-
- public interface OnTrackSelectedListener {
- /**
- * Called when certain subtitle or audio track is selected.
- */
- void onTrackSelected(String selectedTrackId);
- }
-
- public DvrPlayer(TvView tvView) {
- mTvView = tvView;
- mTvView.setCaptionEnabled(true);
- mPlaybackParams.setSpeed(1.0f);
- setTvViewCallbacks();
- setCallback(null);
- }
-
- /**
- * Prepares playback.
- *
- * @param doPlay indicates DVR player do or do not start playback after media is prepared.
- */
- public void prepare(boolean doPlay) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "prepare()");
- if (mProgram == null) {
- throw new IllegalStateException("Recorded program not set");
- } else if (mPlaybackState != PlaybackState.STATE_NONE) {
- throw new IllegalStateException("Playback is already prepared");
- }
- mTvView.timeShiftPlay(mProgram.getInputId(), mProgram.getUri());
- mPlaybackState = PlaybackState.STATE_CONNECTING;
- mPauseOnPrepared = !doPlay;
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Resumes playback.
- */
- public void play() throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "play()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or video not ready yet");
- }
- switch (mPlaybackState) {
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- setPlaybackSpeed(1);
- break;
- default:
- mTvView.timeShiftResume();
- }
- mPlaybackState = PlaybackState.STATE_PLAYING;
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Pauses playback.
- */
- public void pause() throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "pause()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- switch (mPlaybackState) {
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- setPlaybackSpeed(1);
- // falls through
- case PlaybackState.STATE_PLAYING:
- mTvView.timeShiftPause();
- mPlaybackState = PlaybackState.STATE_PAUSED;
- break;
- default:
- break;
- }
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Fast-forwards playback with the given speed. If the given speed is larger than
- * {@value #MAX_FAST_FORWARD_SPEED}, uses {@value #MAX_FAST_FORWARD_SPEED}.
- */
- public void fastForward(int speed) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "fastForward()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (speed <= 0) {
- throw new IllegalArgumentException("Speed cannot be negative or 0");
- }
- if (mTimeShiftCurrentPositionMs >= mProgram.getDurationMillis() - SEEK_POSITION_MARGIN_MS) {
- return;
- }
- speed = Math.min(speed, MAX_FAST_FORWARD_SPEED);
- if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
- setPlaybackSpeed(speed);
- mPlaybackState = PlaybackState.STATE_FAST_FORWARDING;
- mCallback.onPlaybackStateChanged(mPlaybackState, speed);
- }
-
- /**
- * Rewinds playback with the given speed. If the given speed is larger than
- * {@value #MAX_REWIND_SPEED}, uses {@value #MAX_REWIND_SPEED}.
- */
- public void rewind(int speed) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "rewind()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (speed <= 0) {
- throw new IllegalArgumentException("Speed cannot be negative or 0");
- }
- if (mTimeShiftCurrentPositionMs <= REWIND_POSITION_MARGIN_MS) {
- return;
- }
- speed = Math.min(speed, MAX_REWIND_SPEED);
- if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
- setPlaybackSpeed(-speed);
- mPlaybackState = PlaybackState.STATE_REWINDING;
- mCallback.onPlaybackStateChanged(mPlaybackState, speed);
- }
-
- /**
- * Seeks playback to the specified position.
- */
- public void seekTo(long positionMs) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "seekTo()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (mProgram == null || mPlaybackState == PlaybackState.STATE_NONE) {
- return;
- }
- positionMs = getRealSeekPosition(positionMs, SEEK_POSITION_MARGIN_MS);
- if (DEBUG) Log.d(TAG, "Now: " + getPlaybackPosition() + ", shift to: " + positionMs);
- mTvView.timeShiftSeekTo(positionMs + mStartPositionMs);
- if (mPlaybackState == PlaybackState.STATE_FAST_FORWARDING ||
- mPlaybackState == PlaybackState.STATE_REWINDING) {
- mPlaybackState = PlaybackState.STATE_PLAYING;
- mTvView.timeShiftResume();
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
- }
-
- /**
- * Resets playback.
- */
- public void reset() {
- if (DEBUG) Log.d(TAG, "reset()");
- mCallback.onPlaybackStateChanged(PlaybackState.STATE_NONE, 1);
- mPlaybackState = PlaybackState.STATE_NONE;
- mTvView.reset();
- mTimeShiftPlayAvailable = false;
- mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- mTimeShiftCurrentPositionMs = 0;
- mPlaybackParams.setSpeed(1.0f);
- mProgram = null;
- mSelectedAudioTrackId = null;
- mSelectedSubtitleTrackId = null;
- }
-
- /**
- * Sets callbacks for playback.
- */
- public void setCallback(DvrPlayerCallback callback) {
- if (callback != null) {
- mCallback = callback;
- } else {
- mCallback = mEmptyCallback;
- }
- }
-
- /**
- * Sets the listener to aspect ratio changing.
- */
- public void setOnAspectRatioChangedListener(OnAspectRatioChangedListener listener) {
- mOnAspectRatioChangedListener = listener;
- }
-
- /**
- * Sets the listener to content blocking.
- */
- public void setOnContentBlockedListener(OnContentBlockedListener listener) {
- mOnContentBlockedListener = listener;
- }
-
- /**
- * Sets the listener to tracks changing.
- */
- public void setOnTracksAvailabilityChangedListener(
- OnTracksAvailabilityChangedListener listener) {
- mOnTracksAvailabilityChangedListener = listener;
- }
-
- /**
- * Sets the listener to tracks of the given type being selected.
- *
- * @param trackType should be either {@link TvTrackInfo#TYPE_AUDIO}
- * or {@link TvTrackInfo#TYPE_SUBTITLE}.
- */
- public void setOnTrackSelectedListener(int trackType, OnTrackSelectedListener listener) {
- if (trackType == TvTrackInfo.TYPE_AUDIO) {
- mOnAudioTrackSelectedListener = listener;
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- mOnSubtitleTrackSelectedListener = listener;
- }
- }
-
- /**
- * Gets the listener to tracks of the given type being selected.
- */
- public OnTrackSelectedListener getOnTrackSelectedListener(int trackType) {
- if (trackType == TvTrackInfo.TYPE_AUDIO) {
- return mOnAudioTrackSelectedListener;
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- return mOnSubtitleTrackSelectedListener;
- }
- return null;
- }
-
- /**
- * Sets recorded programs for playback. If the player is playing another program, stops it.
- */
- public void setProgram(RecordedProgram program, long initialSeekPositionMs) {
- if (mProgram != null && mProgram.equals(program)) {
- return;
- }
- if (mPlaybackState != PlaybackState.STATE_NONE) {
- reset();
- }
- mInitialSeekPositionMs = initialSeekPositionMs;
- mProgram = program;
- }
-
- /**
- * Returns the recorded program now playing.
- */
- public RecordedProgram getProgram() {
- return mProgram;
- }
-
- /**
- * Returns the currrent playback posistion in msecs.
- */
- public long getPlaybackPosition() {
- return mTimeShiftCurrentPositionMs;
- }
-
- /**
- * Returns the playback speed currently used.
- */
- public int getPlaybackSpeed() {
- return (int) mPlaybackParams.getSpeed();
- }
-
- /**
- * Returns the playback state defined in {@link android.media.session.PlaybackState}.
- */
- public int getPlaybackState() {
- return mPlaybackState;
- }
-
- /**
- * Returns the subtitle tracks of the current playback.
- */
- public ArrayList<TvTrackInfo> getSubtitleTracks() {
- return new ArrayList<>(mTvView.getTracks(TvTrackInfo.TYPE_SUBTITLE));
- }
-
- /**
- * Returns the audio tracks of the current playback.
- */
- public ArrayList<TvTrackInfo> getAudioTracks() {
- return new ArrayList<>(mTvView.getTracks(TvTrackInfo.TYPE_AUDIO));
- }
-
- /**
- * Returns the ID of the selected track of the given type.
- */
- public String getSelectedTrackId(int trackType) {
- if (trackType == TvTrackInfo.TYPE_AUDIO) {
- return mSelectedAudioTrackId;
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- return mSelectedSubtitleTrackId;
- }
- return null;
- }
-
- /**
- * Returns if playback of the recorded program is started.
- */
- public boolean isPlaybackPrepared() {
- return mPlaybackState != PlaybackState.STATE_NONE
- && mPlaybackState != PlaybackState.STATE_CONNECTING;
- }
-
- /**
- * Selects the given track.
- *
- * @return ID of the selected track.
- */
- String selectTrack(int trackType, TvTrackInfo selectedTrack) {
- String oldSelectedTrackId = getSelectedTrackId(trackType);
- String newSelectedTrackId = selectedTrack == null ? null : selectedTrack.getId();
- if (!TextUtils.equals(oldSelectedTrackId, newSelectedTrackId)) {
- if (selectedTrack == null) {
- mTvView.selectTrack(trackType, null);
- return null;
- } else {
- List<TvTrackInfo> tracks = mTvView.getTracks(trackType);
- if (tracks != null && tracks.contains(selectedTrack)) {
- mTvView.selectTrack(trackType, newSelectedTrackId);
- return newSelectedTrackId;
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE && oldSelectedTrackId != null) {
- // Track not found, disabled closed caption.
- mTvView.selectTrack(trackType, null);
- return null;
- }
- }
- }
- return oldSelectedTrackId;
- }
-
- private void setSelectedTrackId(int trackType, String trackId) {
- if (trackType == TvTrackInfo.TYPE_AUDIO) {
- mSelectedAudioTrackId = trackId;
- } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
- mSelectedSubtitleTrackId = trackId;
- }
- }
-
- private void setPlaybackSpeed(int speed) {
- mPlaybackParams.setSpeed(speed);
- mTvView.timeShiftSetPlaybackParams(mPlaybackParams);
- }
-
- private long getRealSeekPosition(long seekPositionMs, long endMarginMs) {
- return Math.max(0, Math.min(seekPositionMs, mProgram.getDurationMillis() - endMarginMs));
- }
-
- private void setTvViewCallbacks() {
- mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
- @Override
- public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
- if (DEBUG) Log.d(TAG, "onTimeShiftStartPositionChanged:" + timeMs);
- mStartPositionMs = timeMs;
- if (mTimeShiftPlayAvailable) {
- resumeToWatchedPositionIfNeeded();
- }
- }
-
- @Override
- public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
- if (DEBUG) Log.d(TAG, "onTimeShiftCurrentPositionChanged: " + timeMs);
- if (!mTimeShiftPlayAvailable) {
- // Workaround of b/31436263
- return;
- }
- // Workaround of b/32211561, TIF won't report start position when TIS report
- // its start position as 0. In that case, we have to do the prework of playback
- // on the first time we get current position, and the start position should be 0
- // at that time.
- if (mStartPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mStartPositionMs = 0;
- resumeToWatchedPositionIfNeeded();
- }
- timeMs -= mStartPositionMs;
- if (mPlaybackState == PlaybackState.STATE_REWINDING
- && timeMs <= REWIND_POSITION_MARGIN_MS) {
- play();
- } else {
- mTimeShiftCurrentPositionMs = getRealSeekPosition(timeMs, 0);
- mCallback.onPlaybackPositionChanged(mTimeShiftCurrentPositionMs);
- if (timeMs >= mProgram.getDurationMillis()) {
- pause();
- mCallback.onPlaybackEnded();
- }
- }
- }
- });
- mTvView.setCallback(new TvView.TvInputCallback() {
- @Override
- public void onTimeShiftStatusChanged(String inputId, int status) {
- if (DEBUG) Log.d(TAG, "onTimeShiftStatusChanged:" + status);
- if (status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE
- && mPlaybackState == PlaybackState.STATE_CONNECTING) {
- mTimeShiftPlayAvailable = true;
- if (mStartPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- // onTimeShiftStatusChanged is sometimes called after
- // onTimeShiftStartPositionChanged is called. In this case,
- // resumeToWatchedPositionIfNeeded needs to be called here.
- resumeToWatchedPositionIfNeeded();
- }
- }
- }
-
- @Override
- public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
- boolean hasClosedCaption =
- !mTvView.getTracks(TvTrackInfo.TYPE_SUBTITLE).isEmpty();
- boolean hasMultiAudio = mTvView.getTracks(TvTrackInfo.TYPE_AUDIO).size() > 1;
- if ((hasClosedCaption != mHasClosedCaption || hasMultiAudio != mHasMultiAudio)
- && mOnTracksAvailabilityChangedListener != null) {
- mOnTracksAvailabilityChangedListener
- .onTracksAvailabilityChanged(hasClosedCaption, hasMultiAudio);
- }
- mHasClosedCaption = hasClosedCaption;
- mHasMultiAudio = hasMultiAudio;
- }
-
- @Override
- public void onTrackSelected(String inputId, int type, String trackId) {
- if (type == TvTrackInfo.TYPE_AUDIO || type == TvTrackInfo.TYPE_SUBTITLE) {
- setSelectedTrackId(type, trackId);
- OnTrackSelectedListener listener = getOnTrackSelectedListener(type);
- if (listener != null) {
- listener.onTrackSelected(trackId);
- }
- } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != null
- && mOnAspectRatioChangedListener != null) {
- List<TvTrackInfo> trackInfos = mTvView.getTracks(TvTrackInfo.TYPE_VIDEO);
- if (trackInfos != null) {
- for (TvTrackInfo trackInfo : trackInfos) {
- if (trackInfo.getId().equals(trackId)) {
- float videoAspectRatio;
- int videoWidth = trackInfo.getVideoWidth();
- int videoHeight = trackInfo.getVideoHeight();
- if (videoWidth > 0 && videoHeight > 0) {
- videoAspectRatio = trackInfo.getVideoPixelAspectRatio()
- * trackInfo.getVideoWidth() / trackInfo.getVideoHeight();
- } else {
- // Aspect ratio is unknown. Pass the message to listeners.
- videoAspectRatio = 0;
- }
- if (DEBUG) Log.d(TAG, "Aspect Ratio: " + videoAspectRatio);
- if (mAspectRatio != videoAspectRatio || videoAspectRatio == 0) {
- mOnAspectRatioChangedListener
- .onAspectRatioChanged(videoAspectRatio);
- mAspectRatio = videoAspectRatio;
- return;
- }
- }
- }
- }
- }
- }
-
- @Override
- public void onContentBlocked(String inputId, TvContentRating rating) {
- if (mOnContentBlockedListener != null) {
- mOnContentBlockedListener.onContentBlocked(rating);
- }
- }
- });
- }
-
- private void resumeToWatchedPositionIfNeeded() {
- if (mInitialSeekPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mTvView.timeShiftSeekTo(getRealSeekPosition(mInitialSeekPositionMs,
- SEEK_POSITION_MARGIN_MS) + mStartPositionMs);
- mInitialSeekPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- }
- if (mPauseOnPrepared) {
- mTvView.timeShiftPause();
- mPlaybackState = PlaybackState.STATE_PAUSED;
- mPauseOnPrepared = false;
- } else {
- mTvView.timeShiftResume();
- mPlaybackState = PlaybackState.STATE_PLAYING;
- }
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-} \ No newline at end of file