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 androidx.print.PrintHelper;
36 import android.view.Menu;
37 import android.view.MenuItem;
38 import android.view.Window;
39 import android.view.WindowManager;
41 import com.android.gallery3d.R;
42 import com.android.gallery3d.common.ApiHelper;
43 import com.android.gallery3d.data.DataManager;
44 import com.android.gallery3d.data.MediaItem;
45 import com.android.gallery3d.filtershow.cache.ImageLoader;
46 import com.android.gallery3d.ui.GLRoot;
47 import com.android.gallery3d.ui.GLRootView;
48 import com.android.gallery3d.util.PanoramaViewHelper;
49 import com.android.gallery3d.util.ThreadPool;
50 import com.android.photos.data.GalleryBitmapPool;
52 import java.io.FileNotFoundException;
54 public class AbstractGalleryActivity extends Activity implements GalleryContext {
55 private static final String TAG = "AbstractGalleryActivity";
56 private GLRootView mGLRootView;
57 private StateManager mStateManager;
58 private GalleryActionBar mActionBar;
59 private OrientationManager mOrientationManager;
60 private TransitionStore mTransitionStore = new TransitionStore();
61 private boolean mDisableToggleStatusBar;
62 private PanoramaViewHelper mPanoramaViewHelper;
64 private AlertDialog mAlertDialog = null;
65 private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
67 public void onReceive(Context context, Intent intent) {
68 if (getExternalCacheDir() != null) onStorageReady();
71 private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
74 protected void onCreate(Bundle savedInstanceState) {
75 super.onCreate(savedInstanceState);
76 mOrientationManager = new OrientationManager(this);
77 toggleStatusBarByOrientation();
78 getWindow().setBackgroundDrawable(null);
79 mPanoramaViewHelper = new PanoramaViewHelper(this);
80 mPanoramaViewHelper.onCreate();
85 protected void onSaveInstanceState(Bundle outState) {
86 mGLRootView.lockRenderThread();
88 super.onSaveInstanceState(outState);
89 getStateManager().saveState(outState);
91 mGLRootView.unlockRenderThread();
96 public void onConfigurationChanged(Configuration config) {
97 super.onConfigurationChanged(config);
98 mStateManager.onConfigurationChange(config);
99 getGalleryActionBar().onConfigurationChanged();
100 invalidateOptionsMenu();
101 toggleStatusBarByOrientation();
105 public boolean onCreateOptionsMenu(Menu menu) {
106 super.onCreateOptionsMenu(menu);
107 return getStateManager().createOptionsMenu(menu);
111 public Context getAndroidContext() {
116 public DataManager getDataManager() {
117 return ((GalleryApp) getApplication()).getDataManager();
121 public ThreadPool getThreadPool() {
122 return ((GalleryApp) getApplication()).getThreadPool();
125 public synchronized StateManager getStateManager() {
126 if (mStateManager == null) {
127 mStateManager = new StateManager(this);
129 return mStateManager;
132 public GLRoot getGLRoot() {
136 public OrientationManager getOrientationManager() {
137 return mOrientationManager;
141 public void setContentView(int resId) {
142 super.setContentView(resId);
143 mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
146 protected void onStorageReady() {
147 if (mAlertDialog != null) {
148 mAlertDialog.dismiss();
150 unregisterReceiver(mMountReceiver);
155 protected void onStart() {
157 if (getExternalCacheDir() == null) {
158 OnCancelListener onCancel = new OnCancelListener() {
160 public void onCancel(DialogInterface dialog) {
164 OnClickListener onClick = new OnClickListener() {
166 public void onClick(DialogInterface dialog, int which) {
170 AlertDialog.Builder builder = new AlertDialog.Builder(this)
171 .setTitle(R.string.no_external_storage_title)
172 .setMessage(R.string.no_external_storage)
173 .setNegativeButton(android.R.string.cancel, onClick)
174 .setOnCancelListener(onCancel);
175 if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
176 setAlertDialogIconAttribute(builder);
178 builder.setIcon(android.R.drawable.ic_dialog_alert);
180 mAlertDialog = builder.show();
181 registerReceiver(mMountReceiver, mMountFilter);
183 mPanoramaViewHelper.onStart();
186 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
187 private static void setAlertDialogIconAttribute(
188 AlertDialog.Builder builder) {
189 builder.setIconAttribute(android.R.attr.alertDialogIcon);
193 protected void onStop() {
195 if (mAlertDialog != null) {
196 unregisterReceiver(mMountReceiver);
197 mAlertDialog.dismiss();
200 mPanoramaViewHelper.onStop();
204 protected void onResume() {
206 mGLRootView.lockRenderThread();
208 getStateManager().resume();
209 getDataManager().resume();
211 mGLRootView.unlockRenderThread();
213 mGLRootView.onResume();
214 mOrientationManager.resume();
218 protected void onPause() {
220 mOrientationManager.pause();
221 mGLRootView.onPause();
222 mGLRootView.lockRenderThread();
224 getStateManager().pause();
225 getDataManager().pause();
227 mGLRootView.unlockRenderThread();
229 GalleryBitmapPool.getInstance().clear();
230 MediaItem.getBytesBufferPool().clear();
234 protected void onDestroy() {
236 mGLRootView.lockRenderThread();
238 getStateManager().destroy();
240 mGLRootView.unlockRenderThread();
242 doUnbindBatchService();
246 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
247 mGLRootView.lockRenderThread();
249 getStateManager().notifyActivityResult(
250 requestCode, resultCode, data);
252 mGLRootView.unlockRenderThread();
257 public void onBackPressed() {
258 // send the back event to the top sub-state
259 GLRoot root = getGLRoot();
260 root.lockRenderThread();
262 getStateManager().onBackPressed();
264 root.unlockRenderThread();
268 public GalleryActionBar getGalleryActionBar() {
269 if (mActionBar == null) {
270 mActionBar = new GalleryActionBar(this);
276 public boolean onOptionsItemSelected(MenuItem item) {
277 GLRoot root = getGLRoot();
278 root.lockRenderThread();
280 return getStateManager().itemSelected(item);
282 root.unlockRenderThread();
286 protected void disableToggleStatusBar() {
287 mDisableToggleStatusBar = true;
290 // Shows status bar in portrait view, hide in landscape view
291 private void toggleStatusBarByOrientation() {
292 if (mDisableToggleStatusBar) return;
294 Window win = getWindow();
295 if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
296 win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
298 win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
302 public TransitionStore getTransitionStore() {
303 return mTransitionStore;
306 public PanoramaViewHelper getPanoramaViewHelper() {
307 return mPanoramaViewHelper;
310 protected boolean isFullscreen() {
311 return (getWindow().getAttributes().flags
312 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
315 private BatchService mBatchService;
316 private boolean mBatchServiceIsBound = false;
317 private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
319 public void onServiceConnected(ComponentName className, IBinder service) {
320 mBatchService = ((BatchService.LocalBinder)service).getService();
324 public void onServiceDisconnected(ComponentName className) {
325 mBatchService = null;
329 private void doBindBatchService() {
330 bindService(new Intent(this, BatchService.class), mBatchServiceConnection, Context.BIND_AUTO_CREATE);
331 mBatchServiceIsBound = true;
334 private void doUnbindBatchService() {
335 if (mBatchServiceIsBound) {
336 // Detach our existing connection.
337 unbindService(mBatchServiceConnection);
338 mBatchServiceIsBound = false;
342 public ThreadPool getBatchServiceThreadPoolIfAvailable() {
343 if (mBatchServiceIsBound && mBatchService != null) {
344 return mBatchService.getThreadPool();
346 throw new RuntimeException("Batch service unavailable");
350 public void printSelectedImage(Uri uri) {
354 String path = ImageLoader.getLocalPathFromUri(this, uri);
356 Uri localUri = Uri.parse(path);
357 path = localUri.getLastPathSegment();
359 path = uri.getLastPathSegment();
361 PrintHelper printer = new PrintHelper(this);
363 printer.printBitmap(path, uri);
364 } catch (FileNotFoundException fnfe) {
365 Log.e(TAG, "Error printing an image", fnfe);