1/*
2 * Copyright (C) 2011 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
17package com.android.mediaframeworktest.unit;
18
19import static org.mockito.Mockito.never;
20import static org.mockito.Mockito.times;
21import static org.mockito.Mockito.verify;
22import static org.mockito.Mockito.when;
23import static org.mockito.Matchers.argThat;
24import static org.mockito.Matchers.any;
25import static org.mockito.Matchers.eq;
26
27import android.content.ContentProviderClient;
28import android.content.ContentValues;
29import android.content.IContentProvider;
30import android.media.MediaInserter;
31import android.net.Uri;
32import android.provider.MediaStore.Audio;
33import android.provider.MediaStore.Files;
34import android.provider.MediaStore.Images;
35import android.provider.MediaStore.Video;
36import android.test.InstrumentationTestCase;
37import android.test.suitebuilder.annotation.SmallTest;
38
39import org.hamcrest.Description;
40import org.mockito.Mock;
41import org.mockito.MockitoAnnotations;
42import org.mockito.compat.ArgumentMatcher;
43
44public class MediaInserterTest extends InstrumentationTestCase {
45
46    private MediaInserter mMediaInserter;
47    private static final int TEST_BUFFER_SIZE = 10;
48    private @Mock IContentProvider mMockProvider;
49    private String mPackageName;
50
51    private int mFilesCounter;
52    private int mAudioCounter;
53    private int mVideoCounter;
54    private int mImagesCounter;
55
56    private static final String sVolumeName = "external";
57    private static final Uri sAudioUri = Audio.Media.getContentUri(sVolumeName);
58    private static final Uri sVideoUri = Video.Media.getContentUri(sVolumeName);
59    private static final Uri sImagesUri = Images.Media.getContentUri(sVolumeName);
60    private static final Uri sFilesUri = Files.getContentUri(sVolumeName);
61
62    private static class MediaUriMatcher extends ArgumentMatcher<Uri> {
63        private final Uri mUri;
64
65        private MediaUriMatcher(Uri uri) {
66            mUri = uri;
67        }
68
69        @Override
70        public boolean matchesObject(Object argument) {
71            if (!(argument instanceof Uri)) {
72                return false;
73            }
74
75            Uri actualUri = (Uri) argument;
76            if (actualUri == mUri)
77                return true;
78            return false;
79        }
80
81        @Override
82        public String toString() {
83            return "expected a TableUri '" + mUri.toString() + "'";
84        }
85    }
86
87    private static Uri eqUri(Uri in) {
88        return argThat(new MediaUriMatcher(in));
89    }
90
91    @Override
92    protected void setUp() throws Exception {
93        super.setUp();
94        MockitoAnnotations.initMocks(this);
95
96        final ContentProviderClient client = new ContentProviderClient(
97                getInstrumentation().getContext().getContentResolver(), mMockProvider, true);
98        mMediaInserter = new MediaInserter(client, TEST_BUFFER_SIZE);
99        mPackageName = getInstrumentation().getContext().getPackageName();
100        mFilesCounter = 0;
101        mAudioCounter = 0;
102        mVideoCounter = 0;
103        mImagesCounter = 0;
104    }
105
106    private ContentValues createFileContent() {
107        ContentValues values = new ContentValues();
108        values.put("_data", "/mnt/sdcard/file" + ++mFilesCounter);
109        return values;
110    }
111
112    private ContentValues createAudioContent() {
113        ContentValues values = new ContentValues();
114        values.put("_data", "/mnt/sdcard/audio" + ++mAudioCounter);
115        return values;
116    }
117
118    private ContentValues createVideoContent() {
119        ContentValues values = new ContentValues();
120        values.put("_data", "/mnt/sdcard/video" + ++mVideoCounter);
121        return values;
122    }
123
124    private ContentValues createImageContent() {
125        ContentValues values = new ContentValues();
126        values.put("_data", "/mnt/sdcard/image" + ++mImagesCounter);
127        return values;
128    }
129
130    private ContentValues createContent(Uri uri) {
131        if (uri == sFilesUri) return createFileContent();
132        else if (uri == sAudioUri) return createAudioContent();
133        else if (uri == sVideoUri) return createVideoContent();
134        else if (uri == sImagesUri) return createImageContent();
135        else throw new IllegalArgumentException("Unknown URL: " + uri.toString());
136    }
137
138    private void fillBuffer(Uri uri, int numberOfFiles) throws Exception {
139        ContentValues values;
140        for (int i = 0; i < numberOfFiles; ++i) {
141            values = createContent(uri);
142            mMediaInserter.insert(uri, values);
143        }
144    }
145
146    @SmallTest
147    public void testInsertContentsLessThanBufferSize() throws Exception {
148        fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
149        fillBuffer(sAudioUri, TEST_BUFFER_SIZE - 3);
150        fillBuffer(sVideoUri, TEST_BUFFER_SIZE - 2);
151        fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
152
153        verify(mMockProvider, never()).bulkInsert(eq(mPackageName), any(), any());
154    }
155
156    @SmallTest
157    public void testInsertContentsEqualToBufferSize() throws Exception {
158        when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
159
160        fillBuffer(sFilesUri, TEST_BUFFER_SIZE);
161        fillBuffer(sAudioUri, TEST_BUFFER_SIZE);
162        fillBuffer(sVideoUri, TEST_BUFFER_SIZE);
163        fillBuffer(sImagesUri, TEST_BUFFER_SIZE);
164
165        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
166    }
167
168    @SmallTest
169    public void testInsertContentsMoreThanBufferSize() throws Exception {
170        when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
171
172        fillBuffer(sFilesUri, TEST_BUFFER_SIZE + 1);
173        fillBuffer(sAudioUri, TEST_BUFFER_SIZE + 2);
174        fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
175        fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
176
177        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
178    }
179
180    @SmallTest
181    public void testFlushAllWithEmptyContents() throws Exception {
182        mMediaInserter.flushAll();
183    }
184
185    @SmallTest
186    public void testFlushAllWithSomeContents() throws Exception {
187        when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
188
189        fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
190        fillBuffer(sAudioUri, TEST_BUFFER_SIZE - 3);
191        fillBuffer(sVideoUri, TEST_BUFFER_SIZE - 2);
192        fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
193        mMediaInserter.flushAll();
194
195        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), any(), any());
196    }
197
198    @SmallTest
199    public void testInsertContentsAfterFlushAll() throws Exception {
200        when(mMockProvider.bulkInsert(eq(mPackageName), any(), any())).thenReturn(1);
201
202        fillBuffer(sFilesUri, TEST_BUFFER_SIZE - 4);
203        fillBuffer(sAudioUri, TEST_BUFFER_SIZE - 3);
204        fillBuffer(sVideoUri, TEST_BUFFER_SIZE - 2);
205        fillBuffer(sImagesUri, TEST_BUFFER_SIZE - 1);
206        mMediaInserter.flushAll();
207
208        fillBuffer(sFilesUri, TEST_BUFFER_SIZE + 1);
209        fillBuffer(sAudioUri, TEST_BUFFER_SIZE + 2);
210        fillBuffer(sVideoUri, TEST_BUFFER_SIZE + 3);
211        fillBuffer(sImagesUri, TEST_BUFFER_SIZE + 4);
212
213        verify(mMockProvider, times(8)).bulkInsert(eq(mPackageName), any(), any());
214    }
215
216    @SmallTest
217    public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
218        when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sFilesUri), any())).thenReturn(1);
219        when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sAudioUri), any())).thenReturn(1);
220        when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sVideoUri), any())).thenReturn(1);
221        when(mMockProvider.bulkInsert(eq(mPackageName), eqUri(sImagesUri), any())).thenReturn(1);
222
223        for (int i = 0; i < TEST_BUFFER_SIZE; ++i) {
224            fillBuffer(sFilesUri, 1);
225            fillBuffer(sAudioUri, 2);
226            fillBuffer(sVideoUri, 3);
227            fillBuffer(sImagesUri, 4);
228        }
229
230        verify(mMockProvider, times(1)).bulkInsert(eq(mPackageName), eqUri(sFilesUri), any());
231        verify(mMockProvider, times(2)).bulkInsert(eq(mPackageName), eqUri(sAudioUri), any());
232        verify(mMockProvider, times(3)).bulkInsert(eq(mPackageName), eqUri(sVideoUri), any());
233        verify(mMockProvider, times(4)).bulkInsert(eq(mPackageName), eqUri(sImagesUri), any());
234    }
235}
236