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.app.ActionBar; 20import android.app.Activity; 21import android.content.BroadcastReceiver; 22import android.content.ContentResolver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.content.res.Configuration; 27import android.os.BatteryManager; 28import android.os.Bundle; 29import android.provider.Settings; 30import android.provider.Settings.SettingNotFoundException; 31import android.view.Menu; 32import android.view.MenuInflater; 33import android.view.MenuItem; 34import android.view.Window; 35import android.view.WindowManager; 36 37import com.android.gallery3d.R; 38import com.android.gallery3d.anim.StateTransitionAnimation; 39import com.android.gallery3d.ui.GLView; 40import com.android.gallery3d.ui.PreparePageFadeoutTexture; 41import com.android.gallery3d.ui.RawTexture; 42import com.android.gallery3d.util.GalleryUtils; 43 44abstract public class ActivityState { 45 protected static final int FLAG_HIDE_ACTION_BAR = 1; 46 protected static final int FLAG_HIDE_STATUS_BAR = 2; 47 protected static final int FLAG_SCREEN_ON_WHEN_PLUGGED = 4; 48 protected static final int FLAG_SCREEN_ON_ALWAYS = 8; 49 protected static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 16; 50 protected static final int FLAG_SHOW_WHEN_LOCKED = 32; 51 52 protected AbstractGalleryActivity mActivity; 53 protected Bundle mData; 54 protected int mFlags; 55 56 protected ResultEntry mReceivedResults; 57 protected ResultEntry mResult; 58 59 protected static class ResultEntry { 60 public int requestCode; 61 public int resultCode = Activity.RESULT_CANCELED; 62 public Intent resultData; 63 } 64 65 protected boolean mHapticsEnabled; 66 private ContentResolver mContentResolver; 67 68 private boolean mDestroyed = false; 69 private boolean mPlugged = false; 70 boolean mIsFinishing = false; 71 72 private static final String KEY_TRANSITION_IN = "transition-in"; 73 74 private StateTransitionAnimation.Transition mNextTransition = 75 StateTransitionAnimation.Transition.None; 76 private StateTransitionAnimation mIntroAnimation; 77 private GLView mContentPane; 78 79 protected ActivityState() { 80 } 81 82 protected void setContentPane(GLView content) { 83 mContentPane = content; 84 if (mIntroAnimation != null) { 85 mContentPane.setIntroAnimation(mIntroAnimation); 86 mIntroAnimation = null; 87 } 88 mContentPane.setBackgroundColor(getBackgroundColor()); 89 mActivity.getGLRoot().setContentPane(mContentPane); 90 } 91 92 void initialize(AbstractGalleryActivity activity, Bundle data) { 93 mActivity = activity; 94 mData = data; 95 mContentResolver = activity.getAndroidContext().getContentResolver(); 96 } 97 98 public Bundle getData() { 99 return mData; 100 } 101 102 protected void onBackPressed() { 103 mActivity.getStateManager().finishState(this); 104 } 105 106 protected void setStateResult(int resultCode, Intent data) { 107 if (mResult == null) return; 108 mResult.resultCode = resultCode; 109 mResult.resultData = data; 110 } 111 112 protected void onConfigurationChanged(Configuration config) { 113 } 114 115 protected void onSaveState(Bundle outState) { 116 } 117 118 protected void onStateResult(int requestCode, int resultCode, Intent data) { 119 } 120 121 protected float[] mBackgroundColor; 122 123 protected int getBackgroundColorId() { 124 return R.color.default_background; 125 } 126 127 protected float[] getBackgroundColor() { 128 return mBackgroundColor; 129 } 130 131 protected void onCreate(Bundle data, Bundle storedState) { 132 mBackgroundColor = GalleryUtils.intColorToFloatARGBArray( 133 mActivity.getResources().getColor(getBackgroundColorId())); 134 } 135 136 protected void clearStateResult() { 137 } 138 139 BroadcastReceiver mPowerIntentReceiver = new BroadcastReceiver() { 140 @Override 141 public void onReceive(Context context, Intent intent) { 142 final String action = intent.getAction(); 143 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 144 boolean plugged = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)); 145 146 if (plugged != mPlugged) { 147 mPlugged = plugged; 148 setScreenFlags(); 149 } 150 } 151 } 152 }; 153 154 private void setScreenFlags() { 155 final Window win = mActivity.getWindow(); 156 final WindowManager.LayoutParams params = win.getAttributes(); 157 if ((0 != (mFlags & FLAG_SCREEN_ON_ALWAYS)) || 158 (mPlugged && 0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED))) { 159 params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 160 } else { 161 params.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 162 } 163 if (0 != (mFlags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)) { 164 params.flags |= WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 165 } else { 166 params.flags &= ~WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 167 } 168 if (0 != (mFlags & FLAG_SHOW_WHEN_LOCKED)) { 169 params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 170 } else { 171 params.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 172 } 173 win.setAttributes(params); 174 } 175 176 protected void transitionOnNextPause(Class<? extends ActivityState> outgoing, 177 Class<? extends ActivityState> incoming, StateTransitionAnimation.Transition hint) { 178 if (outgoing == PhotoPage.class && incoming == AlbumPage.class) { 179 mNextTransition = StateTransitionAnimation.Transition.Outgoing; 180 } else if (outgoing == AlbumPage.class && incoming == PhotoPage.class) { 181 mNextTransition = StateTransitionAnimation.Transition.PhotoIncoming; 182 } else { 183 mNextTransition = hint; 184 } 185 } 186 187 protected void onPause() { 188 if (0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED)) { 189 ((Activity) mActivity).unregisterReceiver(mPowerIntentReceiver); 190 } 191 if (mNextTransition != StateTransitionAnimation.Transition.None) { 192 mActivity.getTransitionStore().put(KEY_TRANSITION_IN, mNextTransition); 193 PreparePageFadeoutTexture.prepareFadeOutTexture(mActivity, mContentPane); 194 mNextTransition = StateTransitionAnimation.Transition.None; 195 } 196 } 197 198 // should only be called by StateManager 199 void resume() { 200 AbstractGalleryActivity activity = mActivity; 201 ActionBar actionBar = activity.getActionBar(); 202 if (actionBar != null) { 203 if ((mFlags & FLAG_HIDE_ACTION_BAR) != 0) { 204 actionBar.hide(); 205 } else { 206 actionBar.show(); 207 } 208 int stateCount = mActivity.getStateManager().getStateCount(); 209 mActivity.getGalleryActionBar().setDisplayOptions(stateCount > 1, true); 210 // Default behavior, this can be overridden in ActivityState's onResume. 211 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 212 } 213 214 activity.invalidateOptionsMenu(); 215 216 setScreenFlags(); 217 218 boolean lightsOut = ((mFlags & FLAG_HIDE_STATUS_BAR) != 0); 219 mActivity.getGLRoot().setLightsOutMode(lightsOut); 220 221 ResultEntry entry = mReceivedResults; 222 if (entry != null) { 223 mReceivedResults = null; 224 onStateResult(entry.requestCode, entry.resultCode, entry.resultData); 225 } 226 227 if (0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED)) { 228 // we need to know whether the device is plugged in to do this correctly 229 final IntentFilter filter = new IntentFilter(); 230 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 231 activity.registerReceiver(mPowerIntentReceiver, filter); 232 } 233 234 try { 235 mHapticsEnabled = Settings.System.getInt(mContentResolver, 236 Settings.System.HAPTIC_FEEDBACK_ENABLED) != 0; 237 } catch (SettingNotFoundException e) { 238 mHapticsEnabled = false; 239 } 240 241 onResume(); 242 243 // the transition store should be cleared after resume; 244 mActivity.getTransitionStore().clear(); 245 } 246 247 // a subclass of ActivityState should override the method to resume itself 248 protected void onResume() { 249 RawTexture fade = mActivity.getTransitionStore().get( 250 PreparePageFadeoutTexture.KEY_FADE_TEXTURE); 251 mNextTransition = mActivity.getTransitionStore().get( 252 KEY_TRANSITION_IN, StateTransitionAnimation.Transition.None); 253 if (mNextTransition != StateTransitionAnimation.Transition.None) { 254 mIntroAnimation = new StateTransitionAnimation(mNextTransition, fade); 255 mNextTransition = StateTransitionAnimation.Transition.None; 256 } 257 } 258 259 protected boolean onCreateActionBar(Menu menu) { 260 // TODO: we should return false if there is no menu to show 261 // this is a workaround for a bug in system 262 return true; 263 } 264 265 protected boolean onItemSelected(MenuItem item) { 266 return false; 267 } 268 269 protected void onDestroy() { 270 mDestroyed = true; 271 } 272 273 boolean isDestroyed() { 274 return mDestroyed; 275 } 276 277 public boolean isFinishing() { 278 return mIsFinishing; 279 } 280 281 protected MenuInflater getSupportMenuInflater() { 282 return mActivity.getMenuInflater(); 283 } 284} 285