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.app.Activity; 20 import android.app.AlertDialog; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.DialogInterface; 24 import android.content.DialogInterface.OnCancelListener; 25 import android.content.DialogInterface.OnClickListener; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.res.Configuration; 29 import android.os.Bundle; 30 import android.view.MenuItem; 31 import android.view.Window; 32 import android.view.WindowManager; 33 34 import com.android.gallery3d.R; 35 import com.android.gallery3d.data.DataManager; 36 import com.android.gallery3d.data.MediaItem; 37 import com.android.gallery3d.ui.GLRoot; 38 import com.android.gallery3d.ui.GLRootView; 39 import com.android.gallery3d.util.ThreadPool; 40 41 public class AbstractGalleryActivity extends Activity implements GalleryActivity { 42 @SuppressWarnings("unused") 43 private static final String TAG = "AbstractGalleryActivity"; 44 private GLRootView mGLRootView; 45 private StateManager mStateManager; 46 private GalleryActionBar mActionBar; 47 private OrientationManager mOrientationManager; 48 private TransitionStore mTransitionStore = new TransitionStore(); 49 private boolean mDisableToggleStatusBar; 50 51 private AlertDialog mAlertDialog = null; 52 private BroadcastReceiver mMountReceiver = new BroadcastReceiver() { 53 @Override 54 public void onReceive(Context context, Intent intent) { 55 if (getExternalCacheDir() != null) onStorageReady(); 56 } 57 }; 58 private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 59 60 @Override 61 protected void onCreate(Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 mOrientationManager = new OrientationManager(this); 64 toggleStatusBarByOrientation(); 65 getWindow().setBackgroundDrawable(null); 66 } 67 68 @Override 69 protected void onSaveInstanceState(Bundle outState) { 70 mGLRootView.lockRenderThread(); 71 try { 72 super.onSaveInstanceState(outState); 73 getStateManager().saveState(outState); 74 } finally { 75 mGLRootView.unlockRenderThread(); 76 } 77 } 78 79 @Override 80 public void onConfigurationChanged(Configuration config) { 81 super.onConfigurationChanged(config); 82 mStateManager.onConfigurationChange(config); 83 invalidateOptionsMenu(); 84 toggleStatusBarByOrientation(); 85 } 86 87 public Context getAndroidContext() { 88 return this; 89 } 90 91 public DataManager getDataManager() { 92 return ((GalleryApp) getApplication()).getDataManager(); 93 } 94 95 public ThreadPool getThreadPool() { 96 return ((GalleryApp) getApplication()).getThreadPool(); 97 } 98 99 public synchronized StateManager getStateManager() { 100 if (mStateManager == null) { 101 mStateManager = new StateManager(this); 102 } 103 return mStateManager; 104 } 105 106 public GLRoot getGLRoot() { 107 return mGLRootView; 108 } 109 110 public OrientationManager getOrientationManager() { 111 return mOrientationManager; 112 } 113 114 @Override 115 public void setContentView(int resId) { 116 super.setContentView(resId); 117 mGLRootView = (GLRootView) findViewById(R.id.gl_root_view); 118 } 119 120 protected void onStorageReady() { 121 if (mAlertDialog != null) { 122 mAlertDialog.dismiss(); 123 mAlertDialog = null; 124 unregisterReceiver(mMountReceiver); 125 } 126 } 127 128 @Override 129 protected void onStart() { 130 super.onStart(); 131 if (getExternalCacheDir() == null) { 132 OnCancelListener onCancel = new OnCancelListener() { 133 @Override 134 public void onCancel(DialogInterface dialog) { 135 finish(); 136 } 137 }; 138 OnClickListener onClick = new OnClickListener() { 139 @Override 140 public void onClick(DialogInterface dialog, int which) { 141 dialog.cancel(); 142 } 143 }; 144 mAlertDialog = new AlertDialog.Builder(this) 145 .setIcon(android.R.drawable.ic_dialog_alert) 146 .setTitle("No Storage") 147 .setMessage("No external storage available.") 148 .setNegativeButton(android.R.string.cancel, onClick) 149 .setOnCancelListener(onCancel) 150 .show(); 151 registerReceiver(mMountReceiver, mMountFilter); 152 } 153 } 154 155 @Override 156 protected void onStop() { 157 super.onStop(); 158 if (mAlertDialog != null) { 159 unregisterReceiver(mMountReceiver); 160 mAlertDialog.dismiss(); 161 mAlertDialog = null; 162 } 163 } 164 165 @Override 166 protected void onResume() { 167 super.onResume(); 168 mGLRootView.lockRenderThread(); 169 try { 170 getStateManager().resume(); 171 getDataManager().resume(); 172 } finally { 173 mGLRootView.unlockRenderThread(); 174 } 175 mGLRootView.onResume(); 176 mOrientationManager.resume(); 177 } 178 179 @Override 180 protected void onPause() { 181 super.onPause(); 182 mOrientationManager.pause(); 183 mGLRootView.onPause(); 184 mGLRootView.lockRenderThread(); 185 try { 186 getStateManager().pause(); 187 getDataManager().pause(); 188 } finally { 189 mGLRootView.unlockRenderThread(); 190 } 191 MediaItem.getMicroThumbPool().clear(); 192 MediaItem.getThumbPool().clear(); 193 MediaItem.getBytesBufferPool().clear(); 194 } 195 196 @Override 197 protected void onDestroy() { 198 super.onDestroy(); 199 mGLRootView.lockRenderThread(); 200 try { 201 getStateManager().destroy(); 202 } finally { 203 mGLRootView.unlockRenderThread(); 204 } 205 } 206 207 @Override 208 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 209 mGLRootView.lockRenderThread(); 210 try { 211 getStateManager().notifyActivityResult( 212 requestCode, resultCode, data); 213 } finally { 214 mGLRootView.unlockRenderThread(); 215 } 216 } 217 218 @Override 219 public void onBackPressed() { 220 // send the back event to the top sub-state 221 GLRoot root = getGLRoot(); 222 root.lockRenderThread(); 223 try { 224 getStateManager().onBackPressed(); 225 } finally { 226 root.unlockRenderThread(); 227 } 228 } 229 230 @Override 231 public GalleryActionBar getGalleryActionBar() { 232 if (mActionBar == null) { 233 mActionBar = new GalleryActionBar(this); 234 } 235 return mActionBar; 236 } 237 238 @Override 239 public boolean onOptionsItemSelected(MenuItem item) { 240 GLRoot root = getGLRoot(); 241 root.lockRenderThread(); 242 try { 243 return getStateManager().itemSelected(item); 244 } finally { 245 root.unlockRenderThread(); 246 } 247 } 248 249 protected void disableToggleStatusBar() { 250 mDisableToggleStatusBar = true; 251 } 252 253 // Shows status bar in portrait view, hide in landscape view 254 private void toggleStatusBarByOrientation() { 255 if (mDisableToggleStatusBar) return; 256 257 Window win = getWindow(); 258 if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 259 win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 260 } else { 261 win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 262 } 263 } 264 265 @Override 266 public TransitionStore getTransitionStore() { 267 return mTransitionStore; 268 } 269 } 270