UriImage.java revision 4bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740
1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentResolver; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap.Config; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.BitmapFactory.Options; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.BitmapRegionDecoder; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.ParcelFileDescriptor; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.webkit.MimeTypeMap; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 284bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.app.GalleryApp; 294bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.common.BitmapUtils; 304bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.common.Utils; 314bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.util.ThreadPool.CancelListener; 324bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.util.ThreadPool.Job; 334bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.util.ThreadPool.JobContext; 344bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin 35d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Changimport java.io.FileInputStream; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.io.FileNotFoundException; 37d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Changimport java.io.InputStream; 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.net.URI; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.net.URL; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class UriImage extends MediaItem { 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "UriImage"; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int STATE_INIT = 0; 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int STATE_DOWNLOADING = 1; 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int STATE_DOWNLOADED = 2; 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int STATE_ERROR = -1; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final Uri mUri; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final String mContentType; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private DownloadCache.Entry mCacheEntry; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private ParcelFileDescriptor mFileDescriptor; 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mState = STATE_INIT; 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mWidth; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mHeight; 57d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang private int mRotation; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private GalleryApp mApplication; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public UriImage(GalleryApp application, Path path, Uri uri) { 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(path, nextVersionNumber()); 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mUri = uri; 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mApplication = Utils.checkNotNull(application); 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentType = getMimeType(uri); 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private String getMimeType(Uri uri) { 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String extension = 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MimeTypeMap.getFileExtensionFromUrl(uri.toString()); 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String type = MimeTypeMap.getSingleton() 73d74016524fa899747411240daa453e5ca9cac219Ray Chen .getMimeTypeFromExtension(extension.toLowerCase()); 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (type != null) return type; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mApplication.getContentResolver().getType(uri); 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Job<Bitmap> requestImage(int type) { 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new BitmapJob(type); 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Job<BitmapRegionDecoder> requestLargeImage() { 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new RegionDecoderJob(); 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void openFileOrDownloadTempFile(JobContext jc) { 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int state = openOrDownloadInner(jc); 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (this) { 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mState = state; 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mState != STATE_DOWNLOADED) { 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mFileDescriptor != null) { 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.closeSilently(mFileDescriptor); 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFileDescriptor = null; 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin notifyAll(); 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int openOrDownloadInner(JobContext jc) { 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String scheme = mUri.getScheme(); 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ContentResolver.SCHEME_CONTENT.equals(scheme) 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || ContentResolver.SCHEME_FILE.equals(scheme)) { 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 109d74016524fa899747411240daa453e5ca9cac219Ray Chen if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) { 110d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang InputStream is = mApplication.getContentResolver() 111d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang .openInputStream(mUri); 112d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang mRotation = Exif.getOrientation(is); 113d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang Utils.closeSilently(is); 114d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang } 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFileDescriptor = mApplication.getContentResolver() 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .openFileDescriptor(mUri, "r"); 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (jc.isCancelled()) return STATE_INIT; 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return STATE_DOWNLOADED; 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (FileNotFoundException e) { 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "fail to open: " + mUri, e); 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return STATE_ERROR; 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin URL url = new URI(mUri.toString()).toURL(); 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCacheEntry = mApplication.getDownloadCache().download(jc, url); 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (jc.isCancelled()) return STATE_INIT; 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mCacheEntry == null) { 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "download failed " + url); 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return STATE_ERROR; 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 132d74016524fa899747411240daa453e5ca9cac219Ray Chen if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) { 133d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang InputStream is = new FileInputStream(mCacheEntry.cacheFile); 134d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang mRotation = Exif.getOrientation(is); 135d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang Utils.closeSilently(is); 136d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang } 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFileDescriptor = ParcelFileDescriptor.open( 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCacheEntry.cacheFile, ParcelFileDescriptor.MODE_READ_ONLY); 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return STATE_DOWNLOADED; 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (Throwable t) { 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "download error", t); 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return STATE_ERROR; 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean prepareInputFile(JobContext jc) { 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin jc.setCancelListener(new CancelListener() { 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onCancel() { 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (this) { 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin notifyAll(); 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }); 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin while (true) { 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (this) { 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (jc.isCancelled()) return false; 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mState == STATE_INIT) { 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mState = STATE_DOWNLOADING; 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Then leave the synchronized block and continue. 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (mState == STATE_ERROR) { 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (mState == STATE_DOWNLOADED) { 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else /* if (mState == STATE_DOWNLOADING) */ { 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin wait(); 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (InterruptedException ex) { 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // ignored. 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin continue; 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This is only reached for STATE_INIT->STATE_DOWNLOADING 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin openFileOrDownloadTempFile(jc); 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class RegionDecoderJob implements Job<BitmapRegionDecoder> { 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public BitmapRegionDecoder run(JobContext jc) { 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!prepareInputFile(jc)) return null; 1834bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin BitmapRegionDecoder decoder = DecodeUtils.createBitmapRegionDecoder( 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin jc, mFileDescriptor.getFileDescriptor(), false); 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mWidth = decoder.getWidth(); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHeight = decoder.getHeight(); 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return decoder; 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class BitmapJob implements Job<Bitmap> { 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mType; 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected BitmapJob(int type) { 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mType = type; 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1984bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin @Override 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Bitmap run(JobContext jc) { 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!prepareInputFile(jc)) return null; 2014bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin int targetSize = MediaItem.getTargetSize(mType); 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Options options = new Options(); 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin options.inPreferredConfig = Config.ARGB_8888; 2044bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin Bitmap bitmap = DecodeUtils.decodeThumbnail(jc, 2054bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin mFileDescriptor.getFileDescriptor(), options, targetSize, mType); 2064bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (jc.isCancelled() || bitmap == null) { 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return null; 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mType == MediaItem.TYPE_MICROTHUMBNAIL) { 2124bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin bitmap = BitmapUtils.resizeAndCropCenter(bitmap, targetSize, true); 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 2144bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin bitmap = BitmapUtils.resizeDownBySideLength(bitmap, targetSize, true); 215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return bitmap; 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getSupportedOperations() { 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int supported = SUPPORT_EDIT | SUPPORT_SETAS; 223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isSharable()) supported |= SUPPORT_SHARE; 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (BitmapUtils.isSupportedByRegionDecoder(mContentType)) { 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin supported |= SUPPORT_FULL_IMAGE; 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return supported; 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean isSharable() { 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // We cannot grant read permission to the receiver since we put 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // the data URI in EXTRA_STREAM instead of the data part of an intent 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // And there are issues in MediaUploader and Bluetooth file sender to 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // share a general image data. So, we only share for local file. 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return ContentResolver.SCHEME_FILE.equals(mUri.getScheme()); 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getMediaType() { 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return MEDIA_TYPE_IMAGE; 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Uri getContentUri() { 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mUri; 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public MediaDetails getDetails() { 250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaDetails details = super.getDetails(); 251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mWidth != 0 && mHeight != 0) { 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_WIDTH, mWidth); 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_HEIGHT, mHeight); 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 255d74016524fa899747411240daa453e5ca9cac219Ray Chen if (mContentType != null) { 256d74016524fa899747411240daa453e5ca9cac219Ray Chen details.addDetail(MediaDetails.INDEX_MIMETYPE, mContentType); 257d74016524fa899747411240daa453e5ca9cac219Ray Chen } 258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ContentResolver.SCHEME_FILE.equals(mUri.getScheme())) { 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String filePath = mUri.getPath(); 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin details.addDetail(MediaDetails.INDEX_PATH, filePath); 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaDetails.extractExifInfo(details, filePath); 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return details; 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public String getMimeType() { 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mContentType; 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void finalize() throws Throwable { 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mFileDescriptor != null) { 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.closeSilently(mFileDescriptor); 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.finalize(); 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 281bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang 282bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang @Override 283bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang public int getWidth() { 284bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang return 0; 285bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang } 286bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang 287bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang @Override 288bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang public int getHeight() { 289bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang return 0; 290bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang } 291d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang 292d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang @Override 293d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang public int getRotation() { 294d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang return mRotation; 295d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang } 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 297