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