OSDN Git Service

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