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