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 
     20 import android.content.ContentResolver;
     21 import android.content.ContentValues;
     22 import android.database.Cursor;
     23 import android.database.SQLException;
     24 import android.net.Uri;
     25 import android.provider.MediaStore.Audio.Genres;
     26 import android.provider.MediaStore.Audio.Media;
     27 import android.provider.MediaStore.Audio.Genres.Members;
     28 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
     29 import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
     30 import android.test.InstrumentationTestCase;
     31 
     32 public class MediaStore_Audio_Genres_MembersTest extends InstrumentationTestCase {
     33     private ContentResolver mContentResolver;
     34 
     35     private long mAudioIdOfJam;
     36 
     37     private long mAudioIdOfJamLive;
     38 
     39     @Override
     40     protected void setUp() throws Exception {
     41         super.setUp();
     42 
     43         mContentResolver = getInstrumentation().getContext().getContentResolver();
     44         Uri uri = Audio1.getInstance().insertToExternal(mContentResolver);
     45         Cursor c = mContentResolver.query(uri, null, null, null, null);
     46         c.moveToFirst();
     47         mAudioIdOfJam = c.getLong(c.getColumnIndex(Media._ID));
     48         c.close();
     49 
     50         uri = Audio2.getInstance().insertToExternal(mContentResolver);
     51         c = mContentResolver.query(uri, null, null, null, null);
     52         c.moveToFirst();
     53         mAudioIdOfJamLive = c.getLong(c.getColumnIndex(Media._ID));
     54         c.close();
     55     }
     56 
     57     @Override
     58     protected void tearDown() throws Exception {
     59         // "jam" should already have been deleted as part of the test, but delete it again just
     60         // in case the test failed and aborted before that.
     61         mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJam, null);
     62         mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJamLive,
     63                 null);
     64         super.tearDown();
     65     }
     66 
     67     public void testGetContentUri() {
     68         Cursor c = null;
     69         assertNotNull(c = mContentResolver.query(
     70                 Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, 1), null,
     71                     null, null, null));
     72         c.close();
     73 
     74         try {
     75             assertNotNull(c = mContentResolver.query(
     76                     Members.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME, 1), null,
     77                         null, null, null));
     78             c.close();
     79             fail("Should throw SQLException as the internal datatbase has no genre");
     80         } catch (SQLException e) {
     81             // expected
     82         }
     83 
     84         // can not accept any other volume names
     85         String volume = "fakeVolume";
     86         assertNull(mContentResolver.query(Members.getContentUri(volume, 1), null, null, null,
     87                 null));
     88     }
     89 
     90     public void testStoreAudioGenresMembersExternal() {
     91         ContentValues values = new ContentValues();
     92         values.put(Genres.NAME, Audio1.GENRE);
     93         Uri uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
     94         Cursor c = mContentResolver.query(uri, null, null, null, null);
     95         c.moveToFirst();
     96 
     97         long genreId = c.getLong(c.getColumnIndex(Genres._ID));
     98         long genre2Id = -1; // used later
     99         c.close();
    100 
    101         // verify that the Uri has the correct format and genre value
    102         assertEquals(uri.toString(), "content://media/external/audio/genres/" + genreId);
    103 
    104         // insert audio as the member of the genre
    105         values.clear();
    106         values.put(Members.AUDIO_ID, mAudioIdOfJam);
    107         Uri membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
    108                 genreId);
    109         assertNotNull(mContentResolver.insert(membersUri, values));
    110 
    111         try {
    112             // query, slow path
    113             c = mContentResolver.query(membersUri, null, null, null, null);
    114 
    115             assertEquals(1, c.getCount());
    116             c.moveToFirst();
    117 
    118             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members.AUDIO_ID)));
    119             assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
    120             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members._ID)));
    121             assertEquals(Audio1.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
    122             assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
    123             assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
    124             assertEquals(Audio1.FILE_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
    125             assertEquals(Audio1.MIME_TYPE, c.getString(c.getColumnIndex(Members.MIME_TYPE)));
    126             assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
    127             assertEquals(Audio1.TITLE, c.getString(c.getColumnIndex(Members.TITLE)));
    128             assertEquals(Audio1.ALBUM, c.getString(c.getColumnIndex(Members.ALBUM)));
    129             assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
    130             String albumKey = c.getString(c.getColumnIndex(Members.ALBUM_KEY));
    131             assertNotNull(albumKey);
    132             long albumId = c.getLong(c.getColumnIndex(Members.ALBUM_ID));
    133             assertTrue(albumId > 0);
    134             assertEquals(Audio1.ARTIST, c.getString(c.getColumnIndex(Members.ARTIST)));
    135             String artistKey = c.getString(c.getColumnIndex(Members.ARTIST_KEY));
    136             assertNotNull(artistKey);
    137             long artistId = c.getLong(c.getColumnIndex(Members.ARTIST_ID));
    138             assertTrue(artistId > 0);
    139             assertEquals(Audio1.COMPOSER, c.getString(c.getColumnIndex(Members.COMPOSER)));
    140             assertEquals(Audio1.DURATION, c.getLong(c.getColumnIndex(Members.DURATION)));
    141             assertEquals(Audio1.IS_ALARM, c.getInt(c.getColumnIndex(Members.IS_ALARM)));
    142             assertEquals(Audio1.IS_MUSIC, c.getInt(c.getColumnIndex(Members.IS_MUSIC)));
    143             assertEquals(Audio1.IS_NOTIFICATION,
    144                     c.getInt(c.getColumnIndex(Members.IS_NOTIFICATION)));
    145             assertEquals(Audio1.IS_RINGTONE, c.getInt(c.getColumnIndex(Members.IS_RINGTONE)));
    146             assertEquals(Audio1.TRACK, c.getInt(c.getColumnIndex(Members.TRACK)));
    147             assertEquals(Audio1.YEAR, c.getInt(c.getColumnIndex(Members.YEAR)));
    148             String titleKey = c.getString(c.getColumnIndex(Members.TITLE_KEY));
    149             assertNotNull(titleKey);
    150             c.close();
    151 
    152             // query again, fast path
    153             c = mContentResolver.query(membersUri,
    154                     new String[] { Members.AUDIO_ID, Members.GENRE_ID},
    155                     null, null, null);
    156             assertEquals(1, c.getCount());
    157             c.moveToFirst();
    158             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members.AUDIO_ID)));
    159             assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
    160             c.close();
    161 
    162             // Query with a constraint on _id. Note that _id corresponds to the _id
    163             // column in the audio table, not the one in the audio_genres_map table.
    164             // We need to preserve this behavior for backward compatibility.
    165             c = mContentResolver.query(membersUri, null,
    166                     Members._ID + "=?", new String[] {Long.toString(mAudioIdOfJam)}, null);
    167             assertEquals(1, c.getCount());
    168             c.moveToFirst();
    169             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members._ID)));
    170             c.close();
    171 
    172             // Query members across all genres
    173             Uri allMembersUri = Uri.parse("content://media/external/audio/genres/all/members");
    174             c = mContentResolver.query(allMembersUri, null, null, null, null);
    175             int colidx = c.getColumnIndex(Members.AUDIO_ID);
    176             int jamcnt = 0;
    177             // The song should appear only once, for the genre we used when inserting it
    178             while(c.moveToNext()) {
    179                 if (c.getLong(colidx) == mAudioIdOfJam) {
    180                     jamcnt++;
    181                     assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
    182                 }
    183             }
    184             assertEquals(1, jamcnt);
    185             c.close();
    186 
    187             // Query the same Uri, but add a where clause to restrict it to the one entry we added
    188             c = mContentResolver.query(allMembersUri, null,
    189                     Members.AUDIO_ID + "=?", new String[] {Long.toString(mAudioIdOfJam)}, null);
    190             assertEquals(1, c.getCount());
    191             c.moveToFirst();
    192             assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
    193             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members.AUDIO_ID)));
    194             c.close();
    195 
    196             // create another genre
    197             values.clear();
    198             values.put(Genres.NAME, Audio1.GENRE + "-2");
    199             uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
    200             c = mContentResolver.query(uri, null, null, null, null);
    201             c.moveToFirst();
    202             genre2Id = c.getLong(c.getColumnIndex(Genres._ID));
    203             c.close();
    204 
    205             // insert the song into the second genre
    206             values.clear();
    207             values.put(Members.AUDIO_ID, mAudioIdOfJam);
    208             Uri members2Uri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
    209                 genre2Id);
    210             assertNotNull(mContentResolver.insert(members2Uri, values));
    211 
    212             // Query members across all genres again
    213             c = mContentResolver.query(allMembersUri, null, null, null, null);
    214             colidx = c.getColumnIndex(Members.AUDIO_ID);
    215             int jamcnt1 = 0;
    216             int jamcnt2 = 0;
    217             // This time the song should appear twice, once for each genre
    218             while(c.moveToNext()) {
    219                 if (c.getLong(colidx) == mAudioIdOfJam) {
    220                     long g = c.getLong(c.getColumnIndex(Members.GENRE_ID));
    221                     if (g == genreId) {
    222                         jamcnt1++;
    223                     } else if (g == genre2Id) {
    224                         jamcnt2++;
    225                     } else {
    226                         fail("wrong genre found");
    227                     }
    228                 }
    229             }
    230             assertEquals(1, jamcnt1);
    231             assertEquals(1, jamcnt2);
    232             c.close();
    233 
    234 
    235             // update the member
    236             values.clear();
    237             values.put(Members.AUDIO_ID, mAudioIdOfJamLive);
    238             try {
    239                 mContentResolver.update(membersUri, values, null, null);
    240                 fail("Should throw SQLException because there is no column with name "
    241                         + "\"Members.AUDIO_ID\" in the table");
    242             } catch (SQLException e) {
    243                 // expected
    244             }
    245 
    246             // Delete the members, note that this does not delete the genre itself
    247             assertEquals(1, mContentResolver.delete(membersUri, null, null)); // check number of rows deleted
    248 
    249             // verify the genre is now empty
    250             c = mContentResolver.query(membersUri, null, null, null, null);
    251             assertEquals(0, c.getCount());
    252             c.close();
    253 
    254             // same for 2nd genre
    255             assertEquals(1, mContentResolver.delete(members2Uri, null, null));
    256             c = mContentResolver.query(members2Uri, null, null, null, null);
    257             assertEquals(0, c.getCount());
    258             c.close();
    259 
    260             // insert again, then verify that deleting the audio entry cleans up its genre member
    261             // entry as well
    262             values.put(Members.AUDIO_ID, mAudioIdOfJam);
    263             membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
    264                     genreId);
    265             assertNotNull(mContentResolver.insert(membersUri, values));
    266             // Query members across all genres
    267             c = mContentResolver.query(allMembersUri,
    268                     new String[] { Members.AUDIO_ID, Members.GENRE_ID}, null, null, null);
    269             colidx = c.getColumnIndex(Members.AUDIO_ID);
    270             jamcnt = 0;
    271             // The song should appear only once, for the genre we used when inserting it
    272             while(c.moveToNext()) {
    273                 if (c.getLong(colidx) == mAudioIdOfJam) {
    274                     jamcnt++;
    275                     assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
    276                 }
    277             }
    278             assertEquals(1, jamcnt);
    279             c.close();
    280             mContentResolver.delete(Media.EXTERNAL_CONTENT_URI,
    281                     Media._ID + "=" + mAudioIdOfJam, null);
    282             // Query members across all genres
    283             c = mContentResolver.query(allMembersUri,
    284                     new String[] { Members.AUDIO_ID, Members.GENRE_ID}, null, null, null);
    285             colidx = c.getColumnIndex(Members.AUDIO_ID);
    286             jamcnt = 0;
    287             // The song should no longer appear in the genre
    288             while(c.moveToNext()) {
    289                 if (c.getLong(colidx) == mAudioIdOfJam) {
    290                     jamcnt++;
    291                 }
    292             }
    293             assertEquals(0, jamcnt);
    294             c.close();
    295         } finally {
    296             // the members are deleted when deleting the genre which they belong to
    297             mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genreId, null);
    298             if (genre2Id >= 0) {
    299                 mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genre2Id, null);
    300             }
    301             c = mContentResolver.query(membersUri, null, null, null, null);
    302             assertEquals(0, c.getCount());
    303             c.close();
    304         }
    305     }
    306 
    307     public void testStoreAudioGenresMembersInternal() {
    308         // the internal database can not have genres
    309         ContentValues values = new ContentValues();
    310         values.put(Genres.NAME, Audio1.GENRE);
    311         Uri uri = mContentResolver.insert(Genres.INTERNAL_CONTENT_URI, values);
    312         assertNull(uri);
    313     }
    314 }
    315