aboutsummaryrefslogtreecommitdiff
path: root/tests/common/src/com/android/tv/testing/data/ChannelUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common/src/com/android/tv/testing/data/ChannelUtils.java')
-rw-r--r--tests/common/src/com/android/tv/testing/data/ChannelUtils.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/tests/common/src/com/android/tv/testing/data/ChannelUtils.java b/tests/common/src/com/android/tv/testing/data/ChannelUtils.java
new file mode 100644
index 00000000..920c7087
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/data/ChannelUtils.java
@@ -0,0 +1,189 @@
+/*
+ * 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.testing.data;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.Channels;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.support.annotation.WorkerThread;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Static helper methods for working with {@link android.media.tv.TvContract}. */
+public class ChannelUtils {
+ private static final String TAG = "ChannelUtils";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Query and return the map of (channel_id, ChannelInfo). See: {@link
+ * com.android.tv.testing.data.ChannelInfo#fromCursor(Cursor)}.
+ */
+ @WorkerThread
+ public static Map<Long, ChannelInfo> queryChannelInfoMapForTvInput(
+ Context context, String inputId) {
+ Uri uri = TvContract.buildChannelsUriForInput(inputId);
+ Map<Long, ChannelInfo> map = new HashMap<>();
+
+ String[] projections = new String[ChannelInfo.PROJECTION.length + 1];
+ projections[0] = Channels._ID;
+ System.arraycopy(ChannelInfo.PROJECTION, 0, projections, 1, ChannelInfo.PROJECTION.length);
+ try (Cursor cursor =
+ context.getContentResolver().query(uri, projections, null, null, null)) {
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ map.put(cursor.getLong(0), ChannelInfo.fromCursor(cursor));
+ }
+ }
+ return map;
+ }
+ }
+
+ @WorkerThread
+ public static void updateChannels(Context context, String inputId, List<ChannelInfo> channels) {
+ // Create a map from original network ID to channel row ID for existing channels.
+ SparseArray<Long> existingChannelsMap = new SparseArray<>();
+ Uri channelsUri = TvContract.buildChannelsUriForInput(inputId);
+ String[] projection = {Channels._ID, Channels.COLUMN_ORIGINAL_NETWORK_ID};
+ ContentResolver resolver = context.getContentResolver();
+ try (Cursor cursor = resolver.query(channelsUri, projection, null, null, null)) {
+ while (cursor != null && cursor.moveToNext()) {
+ long rowId = cursor.getLong(0);
+ int originalNetworkId = cursor.getInt(1);
+ existingChannelsMap.put(originalNetworkId, rowId);
+ }
+ }
+
+ Map<Uri, String> logos = new HashMap<>();
+ for (ChannelInfo channel : channels) {
+ // If a channel exists, update it. If not, insert a new one.
+ ContentValues values = new ContentValues();
+ values.put(Channels.COLUMN_INPUT_ID, inputId);
+ values.put(Channels.COLUMN_DISPLAY_NUMBER, channel.number);
+ values.put(Channels.COLUMN_DISPLAY_NAME, channel.name);
+ values.put(Channels.COLUMN_ORIGINAL_NETWORK_ID, channel.originalNetworkId);
+ String videoFormat = channel.getVideoFormat();
+ if (videoFormat != null) {
+ values.put(Channels.COLUMN_VIDEO_FORMAT, videoFormat);
+ } else {
+ values.putNull(Channels.COLUMN_VIDEO_FORMAT);
+ }
+ if (!TextUtils.isEmpty(channel.appLinkText)) {
+ values.put(Channels.COLUMN_APP_LINK_TEXT, channel.appLinkText);
+ }
+ if (channel.appLinkColor != 0) {
+ values.put(Channels.COLUMN_APP_LINK_COLOR, channel.appLinkColor);
+ }
+ if (!TextUtils.isEmpty(channel.appLinkPosterArtUri)) {
+ values.put(Channels.COLUMN_APP_LINK_POSTER_ART_URI, channel.appLinkPosterArtUri);
+ }
+ if (!TextUtils.isEmpty(channel.appLinkIconUri)) {
+ values.put(Channels.COLUMN_APP_LINK_ICON_URI, channel.appLinkIconUri);
+ }
+ if (!TextUtils.isEmpty(channel.appLinkIntentUri)) {
+ values.put(Channels.COLUMN_APP_LINK_INTENT_URI, channel.appLinkIntentUri);
+ }
+ Long rowId = existingChannelsMap.get(channel.originalNetworkId);
+ Uri uri;
+ if (rowId == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Inserting " + channel);
+ }
+ uri = resolver.insert(TvContract.Channels.CONTENT_URI, values);
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Updating " + channel);
+ }
+ uri = TvContract.buildChannelUri(rowId);
+ resolver.update(uri, values, null, null);
+ existingChannelsMap.remove(channel.originalNetworkId);
+ }
+ if (!TextUtils.isEmpty(channel.logoUrl)) {
+ logos.put(TvContract.buildChannelLogoUri(uri), channel.logoUrl);
+ }
+ }
+ if (!logos.isEmpty()) {
+ new InsertLogosTask(context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, logos);
+ }
+
+ // Deletes channels which don't exist in the new feed.
+ int size = existingChannelsMap.size();
+ for (int i = 0; i < size; ++i) {
+ Long rowId = existingChannelsMap.valueAt(i);
+ resolver.delete(TvContract.buildChannelUri(rowId), null, null);
+ }
+ }
+
+ public static void copy(InputStream is, OutputStream os) throws IOException {
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = is.read(buffer)) != -1) {
+ os.write(buffer, 0, len);
+ }
+ }
+
+ private ChannelUtils() {
+ // Prevent instantiation.
+ }
+
+ public static List<ChannelInfo> createChannelInfos(Context context, int channelCount) {
+ List<ChannelInfo> channels = new ArrayList<>();
+ for (int i = 1; i <= channelCount; i++) {
+ channels.add(ChannelInfo.create(context, i));
+ }
+ return channels;
+ }
+
+ public static class InsertLogosTask extends AsyncTask<Map<Uri, String>, Void, Void> {
+ private final Context mContext;
+
+ InsertLogosTask(Context context) {
+ mContext = context;
+ }
+
+ @SafeVarargs
+ @Override
+ public final Void doInBackground(Map<Uri, String>... logosList) {
+ for (Map<Uri, String> logos : logosList) {
+ for (Uri uri : logos.keySet()) {
+ if (uri == null) {
+ continue;
+ }
+ Uri logoUri = Uri.parse(logos.get(uri));
+ try (InputStream is = mContext.getContentResolver().openInputStream(logoUri);
+ OutputStream os = mContext.getContentResolver().openOutputStream(uri)) {
+ copy(is, os);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to write " + logoUri + " to " + uri, ioe);
+ }
+ }
+ }
+ return null;
+ }
+ }
+}