1 /* 2 * Copyright 2020 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 android.media.tv.tuner.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.media.tv.tuner.Tuner; 25 import android.media.tv.tuner.TunerVersionChecker; 26 import android.media.tv.tuner.dvr.DvrPlayback; 27 import android.media.tv.tuner.dvr.DvrRecorder; 28 import android.media.tv.tuner.dvr.DvrSettings; 29 import android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener; 30 import android.media.tv.tuner.dvr.OnRecordStatusChangedListener; 31 import android.media.tv.tuner.filter.Filter; 32 import android.media.tv.tuner.filter.FilterCallback; 33 import android.media.tv.tuner.filter.FilterConfiguration; 34 import android.media.tv.tuner.filter.FilterEvent; 35 import android.media.tv.tuner.filter.RecordSettings; 36 import android.media.tv.tuner.filter.Settings; 37 import android.media.tv.tuner.filter.TsFilterConfiguration; 38 import android.os.ParcelFileDescriptor; 39 40 import androidx.test.InstrumentationRegistry; 41 import androidx.test.filters.SmallTest; 42 import androidx.test.runner.AndroidJUnit4; 43 44 import com.android.compatibility.common.util.RequiredFeatureRule; 45 46 import org.junit.After; 47 import org.junit.Before; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 52 import java.io.File; 53 import java.io.RandomAccessFile; 54 import java.util.concurrent.Executor; 55 56 @RunWith(AndroidJUnit4.class) 57 @SmallTest 58 public class TunerDvrTest { 59 private static final String TAG = "MediaTunerDvrTest"; 60 private static final long STATUS_CHECK_INTERVAL_MS = 100L; 61 62 @Rule 63 public RequiredFeatureRule featureRule = new RequiredFeatureRule( 64 PackageManager.FEATURE_TUNER); 65 66 private Context mContext; 67 private Tuner mTuner; 68 69 @Before setUp()70 public void setUp() throws Exception { 71 mContext = InstrumentationRegistry.getTargetContext(); 72 InstrumentationRegistry 73 .getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(); 74 mTuner = new Tuner(mContext, null, 100); 75 } 76 77 @After tearDown()78 public void tearDown() { 79 if (mTuner != null) { 80 mTuner.close(); 81 mTuner = null; 82 } 83 } 84 85 @Test testDvrSettings()86 public void testDvrSettings() throws Exception { 87 DvrSettings settings = getDvrSettings(); 88 89 assertEquals(Filter.STATUS_DATA_READY, settings.getStatusMask()); 90 assertEquals(200L, settings.getLowThreshold()); 91 assertEquals(800L, settings.getHighThreshold()); 92 assertEquals(188L, settings.getPacketSize()); 93 assertEquals(DvrSettings.DATA_FORMAT_TS, settings.getDataFormat()); 94 } 95 96 @Test testDvrRecorder()97 public void testDvrRecorder() throws Exception { 98 DvrRecorder d = mTuner.openDvrRecorder(1000, getExecutor(), getRecordListener()); 99 assertNotNull(d); 100 d.configure(getDvrSettings()); 101 102 File tmpFile = File.createTempFile("cts_tuner", "dvr_test"); 103 d.setFileDescriptor( 104 ParcelFileDescriptor.open(tmpFile, ParcelFileDescriptor.MODE_READ_WRITE)); 105 106 Filter filter = mTuner.openFilter( 107 Filter.TYPE_TS, Filter.SUBTYPE_RECORD, 1000, getExecutor(), getFilterCallback()); 108 if (filter != null) { 109 Settings settings = RecordSettings 110 .builder(Filter.TYPE_TS) 111 .setTsIndexMask(RecordSettings.TS_INDEX_FIRST_PACKET) 112 .build(); 113 FilterConfiguration config = TsFilterConfiguration 114 .builder() 115 .setTpid(10) 116 .setSettings(settings) 117 .build(); 118 filter.configure(config); 119 d.attachFilter(filter); 120 } 121 122 d.start(); 123 d.flush(); 124 if (filter != null) { 125 filter.start(); 126 filter.flush(); 127 } 128 d.write(10); 129 d.write(new byte[3], 0, 3); 130 d.stop(); 131 d.close(); 132 if (filter != null) { 133 d.detachFilter(filter); 134 filter.stop(); 135 filter.close(); 136 } 137 138 tmpFile.delete(); 139 } 140 141 @Test testDvrPlayback()142 public void testDvrPlayback() throws Exception { 143 DvrPlayback d = mTuner.openDvrPlayback(1000, getExecutor(), getPlaybackListener()); 144 assertNotNull(d); 145 d.configure(getDvrSettings()); 146 147 File tmpFile = File.createTempFile("cts_tuner", "dvr_test"); 148 try (RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw")) { 149 byte[] bytes = new byte[] {3, 5, 10, 22, 73, 33, 19}; 150 raf.write(bytes); 151 } 152 153 Filter f = mTuner.openFilter( 154 Filter.TYPE_TS, Filter.SUBTYPE_SECTION, 1000, getExecutor(), getFilterCallback()); 155 d.attachFilter(f); 156 d.detachFilter(f); 157 158 d.setFileDescriptor( 159 ParcelFileDescriptor.open(tmpFile, ParcelFileDescriptor.MODE_READ_WRITE)); 160 161 d.start(); 162 d.flush(); 163 assertEquals(3, d.read(3)); 164 assertEquals(3, d.read(new byte[3], 0, 3)); 165 assertEquals(0, d.seek(0)); 166 assertEquals(3, d.read(3)); 167 assertEquals(3, d.read(new byte[3], 0, 3)); 168 assertEquals(5, d.seek(5)); 169 assertEquals(2, d.read(3)); 170 assertEquals(10, d.seek(10)); 171 assertEquals(0, d.read(3)); 172 d.stop(); 173 d.close(); 174 175 tmpFile.delete(); 176 } 177 178 @Test testSetRecordBufferStatusCheckIntervalHint()179 public void testSetRecordBufferStatusCheckIntervalHint() throws Exception { 180 DvrRecorder d = mTuner.openDvrRecorder(1000, getExecutor(), getRecordListener()); 181 assertNotNull(d); 182 183 if (!TunerVersionChecker.isHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_3_0)) { 184 assertEquals(Tuner.RESULT_UNAVAILABLE, 185 d.setRecordBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 186 return; 187 } 188 189 d.configure(getDvrSettings()); 190 191 File tmpFile = File.createTempFile("cts_tuner", "dvr_test"); 192 d.setFileDescriptor( 193 ParcelFileDescriptor.open(tmpFile, ParcelFileDescriptor.MODE_READ_WRITE)); 194 195 assertEquals(Tuner.RESULT_INVALID_ARGUMENT, d.setRecordBufferStatusCheckIntervalHint(-1)); 196 assertEquals(Tuner.RESULT_SUCCESS, 197 d.setRecordBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 198 199 d.start(); 200 d.flush(); 201 d.write(10); 202 d.write(new byte[3], 0, 3); 203 d.stop(); 204 d.close(); 205 206 assertEquals(Tuner.RESULT_NOT_INITIALIZED, 207 d.setRecordBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 208 209 tmpFile.delete(); 210 } 211 212 @Test testSetPlaybackBufferStatusCheckIntervalHint()213 public void testSetPlaybackBufferStatusCheckIntervalHint() throws Exception { 214 DvrPlayback d = mTuner.openDvrPlayback(1000, getExecutor(), getPlaybackListener()); 215 assertNotNull(d); 216 217 if (!TunerVersionChecker.isHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_3_0)) { 218 assertEquals(Tuner.RESULT_UNAVAILABLE, 219 d.setPlaybackBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 220 return; 221 } 222 223 d.configure(getDvrSettings()); 224 225 File tmpFile = File.createTempFile("cts_tuner", "dvr_test"); 226 try (RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw")) { 227 byte[] bytes = new byte[] {3, 5, 10, 22, 73, 33, 19}; 228 raf.write(bytes); 229 } 230 231 d.setFileDescriptor( 232 ParcelFileDescriptor.open(tmpFile, ParcelFileDescriptor.MODE_READ_WRITE)); 233 234 assertEquals(Tuner.RESULT_INVALID_ARGUMENT, 235 d.setPlaybackBufferStatusCheckIntervalHint(-1)); 236 assertEquals(Tuner.RESULT_SUCCESS, 237 d.setPlaybackBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 238 239 d.start(); 240 d.flush(); 241 assertEquals(3, d.read(3)); 242 assertEquals(3, d.read(new byte[3], 0, 3)); 243 assertEquals(0, d.seek(0)); 244 assertEquals(3, d.read(3)); 245 assertEquals(3, d.read(new byte[3], 0, 3)); 246 assertEquals(5, d.seek(5)); 247 assertEquals(2, d.read(3)); 248 assertEquals(10, d.seek(10)); 249 assertEquals(0, d.read(3)); 250 d.stop(); 251 d.close(); 252 253 assertEquals(Tuner.RESULT_NOT_INITIALIZED, 254 d.setPlaybackBufferStatusCheckIntervalHint(STATUS_CHECK_INTERVAL_MS)); 255 256 tmpFile.delete(); 257 } 258 getRecordListener()259 private OnRecordStatusChangedListener getRecordListener() { 260 return new OnRecordStatusChangedListener() { 261 @Override 262 public void onRecordStatusChanged(int status) {} 263 }; 264 } 265 getPlaybackListener()266 private OnPlaybackStatusChangedListener getPlaybackListener() { 267 return new OnPlaybackStatusChangedListener() { 268 @Override 269 public void onPlaybackStatusChanged(int status) {} 270 }; 271 } 272 getExecutor()273 private Executor getExecutor() { 274 return Runnable::run; 275 } 276 getDvrSettings()277 private DvrSettings getDvrSettings() { 278 return DvrSettings 279 .builder() 280 .setStatusMask(Filter.STATUS_DATA_READY) 281 .setLowThreshold(200L) 282 .setHighThreshold(800L) 283 .setPacketSize(188L) 284 .setDataFormat(DvrSettings.DATA_FORMAT_TS) 285 .build(); 286 } 287 getFilterCallback()288 private FilterCallback getFilterCallback() { 289 return new FilterCallback() { 290 @Override 291 public void onFilterEvent(Filter filter, FilterEvent[] events) {} 292 @Override 293 public void onFilterStatusChanged(Filter filter, int status) {} 294 }; 295 } 296 hasTuner()297 private boolean hasTuner() { 298 // TODO: move to a Utils class. 299 return mContext.getPackageManager().hasSystemFeature("android.hardware.tv.tuner"); 300 } 301 } 302