Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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 com.android.cts.provider.R;
     20 
     21 import android.content.ContentResolver;
     22 import android.content.ContentValues;
     23 import android.content.Context;
     24 import android.cts.util.FileCopyHelper;
     25 import android.cts.util.FileUtils;
     26 import android.database.Cursor;
     27 import android.graphics.Bitmap;
     28 import android.graphics.BitmapFactory;
     29 import android.net.Uri;
     30 import android.os.Environment;
     31 import android.provider.MediaStore.Images.Media;
     32 import android.provider.MediaStore.Images.Thumbnails;
     33 import android.test.InstrumentationTestCase;
     34 
     35 import java.io.File;
     36 import java.io.FileNotFoundException;
     37 import java.lang.Math;
     38 import java.util.ArrayList;
     39 
     40 public class MediaStore_Images_MediaTest extends InstrumentationTestCase {
     41     private static final String MIME_TYPE_JPEG = "image/jpeg";
     42 
     43     private static final String TEST_TITLE1 = "test title1";
     44 
     45     private static final String TEST_DESCRIPTION1 = "test description1";
     46 
     47     private static final String TEST_TITLE2 = "test title2";
     48 
     49     private static final String TEST_DESCRIPTION2 = "test description2";
     50 
     51     private static final String TEST_TITLE3 = "test title3";
     52 
     53     private static final String TEST_DESCRIPTION3 = "test description3";
     54 
     55     private ArrayList<Uri> mRowsAdded;
     56 
     57     private Context mContext;
     58 
     59     private ContentResolver mContentResolver;
     60 
     61     private FileCopyHelper mHelper;
     62 
     63     @Override
     64     protected void tearDown() throws Exception {
     65         for (Uri row : mRowsAdded) {
     66             mContentResolver.delete(row, null, null);
     67         }
     68 
     69         mHelper.clear();
     70         super.tearDown();
     71     }
     72 
     73     @Override
     74     protected void setUp() throws Exception {
     75         super.setUp();
     76 
     77         mContext = getInstrumentation().getTargetContext();
     78         mContentResolver = mContext.getContentResolver();
     79 
     80         mHelper = new FileCopyHelper(mContext);
     81         mRowsAdded = new ArrayList<Uri>();
     82     }
     83 
     84     public void testInsertImageWithImagePath() throws Exception {
     85         Cursor c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI, null, null,
     86                 "_id ASC");
     87         int previousCount = c.getCount();
     88         c.close();
     89 
     90         // insert an image by path
     91         String path = mHelper.copy(R.raw.scenery, "mediaStoreTest1.jpg");
     92         String stringUrl = null;
     93         try {
     94             stringUrl = Media.insertImage(mContentResolver, path, TEST_TITLE1, TEST_DESCRIPTION1);
     95         } catch (FileNotFoundException e) {
     96             fail(e.getMessage());
     97         } catch (UnsupportedOperationException e) {
     98             // the tests will be aborted because the image will be put in sdcard
     99             fail("There is no sdcard attached! " + e.getMessage());
    100         }
    101         assertInsertionSuccess(stringUrl);
    102         mRowsAdded.add(Uri.parse(stringUrl));
    103 
    104         // insert another image by path
    105         path = mHelper.copy(R.raw.scenery, "mediaStoreTest2.jpg");
    106         stringUrl = null;
    107         try {
    108             stringUrl = Media.insertImage(mContentResolver, path, TEST_TITLE2, TEST_DESCRIPTION2);
    109         } catch (FileNotFoundException e) {
    110             fail(e.getMessage());
    111         } catch (UnsupportedOperationException e) {
    112             // the tests will be aborted because the image will be put in sdcard
    113             fail("There is no sdcard attached! " + e.getMessage());
    114         }
    115         assertInsertionSuccess(stringUrl);
    116         mRowsAdded.add(Uri.parse(stringUrl));
    117 
    118         // query the newly added image
    119         c = Media.query(mContentResolver, Uri.parse(stringUrl),
    120                 new String[] { Media.TITLE, Media.DESCRIPTION, Media.MIME_TYPE });
    121         assertEquals(1, c.getCount());
    122         c.moveToFirst();
    123         assertEquals(TEST_TITLE2, c.getString(c.getColumnIndex(Media.TITLE)));
    124         assertEquals(TEST_DESCRIPTION2, c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    125         assertEquals(MIME_TYPE_JPEG, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    126         c.close();
    127 
    128         // query all the images in external db and order them by descending id
    129         // (make the images added in test case in the first positions)
    130         c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI,
    131                 new String[] { Media.TITLE, Media.DESCRIPTION, Media.MIME_TYPE }, null,
    132                 "_id DESC");
    133         assertEquals(previousCount + 2, c.getCount());
    134         c.moveToFirst();
    135         assertEquals(TEST_TITLE2, c.getString(c.getColumnIndex(Media.TITLE)));
    136         assertEquals(TEST_DESCRIPTION2, c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    137         assertEquals(MIME_TYPE_JPEG, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    138         c.moveToNext();
    139         assertEquals(TEST_TITLE1, c.getString(c.getColumnIndex(Media.TITLE)));
    140         assertEquals(TEST_DESCRIPTION1, c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    141         assertEquals(MIME_TYPE_JPEG, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    142         c.close();
    143 
    144         // query the second image added in the test
    145         c = Media.query(mContentResolver, Uri.parse(stringUrl),
    146                 new String[] { Media.DESCRIPTION, Media.MIME_TYPE }, Media.TITLE + "=?",
    147                 new String[] { TEST_TITLE2 }, "_id ASC");
    148         assertEquals(1, c.getCount());
    149         c.moveToFirst();
    150         assertEquals(TEST_DESCRIPTION2, c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    151         assertEquals(MIME_TYPE_JPEG, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    152         c.close();
    153     }
    154 
    155     public void testInsertImageWithBitmap() throws Exception {
    156         // insert the image by bitmap
    157         Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
    158         String stringUrl = null;
    159         try{
    160             stringUrl = Media.insertImage(mContentResolver, src, TEST_TITLE3, TEST_DESCRIPTION3);
    161         } catch (UnsupportedOperationException e) {
    162             // the tests will be aborted because the image will be put in sdcard
    163             fail("There is no sdcard attached! " + e.getMessage());
    164         }
    165         assertInsertionSuccess(stringUrl);
    166         mRowsAdded.add(Uri.parse(stringUrl));
    167 
    168         Cursor c = Media.query(mContentResolver, Uri.parse(stringUrl), new String[] { Media.DATA },
    169                 null, "_id ASC");
    170         c.moveToFirst();
    171         // get the bimap by the path
    172         Bitmap result = Media.getBitmap(mContentResolver,
    173                     Uri.fromFile(new File(c.getString(c.getColumnIndex(Media.DATA)))));
    174 
    175         // can not check the identity between the result and source bitmap because
    176         // source bitmap is compressed before it is saved as result bitmap
    177         assertEquals(src.getWidth(), result.getWidth());
    178         assertEquals(src.getHeight(), result.getHeight());
    179     }
    180 
    181     public void testGetContentUri() {
    182         Cursor c = null;
    183         assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
    184                 null));
    185         c.close();
    186         assertNotNull(c = mContentResolver.query(Media.getContentUri("external"), null, null, null,
    187                 null));
    188         c.close();
    189 
    190         // can not accept any other volume names
    191         String volume = "fakeVolume";
    192         assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
    193     }
    194 
    195     private void cleanExternalMediaFile(String path) {
    196         mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, "_data=?", new String[] { path });
    197         new File(path).delete();
    198     }
    199 
    200     public void testStoreImagesMediaExternal() throws Exception {
    201         final String externalPath = Environment.getExternalStorageDirectory().getPath() +
    202                 "/testimage.jpg";
    203         final String externalPath2 = Environment.getExternalStorageDirectory().getPath() +
    204                 "/testimage1.jpg";
    205 
    206         // clean up any potential left over entries from a previous aborted run
    207         cleanExternalMediaFile(externalPath);
    208         cleanExternalMediaFile(externalPath2);
    209 
    210         int numBytes = 1337;
    211         FileUtils.createFile(new File(externalPath), numBytes);
    212 
    213         ContentValues values = new ContentValues();
    214         values.put(Media.ORIENTATION, 0);
    215         values.put(Media.PICASA_ID, 0);
    216         long dateTaken = System.currentTimeMillis();
    217         values.put(Media.DATE_TAKEN, dateTaken);
    218         values.put(Media.DESCRIPTION, "This is a image");
    219         values.put(Media.LATITUDE, 40.689060d);
    220         values.put(Media.LONGITUDE, -74.044636d);
    221         values.put(Media.IS_PRIVATE, 1);
    222         values.put(Media.MINI_THUMB_MAGIC, 0);
    223         values.put(Media.DATA, externalPath);
    224         values.put(Media.DISPLAY_NAME, "testimage");
    225         values.put(Media.MIME_TYPE, "image/jpeg");
    226         values.put(Media.SIZE, numBytes);
    227         values.put(Media.TITLE, "testimage");
    228         long dateAdded = System.currentTimeMillis() / 1000;
    229         values.put(Media.DATE_ADDED, dateAdded);
    230         long dateModified = System.currentTimeMillis() / 1000;
    231         values.put(Media.DATE_MODIFIED, dateModified);
    232 
    233         // insert
    234         Uri uri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
    235         assertNotNull(uri);
    236 
    237         try {
    238             // query
    239             Cursor c = mContentResolver.query(uri, null, null, null, null);
    240             assertEquals(1, c.getCount());
    241             c.moveToFirst();
    242             long id = c.getLong(c.getColumnIndex(Media._ID));
    243             assertTrue(id > 0);
    244             assertEquals(0, c.getInt(c.getColumnIndex(Media.ORIENTATION)));
    245             assertEquals(0, c.getLong(c.getColumnIndex(Media.PICASA_ID)));
    246             assertEquals(dateTaken, c.getLong(c.getColumnIndex(Media.DATE_TAKEN)));
    247             assertEquals("This is a image",
    248                     c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    249             assertEquals(40.689060d, c.getDouble(c.getColumnIndex(Media.LATITUDE)), 0d);
    250             assertEquals(-74.044636d, c.getDouble(c.getColumnIndex(Media.LONGITUDE)), 0d);
    251             assertEquals(1, c.getInt(c.getColumnIndex(Media.IS_PRIVATE)));
    252             assertEquals(0, c.getLong(c.getColumnIndex(Media.MINI_THUMB_MAGIC)));
    253             assertEquals(externalPath, c.getString(c.getColumnIndex(Media.DATA)));
    254             assertEquals("testimage", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
    255             assertEquals("image/jpeg", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    256             assertEquals("testimage", c.getString(c.getColumnIndex(Media.TITLE)));
    257             assertEquals(numBytes, c.getInt(c.getColumnIndex(Media.SIZE)));
    258             long realDateAdded = c.getLong(c.getColumnIndex(Media.DATE_ADDED));
    259             assertTrue(realDateAdded >= dateAdded);
    260             // there can be delay as time is read after creation
    261             assertTrue(Math.abs(dateModified - c.getLong(c.getColumnIndex(Media.DATE_MODIFIED)))
    262                        < 5);
    263             c.close();
    264 
    265             // update
    266             values.clear();
    267             values.put(Media.ORIENTATION, 90);
    268             values.put(Media.PICASA_ID, 10);
    269             dateTaken = System.currentTimeMillis();
    270             values.put(Media.DATE_TAKEN, dateTaken);
    271             values.put(Media.DESCRIPTION, "This is another image");
    272             values.put(Media.LATITUDE, 41.689060d);
    273             values.put(Media.LONGITUDE, -75.044636d);
    274             values.put(Media.IS_PRIVATE, 0);
    275             values.put(Media.MINI_THUMB_MAGIC, 2);
    276             values.put(Media.DATA, externalPath2);
    277             values.put(Media.DISPLAY_NAME, "testimage1");
    278             values.put(Media.MIME_TYPE, "image/jpeg");
    279             values.put(Media.SIZE, 86854);
    280             values.put(Media.TITLE, "testimage1");
    281             dateModified = System.currentTimeMillis() / 1000;
    282             values.put(Media.DATE_MODIFIED, dateModified);
    283             assertEquals(1, mContentResolver.update(uri, values, null, null));
    284 
    285             c = mContentResolver.query(uri, null, null, null, null);
    286             assertEquals(1, c.getCount());
    287             c.moveToFirst();
    288             assertEquals(id, c.getLong(c.getColumnIndex(Media._ID)));
    289             assertEquals(90, c.getInt(c.getColumnIndex(Media.ORIENTATION)));
    290             assertEquals(10, c.getInt(c.getColumnIndex(Media.PICASA_ID)));
    291             assertEquals(dateTaken, c.getLong(c.getColumnIndex(Media.DATE_TAKEN)));
    292             assertEquals("This is another image",
    293                     c.getString(c.getColumnIndex(Media.DESCRIPTION)));
    294             assertEquals(41.689060d, c.getDouble(c.getColumnIndex(Media.LATITUDE)), 0d);
    295             assertEquals(-75.044636d, c.getDouble(c.getColumnIndex(Media.LONGITUDE)), 0d);
    296             assertEquals(0, c.getInt(c.getColumnIndex(Media.IS_PRIVATE)));
    297             assertEquals(2, c.getLong(c.getColumnIndex(Media.MINI_THUMB_MAGIC)));
    298             assertEquals(externalPath2,
    299                     c.getString(c.getColumnIndex(Media.DATA)));
    300             assertEquals("testimage1", c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
    301             assertEquals("image/jpeg", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
    302             assertEquals("testimage1", c.getString(c.getColumnIndex(Media.TITLE)));
    303             assertEquals(86854, c.getInt(c.getColumnIndex(Media.SIZE)));
    304             assertEquals(realDateAdded, c.getLong(c.getColumnIndex(Media.DATE_ADDED)));
    305             assertEquals(dateModified, c.getLong(c.getColumnIndex(Media.DATE_MODIFIED)));
    306             c.close();
    307         } finally {
    308             // delete
    309             assertEquals(1, mContentResolver.delete(uri, null, null));
    310             new File(externalPath).delete();
    311         }
    312     }
    313 
    314     public void testStoreImagesMediaInternal() {
    315         // can not insert any data, so other operations can not be tested
    316         try {
    317             mContentResolver.insert(Media.INTERNAL_CONTENT_URI, new ContentValues());
    318             fail("Should throw UnsupportedOperationException when inserting into internal "
    319                     + "database");
    320         } catch (UnsupportedOperationException e) {
    321         }
    322     }
    323 
    324     private void assertInsertionSuccess(String stringUrl) {
    325         assertNotNull(stringUrl);
    326         // check whether the thumbnails are generated
    327         Cursor c = mContentResolver.query(Uri.parse(stringUrl), new String[]{ Media._ID }, null,
    328                 null, null);
    329         assertTrue(c.moveToFirst());
    330         long imageId = c.getLong(c.getColumnIndex(Media._ID));
    331         c.close();
    332         assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
    333                 Thumbnails.MINI_KIND, null));
    334         assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
    335                 Thumbnails.MICRO_KIND, null));
    336         c = mContentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, null,
    337                 Thumbnails.IMAGE_ID + "=" + imageId, null, null);
    338         assertEquals(2, c.getCount());
    339         c.close();
    340     }
    341 }
    342