• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.camera;
18 
19 
20 import android.content.ContentResolver;
21 import android.content.res.Resources;
22 import android.graphics.Bitmap;
23 import android.graphics.BitmapFactory;
24 import android.graphics.drawable.BitmapDrawable;
25 import android.graphics.drawable.Drawable;
26 import android.graphics.drawable.TransitionDrawable;
27 import android.media.ThumbnailUtils;
28 import android.net.Uri;
29 import android.os.ParcelFileDescriptor;
30 import android.util.Log;
31 import android.view.ViewGroup.LayoutParams;
32 import android.widget.ImageView;
33 
34 import java.io.BufferedInputStream;
35 import java.io.BufferedOutputStream;
36 import java.io.DataInputStream;
37 import java.io.DataOutputStream;
38 import java.io.FileInputStream;
39 import java.io.FileOutputStream;
40 import java.io.IOException;
41 
42 /**
43  * A controller shows thumbnail picture on a button. The thumbnail picture
44  * corresponds to a URI of the original picture/video. The thumbnail bitmap
45  * and the URI can be saved to a file (and later loaded from it).
46  */
47 public class ThumbnailController {
48 
49     @SuppressWarnings("unused")
50     private static final String TAG = "ThumbnailController";
51     private final ContentResolver mContentResolver;
52     private Uri mUri;
53     private Bitmap mThumb;
54     private final ImageView mButton;
55     private Drawable[] mThumbs;
56     private TransitionDrawable mThumbTransition;
57     private boolean mShouldAnimateThumb;
58     private final Resources mResources;
59 
60     // The "frame" is a drawable we want to put on top of the thumbnail.
ThumbnailController(Resources resources, ImageView button, ContentResolver contentResolver)61     public ThumbnailController(Resources resources,
62             ImageView button, ContentResolver contentResolver) {
63         mResources = resources;
64         mButton = button;
65         mContentResolver = contentResolver;
66     }
67 
setData(Uri uri, Bitmap original)68     public void setData(Uri uri, Bitmap original) {
69         // Make sure uri and original are consistently both null or both
70         // non-null.
71         if (uri == null || original == null) {
72             uri = null;
73             original = null;
74         }
75         mUri = uri;
76         updateThumb(original);
77     }
78 
getUri()79     public Uri getUri() {
80         return mUri;
81     }
82 
83     private static final int BUFSIZE = 4096;
84 
85     // Stores the data from the specified file.
86     // Returns true for success.
storeData(String filePath)87     public boolean storeData(String filePath) {
88         if (mUri == null) {
89             return false;
90         }
91 
92         FileOutputStream f = null;
93         BufferedOutputStream b = null;
94         DataOutputStream d = null;
95         try {
96             f = new FileOutputStream(filePath);
97             b = new BufferedOutputStream(f, BUFSIZE);
98             d = new DataOutputStream(b);
99             d.writeUTF(mUri.toString());
100             mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
101             d.close();
102         } catch (IOException e) {
103             return false;
104         } finally {
105             MenuHelper.closeSilently(f);
106             MenuHelper.closeSilently(b);
107             MenuHelper.closeSilently(d);
108         }
109         return true;
110     }
111 
112     // Loads the data from the specified file.
113     // Returns true for success.
loadData(String filePath)114     public boolean loadData(String filePath) {
115         FileInputStream f = null;
116         BufferedInputStream b = null;
117         DataInputStream d = null;
118         try {
119             f = new FileInputStream(filePath);
120             b = new BufferedInputStream(f, BUFSIZE);
121             d = new DataInputStream(b);
122             Uri uri = Uri.parse(d.readUTF());
123             Bitmap thumb = BitmapFactory.decodeStream(d);
124             setData(uri, thumb);
125             d.close();
126         } catch (IOException e) {
127             return false;
128         } finally {
129             MenuHelper.closeSilently(f);
130             MenuHelper.closeSilently(b);
131             MenuHelper.closeSilently(d);
132         }
133         return true;
134     }
135 
updateDisplayIfNeeded()136     public void updateDisplayIfNeeded() {
137         if (mUri == null) {
138             mButton.setImageDrawable(null);
139             return;
140         }
141 
142         if (mShouldAnimateThumb) {
143             mThumbTransition.startTransition(500);
144             mShouldAnimateThumb = false;
145         }
146     }
147 
updateThumb(Bitmap original)148     private void updateThumb(Bitmap original) {
149         if (original == null) {
150             mThumb = null;
151             mThumbs = null;
152             return;
153         }
154 
155         LayoutParams param = mButton.getLayoutParams();
156         final int miniThumbWidth = param.width
157                 - mButton.getPaddingLeft() - mButton.getPaddingRight();
158         final int miniThumbHeight = param.height
159                 - mButton.getPaddingTop() - mButton.getPaddingBottom();
160         mThumb = ThumbnailUtils.extractThumbnail(
161                 original, miniThumbWidth, miniThumbHeight);
162         Drawable drawable;
163         if (mThumbs == null) {
164             mThumbs = new Drawable[2];
165             mThumbs[1] = new BitmapDrawable(mResources, mThumb);
166             drawable = mThumbs[1];
167             mShouldAnimateThumb = false;
168         } else {
169             mThumbs[0] = mThumbs[1];
170             mThumbs[1] = new BitmapDrawable(mResources, mThumb);
171             mThumbTransition = new TransitionDrawable(mThumbs);
172             drawable = mThumbTransition;
173             mShouldAnimateThumb = true;
174         }
175         mButton.setImageDrawable(drawable);
176     }
177 
isUriValid()178     public boolean isUriValid() {
179         if (mUri == null) {
180             return false;
181         }
182         try {
183             ParcelFileDescriptor pfd =
184                     mContentResolver.openFileDescriptor(mUri, "r");
185             if (pfd == null) {
186                 Log.e(TAG, "Fail to open URI.");
187                 return false;
188             }
189             pfd.close();
190         } catch (IOException ex) {
191             return false;
192         }
193         return true;
194     }
195 }
196