OSDN Git Service

361d16bffaee166356896e504c78e8cdf17b3a8d
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / media / Gallery.java
1 package com.cooliris.media;
2
3 import java.io.IOException;
4 import java.net.URISyntaxException;
5 import java.util.HashMap;
6 import java.util.TimeZone;
7
8 import android.app.Activity;
9 import android.app.ProgressDialog;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.res.Configuration;
13 import android.graphics.Bitmap;
14 import android.net.Uri;
15 import android.os.Bundle;
16 import android.os.Handler;
17 import android.os.PowerManager;
18 import android.os.PowerManager.WakeLock;
19 import android.provider.MediaStore.Images;
20 import android.util.DisplayMetrics;
21 import android.util.Log;
22 import android.view.KeyEvent;
23 import android.widget.Toast;
24 import android.media.MediaScannerConnection;
25
26 import com.cooliris.cache.CacheService;
27 import com.cooliris.wallpaper.RandomDataSource;
28 import com.cooliris.wallpaper.Slideshow;
29
30 public final class Gallery extends Activity {
31     public static final TimeZone CURRENT_TIME_ZONE = TimeZone.getDefault();
32     public static float PIXEL_DENSITY = 0.0f;
33     public static final int CROP_MSG_INTERNAL = 100;
34
35     private static final String TAG = "Gallery";
36     private static final int CROP_MSG = 10;
37     private RenderView mRenderView = null;
38     private GridLayer mGridLayer;
39     private final Handler mHandler = new Handler();
40     private ReverseGeocoder mReverseGeocoder;
41     private boolean mPause;
42     private MediaScannerConnection mConnection;
43     private WakeLock mWakeLock;
44     private HashMap<String, Boolean> mAccountsEnabled = new HashMap<String, Boolean>();
45
46     @Override
47     public void onCreate(Bundle savedInstanceState) {
48         super.onCreate(savedInstanceState);
49         final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
50         if (isViewIntent() && getIntent().getData().equals(Images.Media.EXTERNAL_CONTENT_URI)
51                 && getIntent().getExtras().getBoolean("slideshow", false)) {
52             if (!imageManagerHasStorage) {
53                 Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
54                 finish();
55             } else {
56                 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
57                 mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow.All");
58                 mWakeLock.acquire();
59                 Slideshow slideshow = new Slideshow(this);
60                 slideshow.setDataSource(new RandomDataSource());
61                 setContentView(slideshow);
62             }
63             return;
64         }
65         CacheService.computeDirtySets(this);
66         final boolean isCacheReady = CacheService.isCacheReady(false);
67         if (PIXEL_DENSITY == 0.0f) {
68             DisplayMetrics metrics = new DisplayMetrics();
69             getWindowManager().getDefaultDisplay().getMetrics(metrics);
70             PIXEL_DENSITY = metrics.density;
71         }
72         mReverseGeocoder = new ReverseGeocoder(this);
73         mRenderView = new RenderView(this);
74         mGridLayer = new GridLayer(this, (int) (96.0f * PIXEL_DENSITY), (int) (72.0f * PIXEL_DENSITY), new GridLayoutInterface(4),
75                 mRenderView);
76         mRenderView.setRootLayer(mGridLayer);
77         setContentView(mRenderView);
78
79         // Creating the DataSource objects.
80         final PicasaDataSource picasaDataSource = new PicasaDataSource(this);
81         final LocalDataSource localDataSource = new LocalDataSource(this);
82         final ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
83
84         // Depending upon the intent, we assign the right dataSource.
85         if (!isPickIntent() && !isViewIntent()) {
86             if (imageManagerHasStorage) {
87                 mGridLayer.setDataSource(combinedDataSource);
88             } else {
89                 mGridLayer.setDataSource(picasaDataSource);
90             }
91             if (!imageManagerHasStorage) {
92                 Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
93             } else if (!isCacheReady) {
94                 Toast.makeText(this, getResources().getString(R.string.loading_new), Toast.LENGTH_LONG).show();
95             }
96         } else if (!isViewIntent()) {
97             final Intent intent = getIntent();
98             if (intent != null) {
99                 final String type = intent.resolveType(this);
100                 boolean includeImages = isImageType(type);
101                 boolean includeVideos = isVideoType(type);
102                 ((LocalDataSource) localDataSource).setMimeFilter(!includeImages, !includeVideos);
103                 if (includeImages) {
104                     if (imageManagerHasStorage) {
105                         mGridLayer.setDataSource(combinedDataSource);
106                     } else {
107                         mGridLayer.setDataSource(picasaDataSource);
108                     }
109                 } else {
110                     mGridLayer.setDataSource(localDataSource);
111                 }
112                 mGridLayer.setPickIntent(true);
113                 if (!imageManagerHasStorage) {
114                     Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
115                 } else {
116                     Toast.makeText(this, getResources().getString(R.string.pick_prompt), Toast.LENGTH_LONG).show();
117                 }
118             }
119         } else {
120             // View intent for images.
121             Uri uri = getIntent().getData();
122             boolean slideshow = getIntent().getBooleanExtra("slideshow", false);
123             final SingleDataSource singleDataSource = new SingleDataSource(this, uri.toString(), slideshow);
124             final ConcatenatedDataSource singleCombinedDataSource = new ConcatenatedDataSource(singleDataSource, picasaDataSource);
125             mGridLayer.setDataSource(singleCombinedDataSource);
126             mGridLayer.setViewIntent(true, Utils.getBucketNameFromUri(uri));
127             if (singleDataSource.isSingleImage()) {
128                 mGridLayer.setSingleImage(false);
129             } else if (slideshow) {
130                 mGridLayer.setSingleImage(true);
131                 mGridLayer.startSlideshow();
132             }
133         }
134         // We record the set of enabled accounts for picasa.
135         mAccountsEnabled = PicasaDataSource.getAccountStatus(this);
136         Log.i(TAG, "onCreate");
137     }
138
139     public ReverseGeocoder getReverseGeocoder() {
140         return mReverseGeocoder;
141     }
142
143     public Handler getHandler() {
144         return mHandler;
145     }
146
147     @Override
148     public void onRestart() {
149         super.onRestart();
150     }
151
152     @Override
153     public void onStart() {
154         super.onStart();
155     }
156
157     @Override
158     public void onResume() {
159         super.onResume();
160         CacheService.computeDirtySets(this);
161         CacheService.startCache(this, false);
162         if (mRenderView != null) {
163             mRenderView.onResume();
164         }
165         if (mPause) {
166             // We check to see if the authenticated accounts have changed, and
167             // if so, reload the datasource.
168             HashMap<String, Boolean> accountsEnabled = PicasaDataSource.getAccountStatus(this);
169             String[] keys = new String[accountsEnabled.size()];
170             keys = accountsEnabled.keySet().toArray(keys);
171             int numKeys = keys.length;
172             for (int i = 0; i < numKeys; ++i) {
173                 String key = keys[i];
174                 boolean newValue = accountsEnabled.get(key).booleanValue();
175                 boolean oldValue = false;
176                 Boolean oldValObj = mAccountsEnabled.get(key);
177                 if (oldValObj != null) {
178                     oldValue = oldValObj.booleanValue();
179                 }
180                 if (oldValue != newValue) {
181                     // Reload the datasource.
182                     if (mGridLayer != null)
183                         mGridLayer.setDataSource(mGridLayer.getDataSource());
184                     break;
185                 }
186             }
187             mAccountsEnabled = accountsEnabled;
188             mPause = false;
189         }
190     }
191
192     @Override
193     public void onPause() {
194         super.onPause();
195         if (mRenderView != null)
196             mRenderView.onPause();
197         mPause = true;
198     }
199
200     public boolean isPaused() {
201         return mPause;
202     }
203
204     @Override
205     public void onStop() {
206         super.onStop();
207         if (mGridLayer != null)
208             mGridLayer.stop();
209         if (mReverseGeocoder != null) {
210             mReverseGeocoder.flushCache();
211         }
212         LocalDataSource.sThumbnailCache.flush();
213         LocalDataSource.sThumbnailCacheVideo.flush();
214         PicasaDataSource.sThumbnailCache.flush();
215         CacheService.startCache(this, true);
216     }
217
218     @Override
219     public void onDestroy() {
220         // Force GLThread to exit.
221         setContentView(R.layout.main);
222         if (mGridLayer != null) {
223             DataSource dataSource = mGridLayer.getDataSource();
224             if (dataSource != null) {
225                 dataSource.shutdown();
226             }
227             mGridLayer.shutdown();
228         }
229         if (mWakeLock != null) {
230             if (mWakeLock.isHeld()) {
231                 mWakeLock.release();
232             }
233             mWakeLock = null;
234         }
235         if (mReverseGeocoder != null)
236             mReverseGeocoder.shutdown();
237         if (mRenderView != null) {
238             mRenderView.shutdown();
239             mRenderView = null;
240         }
241         mGridLayer = null;
242         super.onDestroy();
243         Log.i(TAG, "onDestroy");
244     }
245
246     @Override
247     public void onConfigurationChanged(Configuration newConfig) {
248         super.onConfigurationChanged(newConfig);
249         if (mGridLayer != null) {
250             mGridLayer.markDirty(30);
251         }
252         if (mRenderView != null)
253             mRenderView.requestRender();
254         Log.i(TAG, "onConfigurationChanged");
255     }
256
257     @Override
258     public boolean onKeyDown(int keyCode, KeyEvent event) {
259         if (mRenderView != null) {
260             return mRenderView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
261         } else {
262             return super.onKeyDown(keyCode, event);
263         }
264     }
265
266     private boolean isPickIntent() {
267         String action = getIntent().getAction();
268         return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
269     }
270
271     private boolean isViewIntent() {
272         String action = getIntent().getAction();
273         return Intent.ACTION_VIEW.equals(action);
274     }
275
276     private boolean isImageType(String type) {
277         return type.equals("vnd.android.cursor.dir/image") || type.equals("image/*");
278     }
279
280     private boolean isVideoType(String type) {
281         return type.equals("vnd.android.cursor.dir/video") || type.equals("video/*");
282     }
283
284     @Override
285     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
286         switch (requestCode) {
287         case CROP_MSG: {
288             if (resultCode == RESULT_OK) {
289                 setResult(resultCode, data);
290                 finish();
291             }
292             break;
293         }
294         case CROP_MSG_INTERNAL: {
295             // We cropped an image, we must try to set the focus of the camera
296             // to that image.
297             if (resultCode == RESULT_OK) {
298                 String contentUri = data.getAction();
299                 if (mGridLayer != null) {
300                     mGridLayer.focusItem(contentUri);
301                 }
302             }
303             break;
304         }
305         }
306     }
307
308     @Override
309     public void onLowMemory() {
310         if (mRenderView != null) {
311             mRenderView.handleLowMemory();
312         }
313     }
314
315     public void launchCropperOrFinish(final MediaItem item) {
316         final Bundle myExtras = getIntent().getExtras();
317         String cropValue = myExtras != null ? myExtras.getString("crop") : null;
318         final String contentUri = item.mContentUri;
319         if (cropValue != null) {
320             Bundle newExtras = new Bundle();
321             if (cropValue.equals("circle")) {
322                 newExtras.putString("circleCrop", "true");
323             }
324             Intent cropIntent = new Intent();
325             cropIntent.setData(Uri.parse(contentUri));
326             cropIntent.setClass(this, CropImage.class);
327             cropIntent.putExtras(newExtras);
328             // Pass through any extras that were passed in.
329             cropIntent.putExtras(myExtras);
330             startActivityForResult(cropIntent, CROP_MSG);
331         } else {
332             if (contentUri.startsWith("http://")) {
333                 // This is a http uri, we must save it locally first and
334                 // generate a content uri from it.
335                 final ProgressDialog dialog = ProgressDialog.show(this, this.getResources().getString(R.string.initializing),
336                         getResources().getString(R.string.running_face_detection), true, false);
337                 if (contentUri != null) {
338                     MediaScannerConnection.MediaScannerConnectionClient client = new MediaScannerConnection.MediaScannerConnectionClient() {
339                         public void onMediaScannerConnected() {
340                             if (mConnection != null) {
341                                 try {
342                                     final String path = UriTexture.writeHttpDataInDirectory(Gallery.this, contentUri,
343                                             LocalDataSource.DOWNLOAD_BUCKET_NAME);
344                                     if (path != null) {
345                                         mConnection.scanFile(path, item.mMimeType);
346                                     } else {
347                                         shutdown("");
348                                     }
349                                 } catch (Exception e) {
350                                     shutdown("");
351                                 }
352                             }
353                         }
354
355                         public void onScanCompleted(String path, Uri uri) {
356                             shutdown(uri.toString());
357                         }
358
359                         public void shutdown(String uri) {
360                             dialog.dismiss();
361                             performReturn(myExtras, uri.toString());
362                             if (mConnection != null) {
363                                 mConnection.disconnect();
364                             }
365                         }
366                     };
367                     MediaScannerConnection connection = new MediaScannerConnection(Gallery.this, client);
368                     connection.connect();
369                     mConnection = connection;
370                 }
371             } else {
372                 performReturn(myExtras, contentUri);
373             }
374         }
375     }
376
377     private void performReturn(Bundle myExtras, String contentUri) {
378         Intent result = new Intent(null, Uri.parse(contentUri));
379         if (myExtras != null && myExtras.getBoolean("return-data")) {
380             // The size of a transaction should be below 100K.
381             Bitmap bitmap = null;
382             try {
383                 bitmap = UriTexture.createFromUri(this, contentUri, 1024, 1024, 0, null);
384             } catch (IOException e) {
385                 ;
386             } catch (URISyntaxException e) {
387                 ;
388             }
389             if (bitmap != null) {
390                 result.putExtra("data", bitmap);
391             }
392         }
393         setResult(RESULT_OK, result);
394         finish();
395     }
396 }