1cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang/* 2cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * Copyright 2018 The Android Open Source Project 3cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * 4cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * Licensed under the Apache License, Version 2.0 (the "License"); 5cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * you may not use this file except in compliance with the License. 6cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * You may obtain a copy of the License at 7cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * 8cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * http://www.apache.org/licenses/LICENSE-2.0 9cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * 10cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * Unless required by applicable law or agreed to in writing, software 11cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * distributed under the License is distributed on an "AS IS" BASIS, 12cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * See the License for the specific language governing permissions and 14cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * limitations under the License. 15cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang */ 16cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 17cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangpackage androidx.media; 18cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 19cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangimport android.content.res.AssetFileDescriptor; 20cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangimport android.util.Log; 21cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 22cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangimport java.io.IOException; 23cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangimport java.io.InputStream; 24cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 25cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang/** 26cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang * A Media2DataSource that reads from a byte array for use in tests. 27cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang */ 28cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kangpublic class TestMedia2DataSource extends Media2DataSource { 29cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private static final String TAG = "TestMedia2DataSource"; 30cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 31cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private byte[] mData; 32cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 33cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private boolean mThrowFromReadAt; 34cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private boolean mThrowFromGetSize; 35cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private Integer mReturnFromReadAt; 36cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private Long mReturnFromGetSize; 37cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang private boolean mIsClosed; 38cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 39cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang // Read an asset fd into a new byte array data source. Closes afd. 40cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public static TestMedia2DataSource fromAssetFd(AssetFileDescriptor afd) throws IOException { 41cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang try { 42cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang InputStream in = afd.createInputStream(); 43cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang final int size = (int) afd.getDeclaredLength(); 44cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang byte[] data = new byte[(int) size]; 45cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang int writeIndex = 0; 46cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang int numRead = 0; 47cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang do { 48cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang numRead = in.read(data, writeIndex, size - writeIndex); 49cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang writeIndex += numRead; 50cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } while (numRead >= 0); 51cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return new TestMedia2DataSource(data); 52cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } finally { 53cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang afd.close(); 54cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 55cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 56cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 57cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public TestMedia2DataSource(byte[] data) { 58cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mData = data; 59cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 60cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 61cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang @Override 62cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public synchronized int readAt(long position, byte[] buffer, int offset, int size) 63cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang throws IOException { 64cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (mThrowFromReadAt) { 65cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang throw new IOException("Test exception from readAt()"); 66cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 67cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (mReturnFromReadAt != null) { 68cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return mReturnFromReadAt; 69cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 70cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 71cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang // Clamp reads past the end of the source. 72cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (position >= mData.length) { 73cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return -1; // -1 indicates EOF 74cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 75cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (position + size > mData.length) { 76cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang size -= (position + size) - mData.length; 77cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 78cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang System.arraycopy(mData, (int) position, buffer, offset, size); 79cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return size; 80cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 81cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 82cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang @Override 83cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public synchronized long getSize() throws IOException { 84cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (mThrowFromGetSize) { 85cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang throw new IOException("Test exception from getSize()"); 86cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 87cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang if (mReturnFromGetSize != null) { 88cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return mReturnFromGetSize; 89cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 90cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 91cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang Log.v(TAG, "getSize: " + mData.length); 92cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return mData.length; 93cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 94cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 95cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang // Note: it's fine to keep using this data source after closing it. 96cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang @Override 97cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public synchronized void close() { 98cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang Log.v(TAG, "close()"); 99cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mIsClosed = true; 100cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 101cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 102cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang // Whether close() has been called. 103cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public synchronized boolean isClosed() { 104cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang return mIsClosed; 105cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 106cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 107cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public void throwFromReadAt() { 108cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mThrowFromReadAt = true; 109cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 110cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 111cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public void throwFromGetSize() { 112cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mThrowFromGetSize = true; 113cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 114cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 115cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public void returnFromReadAt(int numRead) { 116cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mReturnFromReadAt = numRead; 117cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 118cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 119cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang public void returnFromGetSize(long size) { 120cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang mReturnFromGetSize = size; 121cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang } 122cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang} 123cc070c306ccc400a93f0b5501bf28591fb002d45Insun Kang 124