blob: 979a20a49bcc0305d5c627fb7e43ad78fba8ec67 [file] [log] [blame]
/*
* 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 android.support.media.tv;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Build;
import android.support.media.tv.TvContractCompat.Channels;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests that channels can be created using the Builder pattern and correctly obtain
* values from them
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
public class ChannelTest {
@After
public void tearDown() {
if (!Utils.hasTvInputFramework(InstrumentationRegistry.getContext())) {
return;
}
ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver();
resolver.delete(Channels.CONTENT_URI, null, null);
}
@Test
public void testEmptyChannel() {
Channel emptyChannel = new Channel.Builder()
.build();
ContentValues contentValues = emptyChannel.toContentValues(true);
compareChannel(emptyChannel, Channel.fromCursor(getChannelCursor(contentValues)), true);
}
@Test
public void testSampleChannel() {
// Tests cloning and database I/O of a channel with some defined and some undefined
// values.
Channel sampleChannel = new Channel.Builder()
.setDisplayName("Google")
.setDisplayNumber("3")
.setDescription("This is a sample channel")
.setOriginalNetworkId(1)
.setAppLinkIntentUri(Uri.parse(new Intent(Intent.ACTION_VIEW).toUri(
Intent.URI_INTENT_SCHEME)))
.setOriginalNetworkId(0)
.build();
ContentValues contentValues = sampleChannel.toContentValues(true);
compareChannel(sampleChannel, Channel.fromCursor(getChannelCursor(contentValues)), true);
Channel clonedSampleChannel = new Channel.Builder(sampleChannel).build();
compareChannel(sampleChannel, clonedSampleChannel, true);
}
@Test
public void testFullyPopulatedChannel() {
Channel fullyPopulatedChannel = createFullyPopulatedChannel();
ContentValues contentValues = fullyPopulatedChannel.toContentValues(true);
compareChannel(fullyPopulatedChannel, Channel.fromCursor(getChannelCursor(contentValues)),
true);
Channel clonedFullyPopulatedChannel = new Channel.Builder(fullyPopulatedChannel).build();
compareChannel(fullyPopulatedChannel, clonedFullyPopulatedChannel, true);
}
@Test
public void testChannelWithSystemContentProvider() {
if (!Utils.hasTvInputFramework(InstrumentationRegistry.getContext())) {
return;
}
Channel fullyPopulatedChannel = createFullyPopulatedChannel();
ContentValues contentValues = fullyPopulatedChannel.toContentValues();
ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver();
Uri channelUri = resolver.insert(Channels.CONTENT_URI, contentValues);
assertNotNull(channelUri);
Channel channelFromSystemDb = loadChannelFromContentProvider(resolver, channelUri);
compareChannel(fullyPopulatedChannel, channelFromSystemDb, false);
}
@Test
public void testChannelUpdateWithContentProvider() {
if (!Utils.hasTvInputFramework(InstrumentationRegistry.getContext())) {
return;
}
Channel fullyPopulatedChannel = createFullyPopulatedChannel();
ContentValues contentValues = fullyPopulatedChannel.toContentValues();
ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver();
Uri channelUri = resolver.insert(Channels.CONTENT_URI, contentValues);
assertNotNull(channelUri);
Channel channelFromSystemDb = loadChannelFromContentProvider(resolver, channelUri);
compareChannel(fullyPopulatedChannel, channelFromSystemDb, false);
// Update a field from a fully loaded channel.
Channel updatedChannel = new Channel.Builder(channelFromSystemDb)
.setDescription("new description").build();
assertEquals(1, resolver.update(channelUri, updatedChannel.toContentValues(), null, null));
channelFromSystemDb = loadChannelFromContentProvider(resolver, channelUri);
compareChannel(updatedChannel, channelFromSystemDb, false);
// Update a field with null from a fully loaded channel.
updatedChannel = new Channel.Builder(updatedChannel)
.setAppLinkText(null).build();
assertEquals(1, resolver.update(
channelUri, updatedChannel.toContentValues(), null, null));
channelFromSystemDb = loadChannelFromContentProvider(resolver, channelUri);
compareChannel(updatedChannel, channelFromSystemDb, false);
// Update a field without referencing fully channel.
ContentValues values = new Channel.Builder().setDisplayName("abc").build()
.toContentValues();
assertEquals(1, values.size());
assertEquals(1, resolver.update(channelUri, values, null, null));
channelFromSystemDb = loadChannelFromContentProvider(resolver, channelUri);
Channel expectedChannel = new Channel.Builder(channelFromSystemDb)
.setDisplayName("abc").build();
compareChannel(expectedChannel, channelFromSystemDb, false);
}
@Test
public void testChannelEquals() {
assertEquals(createFullyPopulatedChannel(), createFullyPopulatedChannel());
}
private static Channel loadChannelFromContentProvider(
ContentResolver resolver, Uri channelUri) {
try (Cursor cursor = resolver.query(channelUri, null, null, null, null)) {
assertNotNull(cursor);
assertEquals(1, cursor.getCount());
cursor.moveToNext();
return Channel.fromCursor(cursor);
}
}
private static Channel createFullyPopulatedChannel() {
return new Channel.Builder()
.setAppLinkColor(0x00FF0000)
.setAppLinkIconUri(Uri.parse("http://example.com/icon.png"))
.setAppLinkIntent(new Intent())
.setAppLinkPosterArtUri(Uri.parse("http://example.com/poster.png"))
.setAppLinkText("Open an intent")
.setDescription("Channel description")
.setDisplayName("Display Name")
.setDisplayNumber("100")
.setInputId("TestInputService")
.setNetworkAffiliation("Network Affiliation")
.setOriginalNetworkId(2)
.setPackageName("android.support.media.tv.test")
.setSearchable(false)
.setServiceId(3)
.setTransportStreamId(4)
.setType(TvContractCompat.Channels.TYPE_PREVIEW)
.setServiceType(TvContractCompat.Channels.SERVICE_TYPE_AUDIO_VIDEO)
.setVideoFormat(TvContractCompat.Channels.VIDEO_FORMAT_240P)
.setInternalProviderFlag1(0x4)
.setInternalProviderFlag2(0x3)
.setInternalProviderFlag3(0x2)
.setInternalProviderFlag4(0x1)
.setInternalProviderId("Internal Provider")
.setTransient(true)
.setBrowsable(true)
.setLocked(true)
.setSystemApproved(true)
.build();
}
private static void compareChannel(Channel channelA, Channel channelB,
boolean includeIdAndProtectedFields) {
assertEquals(channelA.isSearchable(), channelB.isSearchable());
assertEquals(channelA.getDescription(), channelB.getDescription());
assertEquals(channelA.getDisplayName(), channelB.getDisplayName());
assertEquals(channelA.getDisplayNumber(), channelB.getDisplayNumber());
assertEquals(channelA.getInputId(), channelB.getInputId());
assertEquals(channelA.getNetworkAffiliation(), channelB.getNetworkAffiliation());
assertEquals(channelA.getOriginalNetworkId(), channelB.getOriginalNetworkId());
assertEquals(channelA.getPackageName(), channelB.getPackageName());
assertEquals(channelA.getServiceId(), channelB.getServiceId());
assertEquals(channelA.getServiceType(), channelB.getServiceType());
assertEquals(channelA.getTransportStreamId(), channelB.getTransportStreamId());
assertEquals(channelA.getType(), channelB.getType());
assertEquals(channelA.getVideoFormat(), channelB.getVideoFormat());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
assertEquals(channelA.getAppLinkColor(), channelB.getAppLinkColor());
assertEquals(channelA.getAppLinkIconUri(), channelB.getAppLinkIconUri());
assertEquals(channelA.getAppLinkIntentUri(), channelB.getAppLinkIntentUri());
assertEquals(channelA.getAppLinkPosterArtUri(), channelB.getAppLinkPosterArtUri());
assertEquals(channelA.getAppLinkText(), channelB.getAppLinkText());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assertEquals(channelA.getInternalProviderId(), channelB.getInternalProviderId());
assertEquals(channelA.isTransient(), channelB.isTransient());
}
if (includeIdAndProtectedFields) {
// Skip row ID since the one from system DB has the valid ID while the other does not.
assertEquals(channelA.getId(), channelB.getId());
// When we insert a channel using toContentValues() to the system, we drop some
// protected fields since they only can be modified by system apps.
assertEquals(channelA.isBrowsable(), channelB.isBrowsable());
assertEquals(channelA.isLocked(), channelB.isLocked());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assertEquals(channelA.isSystemApproved(), channelB.isSystemApproved());
}
assertEquals(channelA.toContentValues(), channelB.toContentValues());
}
}
private static MatrixCursor getChannelCursor(ContentValues contentValues) {
String[] cols = Channel.PROJECTION;
MatrixCursor cursor = new MatrixCursor(cols);
MatrixCursor.RowBuilder builder = cursor.newRow();
for (String col : cols) {
if (col != null) {
builder.add(col, contentValues.get(col));
}
}
cursor.moveToFirst();
return cursor;
}
}