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 Lin
274bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.app.GalleryApp;
284b4dbd225685502f4249c2bf25bf74f7ce526645George Mountimport com.android.gallery3d.app.PanoramaMetadataSupport;
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;
584b4dbd225685502f4249c2bf25bf74f7ce526645George Mount    private PanoramaMetadataSupport mPanoramaMetadata = new PanoramaMetadataSupport(this);
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GalleryApp mApplication;
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
6221a412c93c9b0401b039f4eb86d4950752e5bb84Owen Lin    public UriImage(GalleryApp application, Path path, Uri uri, String contentType) {
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super(path, nextVersionNumber());
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mUri = uri;
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mApplication = Utils.checkNotNull(application);
6621a412c93c9b0401b039f4eb86d4950752e5bb84Owen Lin        mContentType = contentType;
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Job<Bitmap> requestImage(int type) {
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return new BitmapJob(type);
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Job<BitmapRegionDecoder> requestLargeImage() {
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return new RegionDecoderJob();
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void openFileOrDownloadTempFile(JobContext jc) {
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int state = openOrDownloadInner(jc);
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        synchronized (this) {
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mState = state;
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mState != STATE_DOWNLOADED) {
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mFileDescriptor != null) {
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    Utils.closeSilently(mFileDescriptor);
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mFileDescriptor = null;
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            notifyAll();
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private int openOrDownloadInner(JobContext jc) {
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String scheme = mUri.getScheme();
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (ContentResolver.SCHEME_CONTENT.equals(scheme)
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                || ContentResolver.SCHEME_FILE.equals(scheme)) {
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            try {
99d74016524fa899747411240daa453e5ca9cac219Ray Chen                if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
100d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    InputStream is = mApplication.getContentResolver()
101d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                            .openInputStream(mUri);
102d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    mRotation = Exif.getOrientation(is);
103d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    Utils.closeSilently(is);
104d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                }
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mFileDescriptor = mApplication.getContentResolver()
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        .openFileDescriptor(mUri, "r");
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (jc.isCancelled()) return STATE_INIT;
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return STATE_DOWNLOADED;
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } catch (FileNotFoundException e) {
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Log.w(TAG, "fail to open: " + mUri, e);
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return STATE_ERROR;
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            try {
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                URL url = new URI(mUri.toString()).toURL();
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mCacheEntry = mApplication.getDownloadCache().download(jc, url);
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (jc.isCancelled()) return STATE_INIT;
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mCacheEntry == null) {
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    Log.w(TAG, "download failed " + url);
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return STATE_ERROR;
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
122d74016524fa899747411240daa453e5ca9cac219Ray Chen                if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
123d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    InputStream is = new FileInputStream(mCacheEntry.cacheFile);
124d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    mRotation = Exif.getOrientation(is);
125d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                    Utils.closeSilently(is);
126d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang                }
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mFileDescriptor = ParcelFileDescriptor.open(
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        mCacheEntry.cacheFile, ParcelFileDescriptor.MODE_READ_ONLY);
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return STATE_DOWNLOADED;
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } catch (Throwable t) {
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Log.w(TAG, "download error", t);
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return STATE_ERROR;
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean prepareInputFile(JobContext jc) {
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        jc.setCancelListener(new CancelListener() {
1397817979db0c52ffeacb951625b1e821eba303285Ahbong Chang            @Override
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public void onCancel() {
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                synchronized (this) {
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    notifyAll();
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        while (true) {
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            synchronized (this) {
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (jc.isCancelled()) return false;
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mState == STATE_INIT) {
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mState = STATE_DOWNLOADING;
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    // Then leave the synchronized block and continue.
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else if (mState == STATE_ERROR) {
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return false;
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else if (mState == STATE_DOWNLOADED) {
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return true;
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else /* if (mState == STATE_DOWNLOADING) */ {
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    try {
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        wait();
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    } catch (InterruptedException ex) {
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        // ignored.
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    }
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    continue;
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // This is only reached for STATE_INIT->STATE_DOWNLOADING
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            openFileOrDownloadTempFile(jc);
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private class RegionDecoderJob implements Job<BitmapRegionDecoder> {
1727817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        @Override
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public BitmapRegionDecoder run(JobContext jc) {
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (!prepareInputFile(jc)) return null;
1754bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin            BitmapRegionDecoder decoder = DecodeUtils.createBitmapRegionDecoder(
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    jc, mFileDescriptor.getFileDescriptor(), false);
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mWidth = decoder.getWidth();
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mHeight = decoder.getHeight();
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return decoder;
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private class BitmapJob implements Job<Bitmap> {
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private int mType;
185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected BitmapJob(int type) {
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mType = type;
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
1904bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin        @Override
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public Bitmap run(JobContext jc) {
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (!prepareInputFile(jc)) return null;
1934bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin            int targetSize = MediaItem.getTargetSize(mType);
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Options options = new Options();
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            options.inPreferredConfig = Config.ARGB_8888;
1964bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin            Bitmap bitmap = DecodeUtils.decodeThumbnail(jc,
1974bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin                    mFileDescriptor.getFileDescriptor(), options, targetSize, mType);
1984bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (jc.isCancelled() || bitmap == null) {
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return null;
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
2044bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin                bitmap = BitmapUtils.resizeAndCropCenter(bitmap, targetSize, true);
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
2064bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin                bitmap = BitmapUtils.resizeDownBySideLength(bitmap, targetSize, true);
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return bitmap;
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int getSupportedOperations() {
214e56abc7049e35f705161086fe51d0ecdbf451b8bJohn Hoford        int supported = SUPPORT_PRINT | SUPPORT_SETAS;
215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (isSharable()) supported |= SUPPORT_SHARE;
216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (BitmapUtils.isSupportedByRegionDecoder(mContentType)) {
217e56abc7049e35f705161086fe51d0ecdbf451b8bJohn Hoford            supported |= SUPPORT_EDIT | SUPPORT_FULL_IMAGE;
218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return supported;
220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
222825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware    @Override
2234b4dbd225685502f4249c2bf25bf74f7ce526645George Mount    public void getPanoramaSupport(PanoramaSupportCallback callback) {
2244b4dbd225685502f4249c2bf25bf74f7ce526645George Mount        mPanoramaMetadata.getPanoramaSupport(mApplication, callback);
225825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware    }
226825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware
227825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware    @Override
2284b4dbd225685502f4249c2bf25bf74f7ce526645George Mount    public void clearCachedPanoramaSupport() {
2294b4dbd225685502f4249c2bf25bf74f7ce526645George Mount        mPanoramaMetadata.clearCachedValues();
230825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware    }
231825afb1b3e7d15b5c258d664ee008dc68da1c407Mangesh Ghiware
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean isSharable() {
233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // We cannot grant read permission to the receiver since we put
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // the data URI in EXTRA_STREAM instead of the data part of an intent
235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // And there are issues in MediaUploader and Bluetooth file sender to
236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // share a general image data. So, we only share for local file.
237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return ContentResolver.SCHEME_FILE.equals(mUri.getScheme());
238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int getMediaType() {
242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return MEDIA_TYPE_IMAGE;
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Uri getContentUri() {
247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mUri;
248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public MediaDetails getDetails() {
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaDetails details = super.getDetails();
253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mWidth != 0 && mHeight != 0) {
254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            details.addDetail(MediaDetails.INDEX_WIDTH, mWidth);
255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            details.addDetail(MediaDetails.INDEX_HEIGHT, mHeight);
256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
257d74016524fa899747411240daa453e5ca9cac219Ray Chen        if (mContentType != null) {
258d74016524fa899747411240daa453e5ca9cac219Ray Chen            details.addDetail(MediaDetails.INDEX_MIMETYPE, mContentType);
259d74016524fa899747411240daa453e5ca9cac219Ray Chen        }
260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (ContentResolver.SCHEME_FILE.equals(mUri.getScheme())) {
261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String filePath = mUri.getPath();
262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            details.addDetail(MediaDetails.INDEX_PATH, filePath);
263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaDetails.extractExifInfo(details, filePath);
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return details;
266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public String getMimeType() {
270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mContentType;
271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void finalize() throws Throwable {
275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mFileDescriptor != null) {
277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Utils.closeSilently(mFileDescriptor);
278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super.finalize();
281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
283bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
284bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    @Override
285bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    public int getWidth() {
286bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        return 0;
287bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
288bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
289bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    @Override
290bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    public int getHeight() {
291bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        return 0;
292bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
293d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang
294d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang    @Override
295d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang    public int getRotation() {
296d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang        return mRotation;
297d6985f9ba58c11c29760f28be07ebd229a9b7a39Chih-Chung Chang    }
298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
299