1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.providers.tv; 18 19 import android.content.ContentValues; 20 import android.content.pm.ProviderInfo; 21 import android.database.Cursor; 22 import android.media.tv.TvContract; 23 import android.media.tv.TvContract.Channels; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.provider.Settings; 27 import android.test.AndroidTestCase; 28 import android.test.mock.MockContentProvider; 29 import android.test.mock.MockContentResolver; 30 31 public class ParametersTest extends AndroidTestCase { 32 private static final String FAKE_INPUT_ID = "ParametersTest"; 33 private static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS"; 34 private static final String PERMISSION_ACCESS_ALL_EPG_DATA = 35 "com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA"; 36 37 private MockContentResolver mResolver; 38 private TvProviderForTesting mProvider; 39 private MockTvProviderContext mContext; 40 41 @Override setUp()42 protected void setUp() throws Exception { 43 super.setUp(); 44 45 mResolver = new MockContentResolver(); 46 mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() { 47 @Override 48 public Bundle call(String method, String request, Bundle args) { 49 return new Bundle(); 50 } 51 }); 52 53 mProvider = new TvProviderForTesting(); 54 mResolver.addProvider(TvContract.AUTHORITY, mProvider); 55 56 mContext = new MockTvProviderContext(mResolver, getContext()); 57 setContext(mContext); 58 59 final ProviderInfo info = new ProviderInfo(); 60 info.authority = TvContract.AUTHORITY; 61 mProvider.attachInfoForTesting(getContext(), info); 62 Utils.clearTvProvider(mResolver); 63 } 64 65 @Override tearDown()66 protected void tearDown() throws Exception { 67 Utils.clearTvProvider(mResolver); 68 mProvider.shutdown(); 69 super.tearDown(); 70 } 71 createDummyChannelValues(int searchable, boolean preview)72 private ContentValues createDummyChannelValues(int searchable, boolean preview) { 73 ContentValues values = new ContentValues(); 74 values.put(Channels.COLUMN_INPUT_ID, FAKE_INPUT_ID); 75 values.put(Channels.COLUMN_INTERNAL_PROVIDER_ID, "ID-4321"); 76 values.put(Channels.COLUMN_TYPE, preview ? Channels.TYPE_PREVIEW : Channels.TYPE_OTHER); 77 values.put(Channels.COLUMN_SERVICE_TYPE, Channels.SERVICE_TYPE_AUDIO_VIDEO); 78 values.put(Channels.COLUMN_DISPLAY_NUMBER, "1"); 79 values.put(Channels.COLUMN_VIDEO_FORMAT, Channels.VIDEO_FORMAT_480P); 80 values.put(Channels.COLUMN_SEARCHABLE, searchable); 81 82 return values; 83 } 84 verifyChannelCountWithPreview(int expectedCount, boolean preview)85 private void verifyChannelCountWithPreview(int expectedCount, boolean preview) { 86 Uri channelUri = Channels.CONTENT_URI.buildUpon() 87 .appendQueryParameter(TvContract.PARAM_PREVIEW, String.valueOf(preview)).build(); 88 verifyChannelCount(channelUri, expectedCount); 89 } 90 verifyChannelCount(Uri channelUri, int expectedCount)91 private void verifyChannelCount(Uri channelUri, int expectedCount) { 92 try (Cursor cursor = mResolver.query( 93 channelUri, new String[] {Channels.COLUMN_TYPE}, null, null, null)) { 94 assertNotNull(cursor); 95 assertEquals("Query:{Uri=" + channelUri + "}", expectedCount, cursor.getCount()); 96 } 97 } 98 insertChannelWithPackageName(ContentValues values, String packageName)99 private void insertChannelWithPackageName(ContentValues values, String packageName) { 100 mProvider.callingPackage = packageName; 101 mResolver.insert(Channels.CONTENT_URI, values); 102 mProvider.callingPackage = null; 103 } 104 verifyChannelQuery(Uri channelsUri, int expectedCount, boolean expectedException)105 private void verifyChannelQuery(Uri channelsUri, int expectedCount, boolean expectedException) { 106 try { 107 verifyChannelCount(channelsUri, expectedCount); 108 if (expectedException) { 109 fail("Query:{Uri=" + channelsUri + "} should throw exception"); 110 } 111 } catch (SecurityException e) { 112 if (!expectedException) { 113 fail("Query failed due to:" + e); 114 } 115 } 116 } 117 verifyChannelUpdate(Uri channelsUri, ContentValues values, int expectedCount, boolean expectedException)118 private void verifyChannelUpdate(Uri channelsUri, ContentValues values, 119 int expectedCount, boolean expectedException) { 120 try { 121 int count = mResolver.update(channelsUri, values, null, null); 122 if (expectedException) { 123 fail("Update:{Uri=" + channelsUri + "} should throw exception"); 124 } 125 assertEquals(expectedCount, count); 126 } catch (SecurityException e) { 127 if (!expectedException) { 128 fail("Update failed due to:" + e); 129 } 130 } 131 } 132 verifyChannelDelete(Uri channelsUri, int expectedCount, boolean expectedException)133 private void verifyChannelDelete(Uri channelsUri, int expectedCount, 134 boolean expectedException) { 135 try { 136 int count = mResolver.delete(channelsUri, null, null); 137 if (expectedException) { 138 fail("Delete:{Uri=" + channelsUri + "} should throw exception"); 139 } 140 assertEquals(expectedCount, count); 141 } catch (SecurityException e) { 142 if (!expectedException) { 143 fail("Delete failed due to:" + e); 144 } 145 } 146 } 147 testTypePreviewQueryChannel()148 public void testTypePreviewQueryChannel() { 149 // Check if there is not any preview and non-preview channels. 150 verifyChannelCountWithPreview(0, true); 151 verifyChannelCountWithPreview(0, false); 152 // Insert one preview channel and then check if the count of preview channels is 0 and the 153 // count of non-preview channels is 0. 154 ContentValues previewChannelContentValue = createDummyChannelValues(1, true); 155 mResolver.insert(Channels.CONTENT_URI, previewChannelContentValue); 156 verifyChannelCountWithPreview(1, true); 157 verifyChannelCountWithPreview(0, false); 158 // Insert one non-preview channel and then check if the count of preview channels or 159 // non-preview channels are both 1. 160 ContentValues nonPreviewChannelContentValue = createDummyChannelValues(1, false); 161 mResolver.insert(Channels.CONTENT_URI, nonPreviewChannelContentValue); 162 verifyChannelCountWithPreview(1, true); 163 verifyChannelCountWithPreview(1, false); 164 } 165 testPackageNameOperateChannels()166 public void testPackageNameOperateChannels() { 167 String packageName = getContext().getPackageName(); 168 String otherPackageName = packageName + ".other"; 169 Uri ownPackageChannelsUri = Channels.CONTENT_URI.buildUpon() 170 .appendQueryParameter(TvContract.PARAM_PACKAGE, packageName).build(); 171 Uri otherPackageChannelsUri = Channels.CONTENT_URI.buildUpon() 172 .appendQueryParameter(TvContract.PARAM_PACKAGE, otherPackageName).build(); 173 174 // Tests with PERMISSION_ACCESS_ALL_EPG_DATA. 175 ContentValues values = createDummyChannelValues(1, false); 176 insertChannelWithPackageName(values, packageName); 177 verifyChannelQuery(ownPackageChannelsUri, 1, false); 178 ContentValues otherValues1 = createDummyChannelValues(1, false); 179 ContentValues otherValues2 = createDummyChannelValues(0, false); 180 insertChannelWithPackageName(otherValues1, otherPackageName); 181 verifyChannelQuery(otherPackageChannelsUri, 1, false); 182 insertChannelWithPackageName(otherValues2, otherPackageName); 183 verifyChannelQuery(otherPackageChannelsUri, 2, false); 184 values.remove(Channels.COLUMN_TYPE); 185 values.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 186 verifyChannelUpdate(ownPackageChannelsUri, values, 1, false); 187 verifyChannelDelete(ownPackageChannelsUri, 1, false); 188 otherValues1.remove(Channels.COLUMN_TYPE); 189 otherValues1.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 190 verifyChannelUpdate(otherPackageChannelsUri, otherValues1, 2, false); 191 verifyChannelDelete(otherPackageChannelsUri, 2, false); 192 193 // Tests with PERMISSION_READ_TV_LISTINGS, without PERMISSION_ACCESS_ALL_EPG_DATA. 194 mContext.grantOrRejectPermission(PERMISSION_ACCESS_ALL_EPG_DATA, false); 195 values = createDummyChannelValues(1, false); 196 insertChannelWithPackageName(values, packageName); 197 verifyChannelQuery(ownPackageChannelsUri, 1, false); 198 otherValues1 = createDummyChannelValues(1, false); 199 otherValues2 = createDummyChannelValues(1, false); 200 ContentValues otherValues3 = createDummyChannelValues(0, false); 201 insertChannelWithPackageName(otherValues1, otherPackageName); 202 verifyChannelQuery(otherPackageChannelsUri, 1, false); 203 insertChannelWithPackageName(otherValues2, otherPackageName); 204 verifyChannelQuery(otherPackageChannelsUri, 2, false); 205 insertChannelWithPackageName(otherValues3, otherPackageName); 206 verifyChannelQuery(otherPackageChannelsUri, 2, false); 207 values.remove(Channels.COLUMN_TYPE); 208 values.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 209 verifyChannelUpdate(ownPackageChannelsUri, values, 1, false); 210 verifyChannelDelete(ownPackageChannelsUri, 1, false); 211 otherValues1.remove(Channels.COLUMN_TYPE); 212 otherValues1.remove(Channels.COLUMN_PACKAGE_NAME); 213 otherValues1.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 214 verifyChannelUpdate(otherPackageChannelsUri, otherValues1, 0, false); 215 verifyChannelDelete(otherPackageChannelsUri, 0, false); 216 217 // Tests without PERMISSION_ACCESS_ALL_EPG_DATA and PERMISSION_READ_TV_LISTINGS. 218 mContext.grantOrRejectPermission(PERMISSION_READ_TV_LISTINGS, false); 219 values = createDummyChannelValues(1, false); 220 insertChannelWithPackageName(values, packageName); 221 verifyChannelQuery(ownPackageChannelsUri, 1, false); 222 otherValues1 = createDummyChannelValues(1, false); 223 insertChannelWithPackageName(otherValues1, otherPackageName); 224 verifyChannelQuery(otherPackageChannelsUri, 0, false); 225 values.remove(Channels.COLUMN_TYPE); 226 values.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 227 verifyChannelUpdate(ownPackageChannelsUri, values, 1, false); 228 verifyChannelDelete(ownPackageChannelsUri, 1, false); 229 otherValues1.remove(Channels.COLUMN_TYPE); 230 otherValues1.remove(Channels.COLUMN_PACKAGE_NAME); 231 otherValues1.put(Channels.COLUMN_DISPLAY_NUMBER, "2"); 232 verifyChannelUpdate(otherPackageChannelsUri, otherValues1, 0, false); 233 verifyChannelDelete(otherPackageChannelsUri, 0, false); 234 } 235 } 236