1b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen/* 2b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * Copyright (C) 2009 The Android Open Source Project 3b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * 4b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * you may not use this file except in compliance with the License. 6b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * You may obtain a copy of the License at 7b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * 8b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * http://www.apache.org/licenses/LICENSE-2.0 9b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * 10b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * Unless required by applicable law or agreed to in writing, software 11b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * distributed under the License is distributed on an "AS IS" BASIS, 12b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * See the License for the specific language governing permissions and 14b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * limitations under the License. 15b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen */ 16b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 17b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenpackage com.android.providers.media; 18b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 191373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chenimport java.io.ByteArrayOutputStream; 20b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport java.io.IOException; 217a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chenimport java.io.OutputStream; 22b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport java.util.Comparator; 23b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport java.util.Random; 24b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 25b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.content.ContentResolver; 26b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.content.ContentUris; 27b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.content.ContentValues; 28b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.database.Cursor; 29b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.graphics.Bitmap; 30b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.graphics.BitmapFactory; 31b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.media.MiniThumbFile; 32ee8598a7e70b10fbcb1c43ade5cf838c6172fe57Ray Chenimport android.media.ThumbnailUtils; 33b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.net.Uri; 3420434e032e498b716f87cce2f23dd646819218bfRay Chenimport android.os.Binder; 351373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chenimport android.os.ParcelFileDescriptor; 36b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.provider.BaseColumns; 3701a6f2f96c5b483f5281f6d3066380a129c06021Ray Chenimport android.provider.MediaStore.Images; 387a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chenimport android.provider.MediaStore.Video; 391373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chenimport android.provider.MediaStore.MediaColumns; 40b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.provider.MediaStore.Images.ImageColumns; 41b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenimport android.util.Log; 42b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 43b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen/** 44b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * Instances of this class are created and put in a queue to be executed sequentially to see if 45b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * it needs to (re)generate the thumbnails. 46b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen */ 47b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chenclass MediaThumbRequest { 48b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen private static final String TAG = "MediaThumbRequest"; 49b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen static final int PRIORITY_LOW = 20; 50b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen static final int PRIORITY_NORMAL = 10; 51b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen static final int PRIORITY_HIGH = 5; 5220434e032e498b716f87cce2f23dd646819218bfRay Chen static final int PRIORITY_CRITICAL = 0; 5320434e032e498b716f87cce2f23dd646819218bfRay Chen static enum State {WAIT, DONE, CANCEL} 54b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen private static final String[] THUMB_PROJECTION = new String[] { 55b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen BaseColumns._ID // 0 56b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen }; 57b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 58b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen ContentResolver mCr; 59b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen String mPath; 60b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen long mRequestTime = System.currentTimeMillis(); 6120434e032e498b716f87cce2f23dd646819218bfRay Chen int mCallingPid = Binder.getCallingPid(); 62e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen long mGroupId; 63b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen int mPriority; 64b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen Uri mUri; 657a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Uri mThumbUri; 667a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen String mOrigColumnName; 67b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen boolean mIsVideo; 68b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen long mOrigId; 6920434e032e498b716f87cce2f23dd646819218bfRay Chen State mState = State.WAIT; 70b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen long mMagic; 71b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 72bf86108d222677067674c0947e8dc2b2bc9cadc2John Eckerdal private static final Random sRandom = new Random(); 73b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 74b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen static Comparator<MediaThumbRequest> getComparator() { 75b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen return new Comparator<MediaThumbRequest>() { 76b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen public int compare(MediaThumbRequest r1, MediaThumbRequest r2) { 77b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (r1.mPriority != r2.mPriority) { 78b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen return r1.mPriority < r2.mPriority ? -1 : 1; 79b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 80b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen return r1.mRequestTime == r2.mRequestTime ? 0 : 81b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen r1.mRequestTime < r2.mRequestTime ? -1 : 1; 82b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 83b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen }; 84b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 85b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 869299727714ad25618a1a77eeca7f1e9c72f1e510Ray Chen MediaThumbRequest(ContentResolver cr, String path, Uri uri, int priority, long magic) { 87b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen mCr = cr; 88b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen mPath = path; 894d96d72ea42c2ec41a891f65623270473ae8eebdRay Chen mPriority = priority; 909299727714ad25618a1a77eeca7f1e9c72f1e510Ray Chen mMagic = magic; 91b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen mUri = uri; 92b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen mIsVideo = "video".equals(uri.getPathSegments().get(1)); 93b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen mOrigId = ContentUris.parseId(uri); 947a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen mThumbUri = mIsVideo 957a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen ? Video.Thumbnails.EXTERNAL_CONTENT_URI 967a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen : Images.Thumbnails.EXTERNAL_CONTENT_URI; 977a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen mOrigColumnName = mIsVideo 987a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen ? Video.Thumbnails.VIDEO_ID 997a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen : Images.Thumbnails.IMAGE_ID; 100e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen // Only requests from Thumbnail API has this group_id parameter. In other cases, 101e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen // mGroupId will always be zero and can't be canceled due to pid mismatch. 102e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen String groupIdParam = uri.getQueryParameter("group_id"); 103e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen if (groupIdParam != null) { 104e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen mGroupId = Long.parseLong(groupIdParam); 105e7219b83c17d75151746d6cad1b61d447910ae92Ray Chen } 106b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 107b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 10854cb8ab64f5cbd33257a926a6a2b588b3106b115Ray Chen Uri updateDatabase(Bitmap thumbnail) { 1097a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Cursor c = mCr.query(mThumbUri, THUMB_PROJECTION, 1107a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen mOrigColumnName+ " = " + mOrigId, null, null); 1117a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen if (c == null) return null; 1127a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen try { 1137a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen if (c.moveToFirst()) { 1147a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen return ContentUris.withAppendedId(mThumbUri, c.getLong(0)); 1157a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1167a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } finally { 1177a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen if (c != null) c.close(); 1187a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1197a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen 12054cb8ab64f5cbd33257a926a6a2b588b3106b115Ray Chen ContentValues values = new ContentValues(4); 1217a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen values.put(Images.Thumbnails.KIND, Images.Thumbnails.MINI_KIND); 1227a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen values.put(mOrigColumnName, mOrigId); 12354cb8ab64f5cbd33257a926a6a2b588b3106b115Ray Chen values.put(Images.Thumbnails.WIDTH, thumbnail.getWidth()); 12454cb8ab64f5cbd33257a926a6a2b588b3106b115Ray Chen values.put(Images.Thumbnails.HEIGHT, thumbnail.getHeight()); 1257a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen try { 1267a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen return mCr.insert(mThumbUri, values); 1277a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } catch (Exception ex) { 1287a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Log.w(TAG, ex); 1297a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen return null; 1307a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1317a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1327a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen 133b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen /** 134b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * Check if the corresponding thumbnail and mini-thumb have been created 135b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * for the given uri. This method creates both of them if they do not 136b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * exist yet or have been changed since last check. After thumbnails are 137b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * created, MINI_KIND thumbnail is stored in JPEG file and MICRO_KIND 138b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * thumbnail is stored in a random access file (MiniThumbFile). 139b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * 140b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen * @throws IOException 141b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen */ 142b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen void execute() throws IOException { 143b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen MiniThumbFile miniThumbFile = MiniThumbFile.instance(mUri); 144b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen long magic = mMagic; 145b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (magic != 0) { 146b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen long fileMagic = miniThumbFile.getMagic(mOrigId); 147b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (fileMagic == magic) { 1487a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Cursor c = null; 1491373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen ParcelFileDescriptor pfd = null; 1501373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen try { 1517a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen c = mCr.query(mThumbUri, THUMB_PROJECTION, 1527a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen mOrigColumnName + " = " + mOrigId, null, null); 1531373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen if (c != null && c.moveToFirst()) { 1541373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen pfd = mCr.openFileDescriptor( 1557a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen mThumbUri.buildUpon().appendPath(c.getString(0)).build(), "r"); 1561373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } 157cf85fbdb58b153eaa1876449dba0bff5ae66bea5Ray Chen } catch (IOException ex) { 158cf85fbdb58b153eaa1876449dba0bff5ae66bea5Ray Chen // MINI_THUMBNAIL not exists, ignore the exception and generate one. 1591373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } finally { 1601373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen if (c != null) c.close(); 1611373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen if (pfd != null) { 1621373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen pfd.close(); 1631373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen return; 1641373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } 1651373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } 166b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 167b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 168b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 169b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // If we can't retrieve the thumbnail, first check if there is one 170b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // embedded in the EXIF data. If not, or it's not big enough, 171b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // decompress the full size image. 172b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen Bitmap bitmap = null; 173b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 174b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (mPath != null) { 175b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (mIsVideo) { 1767a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen bitmap = ThumbnailUtils.createVideoThumbnail(mPath, 1777a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Video.Thumbnails.MINI_KIND); 178b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } else { 1797a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen bitmap = ThumbnailUtils.createImageThumbnail(mPath, 1807a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Images.Thumbnails.MINI_KIND); 1817a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1827a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen if (bitmap == null) { 1837a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen Log.w(TAG, "Can't create mini thumbnail for " + mPath); 1847a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen return; 1857a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } 1867a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen 18754cb8ab64f5cbd33257a926a6a2b588b3106b115Ray Chen Uri uri = updateDatabase(bitmap); 1887a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen if (uri != null) { 1897a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen OutputStream thumbOut = mCr.openOutputStream(uri); 1907a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen bitmap.compress(Bitmap.CompressFormat.JPEG, 85, thumbOut); 1917a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen thumbOut.close(); 192b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 193b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 194b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 1957a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen bitmap = ThumbnailUtils.extractThumbnail(bitmap, 1967a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL, 1977a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL, 1987a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen ThumbnailUtils.OPTIONS_RECYCLE_INPUT); 199b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 200b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen if (bitmap != null) { 2011373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream(); 2021373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen bitmap.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream); 2031373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen bitmap.recycle(); 2041373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen byte [] data = null; 2051373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen 2061373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen try { 2071373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen miniOutStream.close(); 2081373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen data = miniOutStream.toByteArray(); 2091373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } catch (java.io.IOException ex) { 2101373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen Log.e(TAG, "got exception ex " + ex); 2111373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } 212b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen 213b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // We may consider retire this proprietary format, after all it's size is only 214b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // 128 x 128 at most, which is still reasonable to be stored in database. 215b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // Gallery application can use the MINI_THUMB_MAGIC value to determine if it's 216b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen // time to query and fetch by using Cursor.getBlob 2171373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen if (data != null) { 2187a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen // make a new magic number since things are out of sync 2197a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen do { 220bf86108d222677067674c0947e8dc2b2bc9cadc2John Eckerdal magic = sRandom.nextLong(); 2217a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen } while (magic == 0); 2227a7691e1208a6d39d54de9b520a1bbf1c3c911f2Ray Chen 2231373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen miniThumbFile.saveMiniThumbToFile(data, mOrigId, magic); 2241373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen ContentValues values = new ContentValues(); 2251373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen // both video/images table use the same column name "mini_thumb_magic" 2261373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen values.put(ImageColumns.MINI_THUMB_MAGIC, magic); 2271373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen mCr.update(mUri, values, null, null); 2281373bc6df8faed91034ccbd785474cdc84bc1fd6Ray Chen } 229b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } else { 230b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen Log.w(TAG, "can't create bitmap for thumbnail."); 231b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 232b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen } 233b386112a8c5e5bd2d3d77e5398bea26b2172dffcRay Chen} 234