OSDN Git Service

am 695e1aa0: Force a layout pass if the display rotation changes
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / app / AbstractGalleryActivity.java
1 /*
2  * Copyright (C) 2010 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.gallery3d.app;
18
19 import android.annotation.TargetApi;
20 import android.app.AlertDialog;
21 import android.content.BroadcastReceiver;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.DialogInterface.OnCancelListener;
26 import android.content.DialogInterface.OnClickListener;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.ServiceConnection;
30 import android.content.res.Configuration;
31 import android.os.Bundle;
32 import android.os.IBinder;
33 import android.view.Window;
34 import android.view.WindowManager;
35
36 import com.actionbarsherlock.app.SherlockActivity;
37 import com.actionbarsherlock.view.Menu;
38 import com.actionbarsherlock.view.MenuItem;
39 import com.android.gallery3d.R;
40 import com.android.gallery3d.common.ApiHelper;
41 import com.android.gallery3d.data.BitmapPool;
42 import com.android.gallery3d.data.DataManager;
43 import com.android.gallery3d.data.MediaItem;
44 import com.android.gallery3d.ui.GLRoot;
45 import com.android.gallery3d.ui.GLRootView;
46 import com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper;
47 import com.android.gallery3d.util.ThreadPool;
48
49 public class AbstractGalleryActivity extends SherlockActivity implements GalleryContext {
50     @SuppressWarnings("unused")
51     private static final String TAG = "AbstractGalleryActivity";
52     private GLRootView mGLRootView;
53     private StateManager mStateManager;
54     private GalleryActionBar mActionBar;
55     private OrientationManager mOrientationManager;
56     private TransitionStore mTransitionStore = new TransitionStore();
57     private boolean mDisableToggleStatusBar;
58     private PanoramaViewHelper mPanoramaViewHelper;
59
60     private AlertDialog mAlertDialog = null;
61     private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
62         @Override
63         public void onReceive(Context context, Intent intent) {
64             if (getExternalCacheDir() != null) onStorageReady();
65         }
66     };
67     private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
68
69     @Override
70     protected void onCreate(Bundle savedInstanceState) {
71         super.onCreate(savedInstanceState);
72         mOrientationManager = new OrientationManager(this);
73         toggleStatusBarByOrientation();
74         getWindow().setBackgroundDrawable(null);
75         mPanoramaViewHelper = new PanoramaViewHelper(this);
76         mPanoramaViewHelper.onCreate();
77         doBindBatchService();
78     }
79
80     @Override
81     protected void onSaveInstanceState(Bundle outState) {
82         mGLRootView.lockRenderThread();
83         try {
84             super.onSaveInstanceState(outState);
85             getStateManager().saveState(outState);
86         } finally {
87             mGLRootView.unlockRenderThread();
88         }
89     }
90
91     @Override
92     public void onConfigurationChanged(Configuration config) {
93         super.onConfigurationChanged(config);
94         mStateManager.onConfigurationChange(config);
95         getGalleryActionBar().onConfigurationChanged();
96         invalidateOptionsMenu();
97         toggleStatusBarByOrientation();
98     }
99
100     @Override
101     public boolean onCreateOptionsMenu(Menu menu) {
102         super.onCreateOptionsMenu(menu);
103         return getStateManager().createOptionsMenu(menu);
104     }
105
106     @Override
107     public Context getAndroidContext() {
108         return this;
109     }
110
111     @Override
112     public DataManager getDataManager() {
113         return ((GalleryApp) getApplication()).getDataManager();
114     }
115
116     @Override
117     public ThreadPool getThreadPool() {
118         return ((GalleryApp) getApplication()).getThreadPool();
119     }
120
121     public synchronized StateManager getStateManager() {
122         if (mStateManager == null) {
123             mStateManager = new StateManager(this);
124         }
125         return mStateManager;
126     }
127
128     public GLRoot getGLRoot() {
129         return mGLRootView;
130     }
131
132     public OrientationManager getOrientationManager() {
133         return mOrientationManager;
134     }
135
136     @Override
137     public void setContentView(int resId) {
138         super.setContentView(resId);
139         mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
140     }
141
142     protected void onStorageReady() {
143         if (mAlertDialog != null) {
144             mAlertDialog.dismiss();
145             mAlertDialog = null;
146             unregisterReceiver(mMountReceiver);
147         }
148     }
149
150     @Override
151     protected void onStart() {
152         super.onStart();
153         if (getExternalCacheDir() == null) {
154             OnCancelListener onCancel = new OnCancelListener() {
155                 @Override
156                 public void onCancel(DialogInterface dialog) {
157                     finish();
158                 }
159             };
160             OnClickListener onClick = new OnClickListener() {
161                 @Override
162                 public void onClick(DialogInterface dialog, int which) {
163                     dialog.cancel();
164                 }
165             };
166             AlertDialog.Builder builder = new AlertDialog.Builder(this)
167                     .setTitle(R.string.no_external_storage_title)
168                     .setMessage(R.string.no_external_storage)
169                     .setNegativeButton(android.R.string.cancel, onClick)
170                     .setOnCancelListener(onCancel);
171             if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
172                 setAlertDialogIconAttribute(builder);
173             } else {
174                 builder.setIcon(android.R.drawable.ic_dialog_alert);
175             }
176             mAlertDialog = builder.show();
177             registerReceiver(mMountReceiver, mMountFilter);
178         }
179         mPanoramaViewHelper.onStart();
180     }
181
182     @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
183     private static void setAlertDialogIconAttribute(
184             AlertDialog.Builder builder) {
185         builder.setIconAttribute(android.R.attr.alertDialogIcon);
186     }
187
188     @Override
189     protected void onStop() {
190         super.onStop();
191         if (mAlertDialog != null) {
192             unregisterReceiver(mMountReceiver);
193             mAlertDialog.dismiss();
194             mAlertDialog = null;
195         }
196         mPanoramaViewHelper.onStop();
197     }
198
199     @Override
200     protected void onResume() {
201         super.onResume();
202         mGLRootView.lockRenderThread();
203         try {
204             getStateManager().resume();
205             getDataManager().resume();
206         } finally {
207             mGLRootView.unlockRenderThread();
208         }
209         mGLRootView.onResume();
210         mOrientationManager.resume();
211     }
212
213     @Override
214     protected void onPause() {
215         super.onPause();
216         mOrientationManager.pause();
217         mGLRootView.onPause();
218         mGLRootView.lockRenderThread();
219         try {
220             getStateManager().pause();
221             getDataManager().pause();
222         } finally {
223             mGLRootView.unlockRenderThread();
224         }
225         clearBitmapPool(MediaItem.getMicroThumbPool());
226         clearBitmapPool(MediaItem.getThumbPool());
227
228         MediaItem.getBytesBufferPool().clear();
229     }
230
231     private static void clearBitmapPool(BitmapPool pool) {
232         if (pool != null) pool.clear();
233     }
234
235     @Override
236     protected void onDestroy() {
237         super.onDestroy();
238         mGLRootView.lockRenderThread();
239         try {
240             getStateManager().destroy();
241         } finally {
242             mGLRootView.unlockRenderThread();
243         }
244         doUnbindBatchService();
245     }
246
247     @Override
248     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
249         mGLRootView.lockRenderThread();
250         try {
251             getStateManager().notifyActivityResult(
252                     requestCode, resultCode, data);
253         } finally {
254             mGLRootView.unlockRenderThread();
255         }
256     }
257
258     @Override
259     public void onBackPressed() {
260         // send the back event to the top sub-state
261         GLRoot root = getGLRoot();
262         root.lockRenderThread();
263         try {
264             getStateManager().onBackPressed();
265         } finally {
266             root.unlockRenderThread();
267         }
268     }
269
270     public GalleryActionBar getGalleryActionBar() {
271         if (mActionBar == null) {
272             mActionBar = new GalleryActionBar(this);
273         }
274         return mActionBar;
275     }
276
277     @Override
278     public boolean onOptionsItemSelected(MenuItem item) {
279         GLRoot root = getGLRoot();
280         root.lockRenderThread();
281         try {
282             return getStateManager().itemSelected(item);
283         } finally {
284             root.unlockRenderThread();
285         }
286     }
287
288     protected void disableToggleStatusBar() {
289         mDisableToggleStatusBar = true;
290     }
291
292     // Shows status bar in portrait view, hide in landscape view
293     private void toggleStatusBarByOrientation() {
294         if (mDisableToggleStatusBar) return;
295
296         Window win = getWindow();
297         if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
298             win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
299         } else {
300             win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
301         }
302     }
303
304     public TransitionStore getTransitionStore() {
305         return mTransitionStore;
306     }
307
308     public PanoramaViewHelper getPanoramaViewHelper() {
309         return mPanoramaViewHelper;
310     }
311
312     protected boolean isFullscreen() {
313         return (getWindow().getAttributes().flags
314                 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
315     }
316
317     private BatchService mBatchService;
318     private boolean mBatchServiceIsBound = false;
319     private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
320         public void onServiceConnected(ComponentName className, IBinder service) {
321             mBatchService = ((BatchService.LocalBinder)service).getService();
322         }
323
324         public void onServiceDisconnected(ComponentName className) {
325             mBatchService = null;
326         }
327     };
328
329     private void doBindBatchService() {
330         bindService(new Intent(this, BatchService.class), mBatchServiceConnection, Context.BIND_AUTO_CREATE);
331         mBatchServiceIsBound = true;
332     }
333
334     private void doUnbindBatchService() {
335         if (mBatchServiceIsBound) {
336             // Detach our existing connection.
337             unbindService(mBatchServiceConnection);
338             mBatchServiceIsBound = false;
339         }
340     }
341
342     public ThreadPool getBatchServiceThreadPoolIfAvailable() {
343         if (mBatchServiceIsBound && mBatchService != null) {
344             return mBatchService.getThreadPool();
345         } else {
346             // Fall back on the old behavior if for some reason the
347             // service is not available.
348             return getThreadPool();
349         }
350     }
351 }