2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gallery3d.app;
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.net.Uri;
33 import android.os.Bundle;
34 import android.os.IBinder;
35 import android.view.Menu;
36 import android.view.MenuItem;
37 import android.view.Window;
38 import android.view.WindowManager;
40 import com.android.gallery3d.R;
41 import com.android.gallery3d.common.ApiHelper;
42 import com.android.gallery3d.data.DataManager;
43 import com.android.gallery3d.data.MediaItem;
44 import com.android.gallery3d.filtershow.cache.ImageLoader;
45 import com.android.gallery3d.ui.GLRoot;
46 import com.android.gallery3d.ui.GLRootView;
47 import com.android.gallery3d.util.PanoramaViewHelper;
48 import com.android.gallery3d.util.PrintJob;
49 import com.android.gallery3d.util.ThreadPool;
50 import com.android.photos.data.GalleryBitmapPool;
52 public class AbstractGalleryActivity extends Activity implements GalleryContext {
53 @SuppressWarnings("unused")
54 private static final String TAG = "AbstractGalleryActivity";
55 private GLRootView mGLRootView;
56 private StateManager mStateManager;
57 private GalleryActionBar mActionBar;
58 private OrientationManager mOrientationManager;
59 private TransitionStore mTransitionStore = new TransitionStore();
60 private boolean mDisableToggleStatusBar;
61 private PanoramaViewHelper mPanoramaViewHelper;
63 private AlertDialog mAlertDialog = null;
64 private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
66 public void onReceive(Context context, Intent intent) {
67 if (getExternalCacheDir() != null) onStorageReady();
70 private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
73 protected void onCreate(Bundle savedInstanceState) {
74 super.onCreate(savedInstanceState);
75 mOrientationManager = new OrientationManager(this);
76 toggleStatusBarByOrientation();
77 getWindow().setBackgroundDrawable(null);
78 mPanoramaViewHelper = new PanoramaViewHelper(this);
79 mPanoramaViewHelper.onCreate();
84 protected void onSaveInstanceState(Bundle outState) {
85 mGLRootView.lockRenderThread();
87 super.onSaveInstanceState(outState);
88 getStateManager().saveState(outState);
90 mGLRootView.unlockRenderThread();
95 public void onConfigurationChanged(Configuration config) {
96 super.onConfigurationChanged(config);
97 mStateManager.onConfigurationChange(config);
98 getGalleryActionBar().onConfigurationChanged();
99 invalidateOptionsMenu();
100 toggleStatusBarByOrientation();
104 public boolean onCreateOptionsMenu(Menu menu) {
105 super.onCreateOptionsMenu(menu);
106 return getStateManager().createOptionsMenu(menu);
110 public Context getAndroidContext() {
115 public DataManager getDataManager() {
116 return ((GalleryApp) getApplication()).getDataManager();
120 public ThreadPool getThreadPool() {
121 return ((GalleryApp) getApplication()).getThreadPool();
124 public synchronized StateManager getStateManager() {
125 if (mStateManager == null) {
126 mStateManager = new StateManager(this);
128 return mStateManager;
131 public GLRoot getGLRoot() {
135 public OrientationManager getOrientationManager() {
136 return mOrientationManager;
140 public void setContentView(int resId) {
141 super.setContentView(resId);
142 mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
145 protected void onStorageReady() {
146 if (mAlertDialog != null) {
147 mAlertDialog.dismiss();
149 unregisterReceiver(mMountReceiver);
154 protected void onStart() {
156 if (getExternalCacheDir() == null) {
157 OnCancelListener onCancel = new OnCancelListener() {
159 public void onCancel(DialogInterface dialog) {
163 OnClickListener onClick = new OnClickListener() {
165 public void onClick(DialogInterface dialog, int which) {
169 AlertDialog.Builder builder = new AlertDialog.Builder(this)
170 .setTitle(R.string.no_external_storage_title)
171 .setMessage(R.string.no_external_storage)
172 .setNegativeButton(android.R.string.cancel, onClick)
173 .setOnCancelListener(onCancel);
174 if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
175 setAlertDialogIconAttribute(builder);
177 builder.setIcon(android.R.drawable.ic_dialog_alert);
179 mAlertDialog = builder.show();
180 registerReceiver(mMountReceiver, mMountFilter);
182 mPanoramaViewHelper.onStart();
185 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
186 private static void setAlertDialogIconAttribute(
187 AlertDialog.Builder builder) {
188 builder.setIconAttribute(android.R.attr.alertDialogIcon);
192 protected void onStop() {
194 if (mAlertDialog != null) {
195 unregisterReceiver(mMountReceiver);
196 mAlertDialog.dismiss();
199 mPanoramaViewHelper.onStop();
203 protected void onResume() {
205 mGLRootView.lockRenderThread();
207 getStateManager().resume();
208 getDataManager().resume();
210 mGLRootView.unlockRenderThread();
212 mGLRootView.onResume();
213 mOrientationManager.resume();
217 protected void onPause() {
219 mOrientationManager.pause();
220 mGLRootView.onPause();
221 mGLRootView.lockRenderThread();
223 getStateManager().pause();
224 getDataManager().pause();
226 mGLRootView.unlockRenderThread();
228 GalleryBitmapPool.getInstance().clear();
229 MediaItem.getBytesBufferPool().clear();
233 protected void onDestroy() {
235 mGLRootView.lockRenderThread();
237 getStateManager().destroy();
239 mGLRootView.unlockRenderThread();
241 doUnbindBatchService();
245 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
246 mGLRootView.lockRenderThread();
248 getStateManager().notifyActivityResult(
249 requestCode, resultCode, data);
251 mGLRootView.unlockRenderThread();
256 public void onBackPressed() {
257 // send the back event to the top sub-state
258 GLRoot root = getGLRoot();
259 root.lockRenderThread();
261 getStateManager().onBackPressed();
263 root.unlockRenderThread();
267 public GalleryActionBar getGalleryActionBar() {
268 if (mActionBar == null) {
269 mActionBar = new GalleryActionBar(this);
275 public boolean onOptionsItemSelected(MenuItem item) {
276 GLRoot root = getGLRoot();
277 root.lockRenderThread();
279 return getStateManager().itemSelected(item);
281 root.unlockRenderThread();
285 protected void disableToggleStatusBar() {
286 mDisableToggleStatusBar = true;
289 // Shows status bar in portrait view, hide in landscape view
290 private void toggleStatusBarByOrientation() {
291 if (mDisableToggleStatusBar) return;
293 Window win = getWindow();
294 if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
295 win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
297 win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
301 public TransitionStore getTransitionStore() {
302 return mTransitionStore;
305 public PanoramaViewHelper getPanoramaViewHelper() {
306 return mPanoramaViewHelper;
309 protected boolean isFullscreen() {
310 return (getWindow().getAttributes().flags
311 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
314 private BatchService mBatchService;
315 private boolean mBatchServiceIsBound = false;
316 private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
318 public void onServiceConnected(ComponentName className, IBinder service) {
319 mBatchService = ((BatchService.LocalBinder)service).getService();
323 public void onServiceDisconnected(ComponentName className) {
324 mBatchService = null;
328 private void doBindBatchService() {
329 bindService(new Intent(this, BatchService.class), mBatchServiceConnection, Context.BIND_AUTO_CREATE);
330 mBatchServiceIsBound = true;
333 private void doUnbindBatchService() {
334 if (mBatchServiceIsBound) {
335 // Detach our existing connection.
336 unbindService(mBatchServiceConnection);
337 mBatchServiceIsBound = false;
341 public ThreadPool getBatchServiceThreadPoolIfAvailable() {
342 if (mBatchServiceIsBound && mBatchService != null) {
343 return mBatchService.getThreadPool();
345 throw new RuntimeException("Batch service unavailable");
349 public void printSelectedImage(Uri uri) {
353 String path = ImageLoader.getLocalPathFromUri(this, uri);
355 Uri localUri = Uri.parse(path);
356 path = localUri.getLastPathSegment();
358 path = uri.getLastPathSegment();
360 PrintJob.printBitmapAtUri(this, path, uri);