aboutsummaryrefslogtreecommitdiff
path: root/common/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/com')
-rw-r--r--common/src/com/android/tv/common/CollectionUtils.java56
-rw-r--r--common/src/com/android/tv/common/SharedPreferencesUtils.java16
-rw-r--r--common/src/com/android/tv/common/SoftPreconditions.java17
-rw-r--r--common/src/com/android/tv/common/TvContentRatingCache.java2
-rw-r--r--common/src/com/android/tv/common/feature/CommonFeatures.java20
-rw-r--r--common/src/com/android/tv/common/feature/EngOnlyFeature.java2
-rw-r--r--common/src/com/android/tv/common/feature/Sdk.java4
-rw-r--r--common/src/com/android/tv/common/feature/SharedPreferencesFeature.java4
-rw-r--r--common/src/com/android/tv/common/feature/SystemAppFeature.java34
-rw-r--r--common/src/com/android/tv/common/recording/RecordedProgram.java760
-rw-r--r--common/src/com/android/tv/common/ui/setup/OnActionClickListener.java11
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupActionHelper.java57
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupActivity.java18
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupFragment.java26
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java7
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java26
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java2
-rw-r--r--common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java5
18 files changed, 235 insertions, 832 deletions
diff --git a/common/src/com/android/tv/common/CollectionUtils.java b/common/src/com/android/tv/common/CollectionUtils.java
index f81e51a5..300ad8f2 100644
--- a/common/src/com/android/tv/common/CollectionUtils.java
+++ b/common/src/com/android/tv/common/CollectionUtils.java
@@ -16,7 +16,12 @@
package com.android.tv.common;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* Static utilities for collections
@@ -42,4 +47,55 @@ public class CollectionUtils {
}
return result;
}
+
+ /**
+ * Unions the two collections and returns the unified list.
+ * <p>
+ * The elements is not compared with hashcode() or equals(). Comparator is used for the equality
+ * check.
+ */
+ public static <T> List<T> union(Collection<T> originals, Collection<T> toAdds,
+ Comparator<T> comparator) {
+ List<T> result = new ArrayList<>(originals);
+ Collections.sort(result, comparator);
+ List<T> resultToAdd = new ArrayList<>();
+ for (T toAdd : toAdds) {
+ if (Collections.binarySearch(result, toAdd, comparator) < 0) {
+ resultToAdd.add(toAdd);
+ }
+ }
+ result.addAll(resultToAdd);
+ return result;
+ }
+
+ /**
+ * Subtracts the elements from the original collection.
+ */
+ public static <T> List<T> subtract(Collection<T> originals, T[] toSubtracts,
+ Comparator<T> comparator) {
+ List<T> result = new ArrayList<>(originals);
+ Collections.sort(result, comparator);
+ for (T toSubtract : toSubtracts) {
+ int index = Collections.binarySearch(result, toSubtract, comparator);
+ if (index >= 0) {
+ result.remove(index);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns {@code true} if the two specified collections have common elements.
+ */
+ public static <T> boolean containsAny(Collection<T> c1, Collection<T> c2,
+ Comparator<T> comparator) {
+ List<T> contains = new ArrayList<>(c1);
+ Collections.sort(contains, comparator);
+ for (T iterate : c2) {
+ if (Collections.binarySearch(contains, iterate, comparator) >= 0) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/common/src/com/android/tv/common/SharedPreferencesUtils.java b/common/src/com/android/tv/common/SharedPreferencesUtils.java
index 38daa963..fb3d9b56 100644
--- a/common/src/com/android/tv/common/SharedPreferencesUtils.java
+++ b/common/src/com/android/tv/common/SharedPreferencesUtils.java
@@ -28,9 +28,13 @@ public final class SharedPreferencesUtils {
public static final String SHARED_PREF_FEATURES = "sharePreferencesFeatures";
public static final String SHARED_PREF_BROWSABLE = "browsable_shared_preference";
public static final String SHARED_PREF_WATCHED_HISTORY = "watched_history_shared_preference";
+ public static final String SHARED_PREF_DVR_WATCHED_POSITION =
+ "dvr_watched_position_shared_preference";
public static final String SHARED_PREF_AUDIO_CAPABILITIES =
"com.android.tv.audio_capabilities";
public static final String SHARED_PREF_RECURRING_RUNNER = "sharedPreferencesRecurringRunner";
+ public static final String SHARED_PREF_EPG = "epg_preferences";
+ public static final String SHARED_PREF_SERIES_RECORDINGS = "seriesRecordings";
private static boolean sInitializeCalled;
@@ -40,7 +44,7 @@ public final class SharedPreferencesUtils {
* Call {@link Context#getSharedPreferences(String, int)} as early as possible to avoid the ANR
* due to the file loading.
*/
- public static synchronized void initialize(final Context context) {
+ public static synchronized void initialize(final Context context, final Runnable postTask) {
if (!sInitializeCalled) {
sInitializeCalled = true;
new AsyncTask<Void, Void, Void>() {
@@ -50,12 +54,22 @@ public final class SharedPreferencesUtils {
context.getSharedPreferences(SHARED_PREF_FEATURES, Context.MODE_PRIVATE);
context.getSharedPreferences(SHARED_PREF_BROWSABLE, Context.MODE_PRIVATE);
context.getSharedPreferences(SHARED_PREF_WATCHED_HISTORY, Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_DVR_WATCHED_POSITION,
+ Context.MODE_PRIVATE);
context.getSharedPreferences(SHARED_PREF_AUDIO_CAPABILITIES,
Context.MODE_PRIVATE);
context.getSharedPreferences(SHARED_PREF_RECURRING_RUNNER,
Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_EPG, Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_SERIES_RECORDINGS,
+ Context.MODE_PRIVATE);
return null;
}
+
+ @Override
+ protected void onPostExecute(Void result) {
+ postTask.run();
+ }
}.execute();
}
}
diff --git a/common/src/com/android/tv/common/SoftPreconditions.java b/common/src/com/android/tv/common/SoftPreconditions.java
index 9b7713f6..823c42ff 100644
--- a/common/src/com/android/tv/common/SoftPreconditions.java
+++ b/common/src/com/android/tv/common/SoftPreconditions.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.common.BuildConfig;
import com.android.tv.common.feature.Feature;
/**
@@ -43,12 +42,14 @@ public final class SoftPreconditions {
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
+ * @return the evaluation result of the boolean expression
* @throws IllegalArgumentException if {@code expression} is true
*/
- public static void checkArgument(final boolean expression, String tag, String msg) {
+ public static boolean checkArgument(final boolean expression, String tag, String msg) {
if (!expression) {
warn(tag, "Illegal argument", msg, new IllegalArgumentException(msg));
}
+ return expression;
}
/**
@@ -56,10 +57,12 @@ public final class SoftPreconditions {
* method is not true.
*
* @param expression a boolean expression
+ * @return the evaluation result of the boolean expression
* @throws IllegalArgumentException if {@code expression} is true
*/
- public static void checkArgument(final boolean expression) {
+ public static boolean checkArgument(final boolean expression) {
checkArgument(expression, null, null);
+ return expression;
}
/**
@@ -98,12 +101,14 @@ public final class SoftPreconditions {
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
+ * @return the evaluation result of the boolean expression
* @throws IllegalStateException if {@code expression} is true
*/
- public static void checkState(final boolean expression, String tag, String msg) {
+ public static boolean checkState(final boolean expression, String tag, String msg) {
if (!expression) {
warn(tag, "Illegal State", msg, new IllegalStateException(msg));
}
+ return expression;
}
/**
@@ -111,10 +116,12 @@ public final class SoftPreconditions {
* instance, but not involving any parameters to the calling method is not true.
*
* @param expression a boolean expression
+ * @return the evaluation result of the boolean expression
* @throws IllegalStateException if {@code expression} is true
*/
- public static void checkState(final boolean expression) {
+ public static boolean checkState(final boolean expression) {
checkState(expression, null, null);
+ return expression;
}
/**
diff --git a/common/src/com/android/tv/common/TvContentRatingCache.java b/common/src/com/android/tv/common/TvContentRatingCache.java
index 7ea86287..5694cda7 100644
--- a/common/src/com/android/tv/common/TvContentRatingCache.java
+++ b/common/src/com/android/tv/common/TvContentRatingCache.java
@@ -39,7 +39,7 @@ public final class TvContentRatingCache implements MemoryManageable {
private final static TvContentRatingCache INSTANCE = new TvContentRatingCache();
- public final static TvContentRatingCache getInstance() {
+ public static TvContentRatingCache getInstance() {
return INSTANCE;
}
diff --git a/common/src/com/android/tv/common/feature/CommonFeatures.java b/common/src/com/android/tv/common/feature/CommonFeatures.java
index 9925833f..d47aa603 100644
--- a/common/src/com/android/tv/common/feature/CommonFeatures.java
+++ b/common/src/com/android/tv/common/feature/CommonFeatures.java
@@ -16,7 +16,7 @@
package com.android.tv.common.feature;
-import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
+import static com.android.tv.common.feature.FeatureUtils.AND;
import static com.android.tv.common.feature.FeatureUtils.OR;
import static com.android.tv.common.feature.TestableFeature.createTestableFeature;
@@ -30,14 +30,26 @@ public class CommonFeatures {
* DVR
*
* <p>See <a href="https://goto.google.com/atv-dvr-onepager">go/atv-dvr-onepager</a>
+ *
+ * DVR API is introduced in N, it only works when app runs as a system app.
+ */
+ public static final TestableFeature DVR = createTestableFeature(
+ AND(OR(Sdk.N_PRE_2_OR_HIGHER, Sdk.AT_LEAST_N), SystemAppFeature.SYSTEM_APP_FEATURE));
+
+ /**
+ * ENABLE_RECORDING_REGARDLESS_OF_STORAGE_STATUS
+ *
+ * Enables dvr recording regardless of storage status.
*/
- public static TestableFeature DVR = createTestableFeature(
- OR(ENG_ONLY_FEATURE, Sdk.N_PRE_2_OR_HIGHER));
+ public static final Feature FORCE_RECORDING_UNTIL_NO_SPACE =
+ new PropertyFeature("force_recording_until_no_space", false);
/**
* USE_SW_CODEC_FOR_SD
*
* Prefer software based codec for SD channels.
*/
- public static Feature USE_SW_CODEC_FOR_SD = new PropertyFeature("use_sw_codec_for_sd", true);
+ public static final Feature USE_SW_CODEC_FOR_SD =
+ new PropertyFeature("use_sw_codec_for_sd", false
+ );
}
diff --git a/common/src/com/android/tv/common/feature/EngOnlyFeature.java b/common/src/com/android/tv/common/feature/EngOnlyFeature.java
index 14d2b49b..9fc39d9f 100644
--- a/common/src/com/android/tv/common/feature/EngOnlyFeature.java
+++ b/common/src/com/android/tv/common/feature/EngOnlyFeature.java
@@ -24,7 +24,7 @@ import com.android.tv.common.BuildConfig;
* A feature that is only available on {@link BuildConfig#ENG} builds.
*/
public final class EngOnlyFeature implements Feature {
- public static Feature ENG_ONLY_FEATURE = new EngOnlyFeature();
+ public static final Feature ENG_ONLY_FEATURE = new EngOnlyFeature();
private EngOnlyFeature() { }
diff --git a/common/src/com/android/tv/common/feature/Sdk.java b/common/src/com/android/tv/common/feature/Sdk.java
index 268eaea7..46a681f8 100644
--- a/common/src/com/android/tv/common/feature/Sdk.java
+++ b/common/src/com/android/tv/common/feature/Sdk.java
@@ -25,7 +25,7 @@ import android.support.v4.os.BuildCompat;
*/
public class Sdk {
- public static Feature N_PRE_2_OR_HIGHER =
+ public static final Feature N_PRE_2_OR_HIGHER =
new SdkPreviewVersionFeature(Build.VERSION_CODES.M, 2, true);
private static class SdkPreviewVersionFeature implements Feature {
@@ -56,7 +56,7 @@ public class Sdk {
}
}
- public static Feature AT_LEAST_N = new Feature() {
+ public static final Feature AT_LEAST_N = new Feature() {
@Override
public boolean isEnabled(Context context) {
return BuildCompat.isAtLeastN();
diff --git a/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java b/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
index 4d3a70a8..a4a79b38 100644
--- a/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
+++ b/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
@@ -29,9 +29,9 @@ public final class SharedPreferencesFeature implements Feature {
private static final String TAG = "SharedPrefFeature";
private static final boolean DEBUG = false;
- private String mKey;
+ private final String mKey;
private boolean mEnabled;
- private boolean mDefaultValue;
+ private final boolean mDefaultValue;
private SharedPreferences mSharedPreferences;
private final Feature mBaseFeature;
diff --git a/common/src/com/android/tv/common/feature/SystemAppFeature.java b/common/src/com/android/tv/common/feature/SystemAppFeature.java
new file mode 100644
index 00000000..79fd32f3
--- /dev/null
+++ b/common/src/com/android/tv/common/feature/SystemAppFeature.java
@@ -0,0 +1,34 @@
+/*
+ * 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.common.feature;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+
+/**
+ * A feature that is for system App.
+ */
+public final class SystemAppFeature implements Feature {
+ public static final Feature SYSTEM_APP_FEATURE = new SystemAppFeature();
+
+ private SystemAppFeature() { }
+
+ @Override
+ public boolean isEnabled(Context context) {
+ return (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+}
diff --git a/common/src/com/android/tv/common/recording/RecordedProgram.java b/common/src/com/android/tv/common/recording/RecordedProgram.java
deleted file mode 100644
index 63ce6ff9..00000000
--- a/common/src/com/android/tv/common/recording/RecordedProgram.java
+++ /dev/null
@@ -1,760 +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.common.recording;
-
-import static android.media.tv.TvContract.RecordedPrograms;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.media.tv.TvContract;
-import android.net.Uri;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.common.R;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * Immutable instance of {@link android.media.tv.TvContract.RecordedPrograms}.
- */
-public class RecordedProgram {
- public static final int ID_NOT_SET = -1;
-
- public final static String[] PROJECTION = {
- // These are in exactly the order listed in RecordedPrograms
- RecordedPrograms._ID,
- RecordedPrograms.COLUMN_INPUT_ID,
- RecordedPrograms.COLUMN_CHANNEL_ID,
- RecordedPrograms.COLUMN_TITLE,
- RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
- RecordedPrograms.COLUMN_SEASON_TITLE,
- RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
- RecordedPrograms.COLUMN_EPISODE_TITLE,
- RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_BROADCAST_GENRE,
- RecordedPrograms.COLUMN_CANONICAL_GENRE,
- RecordedPrograms.COLUMN_SHORT_DESCRIPTION,
- RecordedPrograms.COLUMN_LONG_DESCRIPTION,
- RecordedPrograms.COLUMN_VIDEO_WIDTH,
- RecordedPrograms.COLUMN_VIDEO_HEIGHT,
- RecordedPrograms.COLUMN_AUDIO_LANGUAGE,
- RecordedPrograms.COLUMN_CONTENT_RATING,
- RecordedPrograms.COLUMN_POSTER_ART_URI,
- RecordedPrograms.COLUMN_THUMBNAIL_URI,
- RecordedPrograms.COLUMN_SEARCHABLE,
- RecordedPrograms.COLUMN_RECORDING_DATA_URI,
- RecordedPrograms.COLUMN_RECORDING_DATA_BYTES,
- RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
- RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
- RecordedPrograms.COLUMN_VERSION_NUMBER,
- };
-
- public static final RecordedProgram fromCursor(Cursor cursor) {
- int index = 0;
- return builder()
- .setId(cursor.getLong(index++))
- .setInputId(cursor.getString(index++))
- .setChannelId(cursor.getLong(index++))
- .setTitle(cursor.getString(index++))
- .setSeasonNumber(cursor.getString(index++))
- .setSeasonTitle(cursor.getString(index++))
- .setEpisodeNumber(cursor.getString(index++))
- .setEpisodeTitle(cursor.getString(index++))
- .setStartTimeUtcMillis(cursor.getLong(index++))
- .setEndTimeUtcMillis(cursor.getLong(index++))
- .setBroadcastGenres(cursor.getString(index++))
- .setCanonicalGenres(cursor.getString(index++))
- .setShortDescription(cursor.getString(index++))
- .setLongDescription(cursor.getString(index++))
- .setVideoWidth(cursor.getInt(index++))
- .setVideoHeight(cursor.getInt(index++))
- .setAudioLanguage(cursor.getString(index++))
- .setContentRating(cursor.getString(index++))
- .setPosterArt(cursor.getString(index++))
- .setThumbnail(cursor.getString(index++))
- .setSearchable(cursor.getInt(index++) == 1)
- .setDataUri(cursor.getString(index++))
- .setDataBytes(cursor.getLong(index++))
- .setDurationMillis(cursor.getLong(index++))
- .setExpireTimeUtcMillis(cursor.getLong(index++))
- .setInternalProviderData(cursor.getBlob(index++))
- .setInternalProviderFlag1(cursor.getInt(index++))
- .setInternalProviderFlag2(cursor.getInt(index++))
- .setInternalProviderFlag3(cursor.getInt(index++))
- .setInternalProviderFlag4(cursor.getInt(index++))
- .setVersionNumber(cursor.getInt(index++))
- .build();
- }
-
- public static ContentValues toValues(RecordedProgram recordedProgram) {
- ContentValues values = new ContentValues();
- if (recordedProgram.mId != ID_NOT_SET) {
- values.put(RecordedPrograms._ID, recordedProgram.mId);
- }
- values.put(RecordedPrograms.COLUMN_INPUT_ID, recordedProgram.mInputId);
- values.put(RecordedPrograms.COLUMN_CHANNEL_ID, recordedProgram.mChannelId);
- values.put(RecordedPrograms.COLUMN_TITLE, recordedProgram.mTitle);
- values.put(RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER, recordedProgram.mSeasonNumber);
- values.put(RecordedPrograms.COLUMN_SEASON_TITLE, recordedProgram.mSeasonTitle);
- values.put(RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER, recordedProgram.mEpisodeNumber);
- values.put(RecordedPrograms.COLUMN_EPISODE_TITLE, recordedProgram.mTitle);
- values.put(RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
- recordedProgram.mStartTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, recordedProgram.mEndTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_BROADCAST_GENRE,
- safeEncode(recordedProgram.mBroadcastGenres));
- values.put(RecordedPrograms.COLUMN_CANONICAL_GENRE,
- safeEncode(recordedProgram.mCanonicalGenres));
- values.put(RecordedPrograms.COLUMN_SHORT_DESCRIPTION, recordedProgram.mShortDescription);
- values.put(RecordedPrograms.COLUMN_LONG_DESCRIPTION, recordedProgram.mLongDescription);
- if (recordedProgram.mVideoWidth == 0) {
- values.putNull(RecordedPrograms.COLUMN_VIDEO_WIDTH);
- } else {
- values.put(RecordedPrograms.COLUMN_VIDEO_WIDTH, recordedProgram.mVideoWidth);
- }
- if (recordedProgram.mVideoHeight == 0) {
- values.putNull(RecordedPrograms.COLUMN_VIDEO_HEIGHT);
- } else {
- values.put(RecordedPrograms.COLUMN_VIDEO_HEIGHT, recordedProgram.mVideoHeight);
- }
- values.put(RecordedPrograms.COLUMN_AUDIO_LANGUAGE, recordedProgram.mAudioLanguage);
- values.put(RecordedPrograms.COLUMN_CONTENT_RATING, recordedProgram.mContentRating);
- values.put(RecordedPrograms.COLUMN_POSTER_ART_URI,
- safeToString(recordedProgram.mPosterArt));
- values.put(RecordedPrograms.COLUMN_THUMBNAIL_URI, safeToString(recordedProgram.mThumbnail));
- values.put(RecordedPrograms.COLUMN_SEARCHABLE, recordedProgram.mSearchable ? 1 : 0);
- values.put(RecordedPrograms.COLUMN_RECORDING_DATA_URI,
- safeToString(recordedProgram.mDataUri));
- values.put(RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, recordedProgram.mDataBytes);
- values.put(RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
- recordedProgram.mDurationMillis);
- values.put(RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
- recordedProgram.mExpireTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
- recordedProgram.mInternalProviderData);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
- recordedProgram.mInternalProviderFlag1);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
- recordedProgram.mInternalProviderFlag2);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
- recordedProgram.mInternalProviderFlag3);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
- recordedProgram.mInternalProviderFlag4);
- values.put(RecordedPrograms.COLUMN_VERSION_NUMBER, recordedProgram.mVersionNumber);
- return values;
- }
-
- public static class Builder{
- private long mId = ID_NOT_SET;
- private String mInputId;
- private long mChannelId;
- private String mTitle;
- private String mSeasonNumber;
- private String mSeasonTitle;
- private String mEpisodeNumber;
- private String mEpisodeTitle;
- private long mStartTimeUtcMillis;
- private long mEndTimeUtcMillis;
- private String[] mBroadcastGenres;
- private String[] mCanonicalGenres;
- private String mShortDescription;
- private String mLongDescription;
- private int mVideoWidth;
- private int mVideoHeight;
- private String mAudioLanguage;
- private String mContentRating;
- private Uri mPosterArt;
- private Uri mThumbnail;
- private boolean mSearchable = true;
- private Uri mDataUri;
- private long mDataBytes;
- private long mDurationMillis;
- private long mExpireTimeUtcMillis;
- private byte[] mInternalProviderData;
- private int mInternalProviderFlag1;
- private int mInternalProviderFlag2;
- private int mInternalProviderFlag3;
- private int mInternalProviderFlag4;
- private int mVersionNumber;
-
- public Builder setId(long id) {
- mId = id;
- return this;
- }
-
- public Builder setInputId(String inputId) {
- mInputId = inputId;
- return this;
- }
-
- public Builder setChannelId(long channelId) {
- mChannelId = channelId;
- return this;
- }
-
- public Builder setTitle(String title) {
- mTitle = title;
- return this;
- }
-
- public Builder setSeasonNumber(String seasonNumber) {
- mSeasonNumber = seasonNumber;
- return this;
- }
-
- public Builder setSeasonTitle(String seasonTitle) {
- mSeasonTitle = seasonTitle;
- return this;
- }
-
- public Builder setEpisodeNumber(String episodeNumber) {
- mEpisodeNumber = episodeNumber;
- return this;
- }
-
- public Builder setEpisodeTitle(String episodeTitle) {
- mEpisodeTitle = episodeTitle;
- return this;
- }
-
- public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
- mStartTimeUtcMillis = startTimeUtcMillis;
- return this;
- }
-
- public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
- mEndTimeUtcMillis = endTimeUtcMillis;
- return this;
- }
-
- public Builder setBroadcastGenres(String broadcastGenres) {
- if (TextUtils.isEmpty(broadcastGenres)) {
- mBroadcastGenres = null;
- return this;
- }
- return setBroadcastGenres(TvContract.Programs.Genres.decode(broadcastGenres));
- }
-
- private Builder setBroadcastGenres(String[] broadcastGenres) {
- mBroadcastGenres = broadcastGenres;
- return this;
- }
-
- public Builder setCanonicalGenres(String canonicalGenres) {
- if (TextUtils.isEmpty(canonicalGenres)) {
- mCanonicalGenres = null;
- return this;
- }
- return setCanonicalGenres(TvContract.Programs.Genres.decode(canonicalGenres));
- }
-
- private Builder setCanonicalGenres(String[] canonicalGenres) {
- mCanonicalGenres = canonicalGenres;
- return this;
- }
-
- public Builder setShortDescription(String shortDescription) {
- mShortDescription = shortDescription;
- return this;
- }
-
- public Builder setLongDescription(String longDescription) {
- mLongDescription = longDescription;
- return this;
- }
-
- public Builder setVideoWidth(int videoWidth) {
- mVideoWidth = videoWidth;
- return this;
- }
-
- public Builder setVideoHeight(int videoHeight) {
- mVideoHeight = videoHeight;
- return this;
- }
-
- public Builder setAudioLanguage(String audioLanguage) {
- mAudioLanguage = audioLanguage;
- return this;
- }
-
- public Builder setContentRating(String contentRating) {
- mContentRating = contentRating;
- return this;
- }
-
- private Uri toUri(String uriString) {
- try {
- return uriString == null ? null : Uri.parse(uriString);
- } catch (Exception e) {
- return null;
- }
- }
-
- public Builder setPosterArt(String posterArtUri) {
- return setPosterArt(toUri(posterArtUri));
- }
-
- public Builder setPosterArt(Uri posterArt) {
- mPosterArt = posterArt;
- return this;
- }
-
- public Builder setThumbnail(String thumbnailUri) {
- return setThumbnail(toUri(thumbnailUri));
- }
-
- public Builder setThumbnail(Uri thumbnail) {
- mThumbnail = thumbnail;
- return this;
- }
-
- public Builder setSearchable(boolean searchable) {
- mSearchable = searchable;
- return this;
- }
-
- public Builder setDataUri(String dataUri) {
- return setDataUri(toUri(dataUri));
- }
-
- public Builder setDataUri(Uri dataUri) {
- mDataUri = dataUri;
- return this;
- }
-
- public Builder setDataBytes(long dataBytes) {
- mDataBytes = dataBytes;
- return this;
- }
-
- public Builder setDurationMillis(long durationMillis) {
- mDurationMillis = durationMillis;
- return this;
- }
-
- public Builder setExpireTimeUtcMillis(long expireTimeUtcMillis) {
- mExpireTimeUtcMillis = expireTimeUtcMillis;
- return this;
- }
-
- public Builder setInternalProviderData(byte[] internalProviderData) {
- mInternalProviderData = internalProviderData;
- return this;
- }
-
- public Builder setInternalProviderFlag1(int internalProviderFlag1) {
- mInternalProviderFlag1 = internalProviderFlag1;
- return this;
- }
-
- public Builder setInternalProviderFlag2(int internalProviderFlag2) {
- mInternalProviderFlag2 = internalProviderFlag2;
- return this;
- }
-
- public Builder setInternalProviderFlag3(int internalProviderFlag3) {
- mInternalProviderFlag3 = internalProviderFlag3;
- return this;
- }
-
- public Builder setInternalProviderFlag4(int internalProviderFlag4) {
- mInternalProviderFlag4 = internalProviderFlag4;
- return this;
- }
-
- public Builder setVersionNumber(int versionNumber) {
- mVersionNumber = versionNumber;
- return this;
- }
-
- public RecordedProgram build() {
- return new RecordedProgram(mId, mInputId, mChannelId, mTitle, mSeasonNumber,
- mSeasonTitle, mEpisodeNumber, mEpisodeTitle, mStartTimeUtcMillis,
- mEndTimeUtcMillis, mBroadcastGenres, mCanonicalGenres, mShortDescription,
- mLongDescription, mVideoWidth, mVideoHeight, mAudioLanguage, mContentRating,
- mPosterArt, mThumbnail, mSearchable, mDataUri, mDataBytes, mDurationMillis,
- mExpireTimeUtcMillis, mInternalProviderData, mInternalProviderFlag1,
- mInternalProviderFlag2, mInternalProviderFlag3, mInternalProviderFlag4,
- mVersionNumber);
- }
- }
-
- public static Builder builder() { return new Builder(); }
-
- public static Builder buildFrom(RecordedProgram orig) {
- return builder()
- .setId(orig.getId())
- .setInputId(orig.getInputId())
- .setChannelId(orig.getChannelId())
- .setTitle(orig.getTitle())
- .setSeasonNumber(orig.getSeasonNumber())
- .setSeasonTitle(orig.getSeasonTitle())
- .setEpisodeNumber(orig.getEpisodeNumber())
- .setEpisodeTitle(orig.getEpisodeTitle())
- .setStartTimeUtcMillis(orig.getStartTimeUtcMillis())
- .setEndTimeUtcMillis(orig.getEndTimeUtcMillis())
- .setBroadcastGenres(orig.getBroadcastGenres())
- .setCanonicalGenres(orig.getCanonicalGenres())
- .setShortDescription(orig.getShortDescription())
- .setLongDescription(orig.getLongDescription())
- .setVideoWidth(orig.getVideoWidth())
- .setVideoHeight(orig.getVideoHeight())
- .setAudioLanguage(orig.getAudioLanguage())
- .setContentRating(orig.getContentRating())
- .setPosterArt(orig.getPosterArt())
- .setThumbnail(orig.getThumbnail())
- .setSearchable(orig.isSearchable())
- .setInternalProviderData(orig.getInternalProviderData())
- .setInternalProviderFlag1(orig.getInternalProviderFlag1())
- .setInternalProviderFlag2(orig.getInternalProviderFlag2())
- .setInternalProviderFlag3(orig.getInternalProviderFlag3())
- .setInternalProviderFlag4(orig.getInternalProviderFlag4())
- .setVersionNumber(orig.getVersionNumber());
- }
-
- public static final Comparator<RecordedProgram> START_TIME_THEN_ID_COMPARATOR
- = new Comparator<RecordedProgram>() {
- @Override
- public int compare(RecordedProgram lhs, RecordedProgram rhs) {
- int res = Long.compare(lhs.getStartTimeUtcMillis(), rhs.getStartTimeUtcMillis());
- if (res != 0) {
- return res;
- }
- return Long.compare(lhs.mId, rhs.mId);
- }
- };
-
- private final long mId;
- private final String mInputId;
- private final long mChannelId;
- private final String mTitle;
- private final String mSeasonNumber;
- private final String mSeasonTitle;
- private final String mEpisodeNumber;
- private final String mEpisodeTitle;
- private final long mStartTimeUtcMillis;
- private final long mEndTimeUtcMillis;
- private final String[] mBroadcastGenres;
- private final String[] mCanonicalGenres;
- private final String mShortDescription;
- private final String mLongDescription;
- private final int mVideoWidth;
- private final int mVideoHeight;
- private final String mAudioLanguage;
- private final String mContentRating;
- private final Uri mPosterArt;
- private final Uri mThumbnail;
- private final boolean mSearchable;
- private final Uri mDataUri;
- private final long mDataBytes;
- private final long mDurationMillis;
- private final long mExpireTimeUtcMillis;
- private final byte[] mInternalProviderData;
- private final int mInternalProviderFlag1;
- private final int mInternalProviderFlag2;
- private final int mInternalProviderFlag3;
- private final int mInternalProviderFlag4;
- private final int mVersionNumber;
-
- private RecordedProgram(long id, String inputId, long channelId, String title,
- String seasonNumber, String seasonTitle, String episodeNumber, String episodeTitle,
- long startTimeUtcMillis, long endTimeUtcMillis, String[] broadcastGenres,
- String[] canonicalGenres, String shortDescription, String longDescription,
- int videoWidth, int videoHeight, String audioLanguage, String contentRating,
- Uri posterArt, Uri thumbnail, boolean searchable, Uri dataUri, long dataBytes,
- long durationMillis, long expireTimeUtcMillis, byte[] internalProviderData,
- int internalProviderFlag1, int internalProviderFlag2, int internalProviderFlag3,
- int internalProviderFlag4, int versionNumber) {
- mId = id;
- mInputId = inputId;
- mChannelId = channelId;
- mTitle = title;
- mSeasonNumber = seasonNumber;
- mSeasonTitle = seasonTitle;
- mEpisodeNumber = episodeNumber;
- mEpisodeTitle = episodeTitle;
- mStartTimeUtcMillis = startTimeUtcMillis;
- mEndTimeUtcMillis = endTimeUtcMillis;
- mBroadcastGenres = broadcastGenres;
- mCanonicalGenres = canonicalGenres;
- mShortDescription = shortDescription;
- mLongDescription = longDescription;
- mVideoWidth = videoWidth;
- mVideoHeight = videoHeight;
-
- mAudioLanguage = audioLanguage;
- mContentRating = contentRating;
- mPosterArt = posterArt;
- mThumbnail = thumbnail;
- mSearchable = searchable;
- mDataUri = dataUri;
- mDataBytes = dataBytes;
- mDurationMillis = durationMillis;
- mExpireTimeUtcMillis = expireTimeUtcMillis;
- mInternalProviderData = internalProviderData;
- mInternalProviderFlag1 = internalProviderFlag1;
- mInternalProviderFlag2 = internalProviderFlag2;
- mInternalProviderFlag3 = internalProviderFlag3;
- mInternalProviderFlag4 = internalProviderFlag4;
- mVersionNumber = versionNumber;
- }
-
- public String getAudioLanguage() {
- return mAudioLanguage;
- }
-
- public String[] getBroadcastGenres() {
- return mBroadcastGenres;
- }
-
- public String[] getCanonicalGenres() {
- return mCanonicalGenres;
- }
-
- public long getChannelId() {
- return mChannelId;
- }
-
- public String getContentRating() {
- return mContentRating;
- }
-
- public Uri getDataUri() {
- return mDataUri;
- }
-
- public long getDataBytes() {
- return mDataBytes;
- }
-
- public long getDurationMillis() {
- return mDurationMillis;
- }
-
- public long getEndTimeUtcMillis() {
- return mEndTimeUtcMillis;
- }
-
- public String getEpisodeNumber() {
- return mEpisodeNumber;
- }
-
- public String getEpisodeTitle() {
- return mEpisodeTitle;
- }
-
- public String getEpisodeDisplayTitle(Context context) {
- if (!TextUtils.isEmpty(mSeasonNumber) && !TextUtils.isEmpty(mEpisodeNumber)
- && !TextUtils.isEmpty(mEpisodeTitle)) {
- return String.format(context.getResources().getString(R.string.episode_format),
- mSeasonNumber, mEpisodeNumber, mEpisodeTitle);
- }
- return mEpisodeTitle;
- }
-
- public long getExpireTimeUtcMillis() {
- return mExpireTimeUtcMillis;
- }
-
- public long getId() {
- return mId;
- }
-
- public String getInputId() {
- return mInputId;
- }
-
- public byte[] getInternalProviderData() {
- return mInternalProviderData;
- }
-
- public int getInternalProviderFlag1() {
- return mInternalProviderFlag1;
- }
-
- public int getInternalProviderFlag2() {
- return mInternalProviderFlag2;
- }
-
- public int getInternalProviderFlag3() {
- return mInternalProviderFlag3;
- }
-
- public int getInternalProviderFlag4() {
- return mInternalProviderFlag4;
- }
-
- public String getLongDescription() {
- return mLongDescription;
- }
-
- public Uri getPosterArt() {
- return mPosterArt;
- }
-
- public boolean isSearchable() {
- return mSearchable;
- }
-
- public String getSeasonNumber() {
- return mSeasonNumber;
- }
-
- public String getSeasonTitle() {
- return mSeasonTitle;
- }
-
- public String getShortDescription() {
- return mShortDescription;
- }
-
- public long getStartTimeUtcMillis() {
- return mStartTimeUtcMillis;
- }
-
- public Uri getThumbnail() {
- return mThumbnail;
- }
-
- public String getTitle() {
- return mTitle;
- }
-
- public Uri getUri() {
- return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, mId);
- }
-
- public int getVersionNumber() {
- return mVersionNumber;
- }
-
- public int getVideoHeight() {
- return mVideoHeight;
- }
-
- public int getVideoWidth() {
- return mVideoWidth;
- }
-
- /**
- * Compares everything except {@link #getInternalProviderData()}
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- RecordedProgram that = (RecordedProgram) o;
- return Objects.equals(mId, that.mId) &&
- Objects.equals(mChannelId, that.mChannelId) &&
- Objects.equals(mSeasonNumber, that.mSeasonNumber) &&
- Objects.equals(mSeasonTitle, that.mSeasonTitle) &&
- Objects.equals(mEpisodeNumber, that.mEpisodeNumber) &&
- Objects.equals(mStartTimeUtcMillis, that.mStartTimeUtcMillis) &&
- Objects.equals(mEndTimeUtcMillis, that.mEndTimeUtcMillis) &&
- Objects.equals(mVideoWidth, that.mVideoWidth) &&
- Objects.equals(mVideoHeight, that.mVideoHeight) &&
- Objects.equals(mSearchable, that.mSearchable) &&
- Objects.equals(mDataBytes, that.mDataBytes) &&
- Objects.equals(mDurationMillis, that.mDurationMillis) &&
- Objects.equals(mExpireTimeUtcMillis, that.mExpireTimeUtcMillis) &&
- Objects.equals(mInternalProviderFlag1, that.mInternalProviderFlag1) &&
- Objects.equals(mInternalProviderFlag2, that.mInternalProviderFlag2) &&
- Objects.equals(mInternalProviderFlag3, that.mInternalProviderFlag3) &&
- Objects.equals(mInternalProviderFlag4, that.mInternalProviderFlag4) &&
- Objects.equals(mVersionNumber, that.mVersionNumber) &&
- Objects.equals(mTitle, that.mTitle) &&
- Objects.equals(mEpisodeTitle, that.mEpisodeTitle) &&
- Arrays.equals(mBroadcastGenres, that.mBroadcastGenres) &&
- Arrays.equals(mCanonicalGenres, that.mCanonicalGenres) &&
- Objects.equals(mShortDescription, that.mShortDescription) &&
- Objects.equals(mLongDescription, that.mLongDescription) &&
- Objects.equals(mAudioLanguage, that.mAudioLanguage) &&
- Objects.equals(mContentRating, that.mContentRating) &&
- Objects.equals(mPosterArt, that.mPosterArt) &&
- Objects.equals(mThumbnail, that.mThumbnail);
- }
-
- /**
- * Hashes based on the ID.
- */
- @Override
- public int hashCode() {
- return Objects.hash(mId);
- }
-
- @Override
- public String toString() {
- return "RecordedProgram"
- + "[" + mId +
- "]{ mInputId=" + mInputId +
- ", mChannelId='" + mChannelId + '\'' +
- ", mTitle='" + mTitle + '\'' +
- ", mEpisodeNumber=" + mEpisodeNumber +
- ", mEpisodeTitle='" + mEpisodeTitle + '\'' +
- ", mStartTimeUtcMillis=" + mStartTimeUtcMillis +
- ", mEndTimeUtcMillis=" + mEndTimeUtcMillis +
- ", mBroadcastGenres=" +
- (mBroadcastGenres != null ? Arrays.toString(mBroadcastGenres) : "null") +
- ", mCanonicalGenres=" +
- (mCanonicalGenres != null ? Arrays.toString(mCanonicalGenres) : "null") +
- ", mShortDescription='" + mShortDescription + '\'' +
- ", mLongDescription='" + mLongDescription + '\'' +
- ", mVideoHeight=" + mVideoHeight +
- ", mVideoWidth=" + mVideoWidth +
- ", mAudioLanguage='" + mAudioLanguage + '\'' +
- ", mContentRating='" + mContentRating + '\'' +
- ", mPosterArt=" + mPosterArt +
- ", mThumbnail=" + mThumbnail +
- ", mSearchable=" + mSearchable +
- ", mDataUri=" + mDataUri +
- ", mDataBytes=" + mDataBytes +
- ", mDurationMillis=" + mDurationMillis +
- ", mExpireTimeUtcMillis=" + mExpireTimeUtcMillis +
- ", mInternalProviderData.length=" +
- (mInternalProviderData == null ? "null" : mInternalProviderData.length) +
- ", mInternalProviderFlag1=" + mInternalProviderFlag1 +
- ", mInternalProviderFlag2=" + mInternalProviderFlag2 +
- ", mInternalProviderFlag3=" + mInternalProviderFlag3 +
- ", mInternalProviderFlag4=" + mInternalProviderFlag4 +
- ", mSeasonNumber=" + mSeasonNumber +
- ", mSeasonTitle=" + mSeasonTitle +
- ", mVersionNumber=" + mVersionNumber +
- '}';
- }
-
- @Nullable
- private static String safeToString(@Nullable Object o) {
- return o == null ? null : o.toString();
- }
-
- @Nullable
- private static String safeEncode(@Nullable String[] genres) {
- return genres == null ? null : TvContract.Programs.Genres.encode(genres);
- }
-}
diff --git a/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java b/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
index 15b38f02..392d489f 100644
--- a/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
+++ b/common/src/com/android/tv/common/ui/setup/OnActionClickListener.java
@@ -16,15 +16,20 @@
package com.android.tv.common.ui.setup;
+import android.os.Bundle;
+
/**
* A listener for the action click.
*/
public interface OnActionClickListener {
/**
* Called when the action is clicked.
+ * <p>
+ * The method should return {@code true} if the action is handled, otherwise {@code false}.
*
- * @param category action category.
- * @param id action id.
+ * @param category The action category.
+ * @param id The action id.
+ * @param params The parameter for the action.
*/
- void onActionClick(String category, int id);
+ boolean onActionClick(String category, int id, Bundle params);
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java b/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
index 0f44ce06..7ee06faf 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupActionHelper.java
@@ -17,6 +17,8 @@
package com.android.tv.common.ui.setup;
import android.app.Fragment;
+import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -24,47 +26,60 @@ import android.view.View.OnClickListener;
* Helper class for the execution in the fragment.
*/
public class SetupActionHelper {
+ private static final String TAG = "SetupActionHelper";
+
/**
- * Executes the action of the given {@code actionId}.
+ * Executes the action.
*/
- public static void onActionClick(Fragment fragment, String category, int actionId) {
- OnActionClickListener listener = null;
- if (fragment instanceof SetupFragment) {
- listener = ((SetupFragment) fragment).getOnActionClickListener();
- }
- if (listener == null && fragment.getActivity() instanceof OnActionClickListener) {
- listener = (OnActionClickListener) fragment.getActivity();
- }
- if (listener != null) {
- listener.onActionClick(category, actionId);
+ public static boolean onActionClick(Fragment fragment, String category, int actionId) {
+ return onActionClick(fragment, category, actionId, null);
+ }
+
+ /**
+ * Executes the action.
+ */
+ public static boolean onActionClick(Fragment fragment, String category, int actionId,
+ Bundle params) {
+ if (fragment.getActivity() instanceof OnActionClickListener) {
+ return ((OnActionClickListener) fragment.getActivity()).onActionClick(category,
+ actionId, params);
}
+ Log.e(TAG, "Activity can't handle the action: {category=" + category + ", actionId="
+ + actionId + ", params=" + params + "}");
+ return false;
}
/**
* Creates an {@link OnClickListener} to handle the action.
*/
- public static OnClickListener createOnClickListenerForAction(OnActionClickListener listener,
- String category, int actionId) {
- return new OnActionClickListenerForAction(listener, category, actionId);
+ public static OnClickListener createOnClickListenerForAction(Fragment fragment, String category,
+ int actionId, Bundle params) {
+ return new OnActionClickListenerForAction(fragment, category, actionId, params);
}
+ /**
+ * The {@link OnClickListener} for the view.
+ * <p>
+ * Note that this class should be used only for the views in the {@code mFragment} to avoid the
+ * leak of mFragment.
+ */
private static class OnActionClickListenerForAction implements OnClickListener {
- private final OnActionClickListener mListener;
+ private final Fragment mFragment;
private final String mCategory;
private final int mActionId;
+ private final Bundle mParams;
- OnActionClickListenerForAction(OnActionClickListener listener, String category,
- int actionId) {
- mListener = listener;
+ OnActionClickListenerForAction(Fragment fragment, String category, int actionId,
+ Bundle params) {
+ mFragment = fragment;
mCategory = category;
mActionId = actionId;
+ mParams = params;
}
@Override
public void onClick(View v) {
- if (mListener != null) {
- mListener.onActionClick(mCategory, mActionId);
- }
+ SetupActionHelper.onActionClick(mFragment, mCategory, mActionId, mParams);
}
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupActivity.java b/common/src/com/android/tv/common/ui/setup/SetupActivity.java
index 8c7b1b8e..2b381a6e 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupActivity.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupActivity.java
@@ -49,6 +49,7 @@ public abstract class SetupActivity extends Activity implements OnActionClickLis
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ SetupAnimationHelper.initialize(this);
setContentView(R.layout.activity_setup);
mFragmentTransitionDuration = getResources().getInteger(
R.integer.setup_fragment_transition_duration);
@@ -129,19 +130,26 @@ public abstract class SetupActivity extends Activity implements OnActionClickLis
}
@Override
- public void onActionClick(String category, int actionId) {
+ public boolean onActionClick(String category, int actionId, Bundle params) {
if (mHandler.hasMessages(MSG_EXECUTE_ACTION)) {
- return;
+ return false;
}
- executeAction(category, actionId);
+ return executeAction(category, actionId, params);
}
protected void executeActionWithDelay(Runnable action, int delayMs) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_EXECUTE_ACTION, action), delayMs);
}
- // Override this method if the inherited class wants to handle the action.
- protected void executeAction(String category, int actionId) { }
+ /**
+ * Override this method if the inherited class wants to handle the action.
+ * <p>
+ * The override method should return {@code true} if the action is handled, otherwise
+ * {@code false}.
+ */
+ protected boolean executeAction(String category, int actionId, Bundle params) {
+ return false;
+ }
/**
* Returns the duration of the shared element transition.
diff --git a/common/src/com/android/tv/common/ui/setup/SetupFragment.java b/common/src/com/android/tv/common/ui/setup/SetupFragment.java
index df7256d3..d2b9d7c8 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupFragment.java
@@ -47,11 +47,9 @@ public abstract class SetupFragment extends Fragment {
public static final int FRAGMENT_REENTER_TRANSITION = FRAGMENT_ENTER_TRANSITION << 2;
public static final int FRAGMENT_RETURN_TRANSITION = FRAGMENT_ENTER_TRANSITION << 3;
- private OnActionClickListener mOnActionClickListener;
-
private boolean mEnterTransitionRunning;
- private TransitionListener mTransitionListener = new TransitionListener() {
+ private final TransitionListener mTransitionListener = new TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
mEnterTransitionRunning = true;
@@ -103,20 +101,6 @@ public abstract class SetupFragment extends Fragment {
}
/**
- * Returns action click listener.
- */
- public OnActionClickListener getOnActionClickListener() {
- return mOnActionClickListener;
- }
-
- /**
- * Sets action click listener.
- */
- public void setOnActionClickListener(OnActionClickListener onActionClickListener) {
- mOnActionClickListener = onActionClickListener;
- }
-
- /**
* Returns the layout resource ID for this fragment.
*/
abstract protected int getLayoutResourceId();
@@ -130,8 +114,12 @@ public abstract class SetupFragment extends Fragment {
});
}
- protected void onActionClick(String category, int actionId) {
- SetupActionHelper.onActionClick(this, category, actionId);
+ protected boolean onActionClick(String category, int actionId) {
+ return SetupActionHelper.onActionClick(this, category, actionId);
+ }
+
+ protected boolean onActionClick(String category, int actionId, Bundle params) {
+ return SetupActionHelper.onActionClick(this, category, actionId, params);
}
@Override
diff --git a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
index aa912a97..bcaefec9 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
@@ -57,9 +57,7 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
R.dimen.setup_done_button_container_width);
// Guided actions list
View list = view.findViewById(R.id.guidedactions_list);
- View list2 = view.findViewById(R.id.guidedactions_list2);
- MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.findViewById(
- R.id.guidedactions_list).getLayoutParams();
+ MarginLayoutParams marginLayoutParams = (MarginLayoutParams) list.getLayoutParams();
// Use content view to check layout direction while view is being created.
if (getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_LTR) {
@@ -74,6 +72,9 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
}
// gridView Alignment
VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView();
+ // Workaround of b/28274171
+ // TODO: Remove the following line once b/28274171 is resolved.
+ gridView.setFocusable(true);
int offset = getResources().getDimensionPixelOffset(
R.dimen.setup_guidedactions_selector_margin_top);
gridView.setWindowAlignmentOffset(offset);
diff --git a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
index fea9bf4a..63247481 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
@@ -17,6 +17,8 @@
package com.android.tv.common.ui.setup;
import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -28,15 +30,27 @@ import com.android.tv.common.R;
* A fragment for channel source info/setup.
*/
public abstract class SetupMultiPaneFragment extends SetupFragment {
+ private static final String TAG = "SetupMultiPaneFragment";
+ private static final boolean DEBUG = false;
+
public static final int ACTION_DONE = Integer.MAX_VALUE;
+ private static final String CONTENT_FRAGMENT_TAG = "content_fragment";
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ if (DEBUG) {
+ Log.d(TAG, "onCreateView(" + inflater + ", " + container + ", " + savedInstanceState
+ + ")");
+ }
View view = super.onCreateView(inflater, container, savedInstanceState);
- SetupGuidedStepFragment contentFragment = onCreateContentFragment();
- getChildFragmentManager().beginTransaction()
- .replace(R.id.guided_step_fragment_container, contentFragment).commit();
+ if (savedInstanceState == null) {
+ SetupGuidedStepFragment contentFragment = onCreateContentFragment();
+ getChildFragmentManager().beginTransaction()
+ .replace(R.id.guided_step_fragment_container, contentFragment,
+ CONTENT_FRAGMENT_TAG).commit();
+ }
if (needsDoneButton()) {
setOnClickAction(view.findViewById(R.id.button_done), getActionCategory(), ACTION_DONE);
} else {
@@ -64,6 +78,12 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
abstract protected SetupGuidedStepFragment onCreateContentFragment();
+ @Nullable
+ protected SetupGuidedStepFragment getContentFragment() {
+ return (SetupGuidedStepFragment) getChildFragmentManager()
+ .findFragmentByTag(CONTENT_FRAGMENT_TAG);
+ }
+
abstract protected String getActionCategory();
protected boolean needsDoneButton() {
diff --git a/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java b/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
index 5c57d84d..e1a8e60c 100644
--- a/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
+++ b/common/src/com/android/tv/common/ui/setup/animation/FadeAndShortSlide.java
@@ -90,7 +90,7 @@ public class FadeAndShortSlide extends Visibility {
private Visibility mFade = new Fade();
// TODO: Consider using TransitionPropagation.
- private int[] mParentIdsForDelay;
+ private final int[] mParentIdsForDelay;
private int mDistance = DEFAULT_DISTANCE;
public FadeAndShortSlide() {
diff --git a/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java b/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
index 0c5849ea..d98138a2 100644
--- a/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
+++ b/common/src/com/android/tv/common/ui/setup/animation/SetupAnimationHelper.java
@@ -49,6 +49,9 @@ public final class SetupAnimationHelper {
* Load initial parameters. This method should be called before using this class.
*/
public static void initialize(Context context) {
+ if (sInitialized) {
+ return;
+ }
sFragmentTransitionDuration = context.getResources()
.getInteger(R.integer.setup_fragment_transition_duration);
sFragmentTransitionLongDistance = context.getResources()
@@ -66,7 +69,7 @@ public final class SetupAnimationHelper {
public static class TransitionBuilder {
private int mSlideEdge = Gravity.START;
- private int mDistance = sFragmentTransitionLongDistance;
+ private final int mDistance = sFragmentTransitionLongDistance;
private long mDuration = sFragmentTransitionDuration;
private int[] mParentIdForDelay;
private int[] mExcludeIds;