OSDN Git Service

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