Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2012 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.provider.cts;
     18 
     19 import android.provider.cts.R;
     20 
     21 import android.content.ContentResolver;
     22 import android.content.ContentUris;
     23 import android.content.ContentValues;
     24 import android.database.Cursor;
     25 import android.media.MediaCodecInfo;
     26 import android.media.MediaCodecList;
     27 import android.net.Uri;
     28 import android.os.Environment;
     29 import android.provider.MediaStore.Files;
     30 import android.provider.MediaStore.Video.Media;
     31 import android.provider.MediaStore.Video.Thumbnails;
     32 import android.provider.MediaStore.Video.VideoColumns;
     33 import android.test.AndroidTestCase;
     34 import android.util.Log;
     35 
     36 import com.android.compatibility.common.util.FileCopyHelper;
     37 import com.android.compatibility.common.util.MediaUtils;
     38 
     39 import java.io.File;
     40 import java.io.IOException;
     41 
     42 public class MediaStore_Video_ThumbnailsTest extends AndroidTestCase {
     43     private static final String TAG = "MediaStore_Video_ThumbnailsTest";
     44 
     45     private ContentResolver mResolver;
     46 
     47     private FileCopyHelper mFileHelper;
     48 
     49     private boolean hasCodec() {
     50         return MediaUtils.hasCodecForResourceAndDomain(
     51                 mContext, R.raw.testthumbvideo, "video/");
     52     }
     53 
     54     @Override
     55     protected void setUp() throws Exception {
     56         super.setUp();
     57         mResolver = mContext.getContentResolver();
     58         mFileHelper = new FileCopyHelper(mContext);
     59     }
     60 
     61     @Override
     62     protected void tearDown() throws Exception {
     63         mFileHelper.clear();
     64         super.tearDown();
     65     }
     66 
     67     public void testGetContentUri() {
     68         Uri internalUri = Thumbnails.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME);
     69         Uri externalUri = Thumbnails.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME);
     70         assertEquals(Thumbnails.INTERNAL_CONTENT_URI, internalUri);
     71         assertEquals(Thumbnails.EXTERNAL_CONTENT_URI, externalUri);
     72     }
     73 
     74     public void testGetThumbnail() throws Exception {
     75         // Insert a video into the provider.
     76         Uri videoUri = insertVideo();
     77         long videoId = ContentUris.parseId(videoUri);
     78         assertTrue(videoId != -1);
     79         assertEquals(ContentUris.withAppendedId(Media.EXTERNAL_CONTENT_URI, videoId),
     80                 videoUri);
     81 
     82         // Get the current thumbnail count for future comparison.
     83         int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
     84 
     85         // Don't run the test if the codec isn't supported.
     86         if (!hasCodec()) {
     87             // Calling getThumbnail should not generate a new thumbnail.
     88             assertNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
     89             Log.i(TAG, "SKIPPING testGetThumbnail(): codec not supported");
     90             return;
     91         }
     92 
     93         // Calling getThumbnail should generate a new thumbnail.
     94         assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
     95         assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MICRO_KIND, null));
     96 
     97         try {
     98             Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.FULL_SCREEN_KIND, null);
     99             fail();
    100         } catch (IllegalArgumentException e) {
    101             // Full screen thumbnails not supported by getThumbnail...
    102         }
    103 
    104         // Check that an additional thumbnails have been registered.
    105         int count2 = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
    106         assertTrue(count2 > count);
    107 
    108         Cursor c = mResolver.query(Thumbnails.EXTERNAL_CONTENT_URI,
    109                 new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.VIDEO_ID },
    110                 null, null, null);
    111 
    112         if (c.moveToLast()) {
    113             long vid = c.getLong(2);
    114             assertEquals(videoId, vid);
    115             String path = c.getString(1);
    116             assertTrue("thumbnail file does not exist", new File(path).exists());
    117             long id = c.getLong(0);
    118             mResolver.delete(ContentUris.withAppendedId(Thumbnails.EXTERNAL_CONTENT_URI, id),
    119                     null, null);
    120             assertFalse("thumbnail file should no longer exist", new File(path).exists());
    121         }
    122         c.close();
    123 
    124         assertEquals(1, mResolver.delete(videoUri, null, null));
    125     }
    126 
    127     public void testThumbnailGenerationAndCleanup() throws Exception {
    128 
    129         if (!hasCodec()) {
    130             // we don't support video, so no need to run the test
    131             Log.i(TAG, "SKIPPING testThumbnailGenerationAndCleanup(): codec not supported");
    132             return;
    133         }
    134 
    135         // insert a video
    136         Uri uri = insertVideo();
    137 
    138         // request thumbnail creation
    139         Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
    140                 Thumbnails.MINI_KIND, null /* options */);
    141 
    142         // query the thumbnail
    143         Cursor c = mResolver.query(
    144                 Thumbnails.EXTERNAL_CONTENT_URI,
    145                 new String [] {Thumbnails.DATA},
    146                 "video_id=?",
    147                 new String[] {uri.getLastPathSegment()},
    148                 null /* sort */
    149                 );
    150         assertTrue("couldn't find thumbnail", c.moveToNext());
    151         String path = c.getString(0);
    152         c.close();
    153         assertTrue("thumbnail does not exist", new File(path).exists());
    154 
    155         // delete the source video and check that the thumbnail is gone too
    156         mResolver.delete(uri, null /* where clause */, null /* where args */);
    157         assertFalse("thumbnail still exists after source file delete", new File(path).exists());
    158 
    159         // insert again
    160         uri = insertVideo();
    161 
    162         // request thumbnail creation
    163         Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
    164                 Thumbnails.MINI_KIND, null);
    165 
    166         // query its thumbnail again
    167         c = mResolver.query(
    168                 Thumbnails.EXTERNAL_CONTENT_URI,
    169                 new String [] {Thumbnails.DATA},
    170                 "video_id=?",
    171                 new String[] {uri.getLastPathSegment()},
    172                 null /* sort */
    173                 );
    174         assertTrue("couldn't find thumbnail", c.moveToNext());
    175         path = c.getString(0);
    176         c.close();
    177         assertTrue("thumbnail does not exist", new File(path).exists());
    178 
    179         // update the media type
    180         ContentValues values = new ContentValues();
    181         values.put("media_type", 0);
    182         assertEquals("unexpected number of updated rows",
    183                 1, mResolver.update(uri, values, null /* where */, null /* where args */));
    184 
    185         // video was marked as regular file in the database, which should have deleted its thumbnail
    186 
    187         // query its thumbnail again
    188         c = mResolver.query(
    189                 Thumbnails.EXTERNAL_CONTENT_URI,
    190                 new String [] {Thumbnails.DATA},
    191                 "video_id=?",
    192                 new String[] {uri.getLastPathSegment()},
    193                 null /* sort */
    194                 );
    195         if (c != null) {
    196             assertFalse("thumbnail entry exists for non-thumbnail file", c.moveToNext());
    197             c.close();
    198         }
    199         assertFalse("thumbnail remains after source file type change", new File(path).exists());
    200 
    201         // check source no longer exists as video
    202         c = mResolver.query(uri,
    203                 null /* projection */, null /* where */, null /* where args */, null /* sort */);
    204         assertFalse("source entry should be gone", c.moveToNext());
    205         c.close();
    206 
    207         // check source still exists as file
    208         Uri fileUri = ContentUris.withAppendedId(
    209                 Files.getContentUri("external"),
    210                 Long.valueOf(uri.getLastPathSegment()));
    211         c = mResolver.query(fileUri,
    212                 null /* projection */, null /* where */, null /* where args */, null /* sort */);
    213         assertTrue("source entry should be gone", c.moveToNext());
    214         String sourcePath = c.getString(c.getColumnIndex("_data"));
    215         c.close();
    216 
    217         // clean up
    218         mResolver.delete(uri, null /* where */, null /* where args */);
    219         new File(sourcePath).delete();
    220     }
    221 
    222     private Uri insertVideo() throws IOException {
    223         File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
    224         // clean up any potential left over entries from a previous aborted run
    225         mResolver.delete(Media.EXTERNAL_CONTENT_URI,
    226                 "_data=?", new String[] { file.getAbsolutePath() });
    227         file.delete();
    228         mFileHelper.copyToExternalStorage(R.raw.testthumbvideo, file);
    229 
    230         ContentValues values = new ContentValues();
    231         values.put(VideoColumns.DATA, file.getAbsolutePath());
    232         return mResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
    233     }
    234 
    235     private int getThumbnailCount(Uri uri) {
    236         Cursor cursor = mResolver.query(uri, null, null, null, null);
    237         try {
    238             return cursor.getCount();
    239         } finally {
    240             cursor.close();
    241         }
    242     }
    243 }
    244