1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.app;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Linimport android.annotation.TargetApi;
202abaaf7caa9a83ba1ea759868aabde7f21387184John Reckimport android.app.Activity;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.app.AlertDialog;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.BroadcastReceiver;
23a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescuimport android.content.ComponentName;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.DialogInterface;
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.DialogInterface.OnCancelListener;
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.DialogInterface.OnClickListener;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Intent;
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.IntentFilter;
30a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescuimport android.content.ServiceConnection;
318e565703e8d482421714383a8ad40a67929ce2daOwen Linimport android.content.res.Configuration;
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Bundle;
33a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescuimport android.os.IBinder;
342abaaf7caa9a83ba1ea759868aabde7f21387184John Reckimport android.view.Menu;
352abaaf7caa9a83ba1ea759868aabde7f21387184John Reckimport android.view.MenuItem;
364d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Tingimport android.view.Window;
374d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Tingimport android.view.WindowManager;
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
394bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.R;
40b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Linimport com.android.gallery3d.common.ApiHelper;
414bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.data.DataManager;
42d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Linimport com.android.gallery3d.data.MediaItem;
434bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.ui.GLRoot;
444bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Linimport com.android.gallery3d.ui.GLRootView;
45e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberlingimport com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper;
46a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescuimport com.android.gallery3d.util.ThreadPool;
47ca6f04e27bbcab953bd3f9dcf50476a1c4b70aacBobby Georgescuimport com.android.photos.data.GalleryBitmapPool;
484bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin
492abaaf7caa9a83ba1ea759868aabde7f21387184John Reckpublic class AbstractGalleryActivity extends Activity implements GalleryContext {
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @SuppressWarnings("unused")
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "AbstractGalleryActivity";
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GLRootView mGLRootView;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private StateManager mStateManager;
548cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen    private GalleryActionBar mActionBar;
55bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang    private OrientationManager mOrientationManager;
56616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    private TransitionStore mTransitionStore = new TransitionStore();
57b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li    private boolean mDisableToggleStatusBar;
58e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling    private PanoramaViewHelper mPanoramaViewHelper;
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private AlertDialog mAlertDialog = null;
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onReceive(Context context, Intent intent) {
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (getExternalCacheDir() != null) onStorageReady();
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
704d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    protected void onCreate(Bundle savedInstanceState) {
714d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting        super.onCreate(savedInstanceState);
72bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang        mOrientationManager = new OrientationManager(this);
734d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting        toggleStatusBarByOrientation();
747896b2ce915cbd180682e94e2fe3d246ff760763Owen Lin        getWindow().setBackgroundDrawable(null);
75e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling        mPanoramaViewHelper = new PanoramaViewHelper(this);
76e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling        mPanoramaViewHelper.onCreate();
77a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        doBindBatchService();
784d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    }
794d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting
804d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    @Override
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onSaveInstanceState(Bundle outState) {
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.lockRenderThread();
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super.onSaveInstanceState(outState);
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getStateManager().saveState(outState);
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mGLRootView.unlockRenderThread();
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
918e565703e8d482421714383a8ad40a67929ce2daOwen Lin    @Override
928e565703e8d482421714383a8ad40a67929ce2daOwen Lin    public void onConfigurationChanged(Configuration config) {
938e565703e8d482421714383a8ad40a67929ce2daOwen Lin        super.onConfigurationChanged(config);
948e565703e8d482421714383a8ad40a67929ce2daOwen Lin        mStateManager.onConfigurationChange(config);
955d4b8fd9fd2e601b780c027ef912c8fabfe3ee1eBobby Georgescu        getGalleryActionBar().onConfigurationChanged();
96108667b88ed4046556e967fcb9541fa9efd7c606Ray Chen        invalidateOptionsMenu();
974d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting        toggleStatusBarByOrientation();
988e565703e8d482421714383a8ad40a67929ce2daOwen Lin    }
998e565703e8d482421714383a8ad40a67929ce2daOwen Lin
100b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    @Override
101b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    public boolean onCreateOptionsMenu(Menu menu) {
102b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin        super.onCreateOptionsMenu(menu);
103b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin        return getStateManager().createOptionsMenu(menu);
104b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    }
105b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin
106b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    @Override
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Context getAndroidContext() {
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return this;
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
111b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    @Override
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public DataManager getDataManager() {
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return ((GalleryApp) getApplication()).getDataManager();
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
116b1eb01cd02d1e75e6b9c3e593f6ff34335e2ca8aOwen Lin    @Override
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public ThreadPool getThreadPool() {
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return ((GalleryApp) getApplication()).getThreadPool();
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public synchronized StateManager getStateManager() {
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mStateManager == null) {
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mStateManager = new StateManager(this);
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mStateManager;
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public GLRoot getGLRoot() {
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mGLRootView;
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
132bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang    public OrientationManager getOrientationManager() {
133bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang        return mOrientationManager;
134bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang    }
135bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void setContentView(int resId) {
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.setContentView(resId);
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onStorageReady() {
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mAlertDialog != null) {
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlertDialog.dismiss();
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlertDialog = null;
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            unregisterReceiver(mMountReceiver);
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onStart() {
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onStart();
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (getExternalCacheDir() == null) {
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            OnCancelListener onCancel = new OnCancelListener() {
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                @Override
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                public void onCancel(DialogInterface dialog) {
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    finish();
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            };
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            OnClickListener onClick = new OnClickListener() {
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                @Override
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                public void onClick(DialogInterface dialog, int which) {
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    dialog.cancel();
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            };
166840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            AlertDialog.Builder builder = new AlertDialog.Builder(this)
167fd3071dfc28b4caad583c77d7a4d9dad8fb86a3aOwen Lin                    .setTitle(R.string.no_external_storage_title)
168fd3071dfc28b4caad583c77d7a4d9dad8fb86a3aOwen Lin                    .setMessage(R.string.no_external_storage)
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    .setNegativeButton(android.R.string.cancel, onClick)
170840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang                    .setOnCancelListener(onCancel);
171840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
172840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang                setAlertDialogIconAttribute(builder);
173840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            } else {
174840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang                builder.setIcon(android.R.drawable.ic_dialog_alert);
175840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            }
176840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            mAlertDialog = builder.show();
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            registerReceiver(mMountReceiver, mMountFilter);
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
179e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling        mPanoramaViewHelper.onStart();
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
182840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
183840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    private static void setAlertDialogIconAttribute(
184840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang            AlertDialog.Builder builder) {
185840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang        builder.setIconAttribute(android.R.attr.alertDialogIcon);
186840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang    }
187840ae396bac4ff8ff34e88c8d2a1773cb112a4b6Chih-Chung Chang
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onStop() {
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onStop();
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mAlertDialog != null) {
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            unregisterReceiver(mMountReceiver);
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlertDialog.dismiss();
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlertDialog = null;
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
196e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling        mPanoramaViewHelper.onStop();
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onResume() {
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onResume();
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.lockRenderThread();
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getStateManager().resume();
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getDataManager().resume();
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mGLRootView.unlockRenderThread();
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.onResume();
210bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang        mOrientationManager.resume();
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onPause() {
215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onPause();
216bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang        mOrientationManager.pause();
217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.onPause();
218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.lockRenderThread();
219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getStateManager().pause();
221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getDataManager().pause();
222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mGLRootView.unlockRenderThread();
224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
225f52ceba89962829aa12f5caba131580e8da85880Bobby Georgescu        GalleryBitmapPool.getInstance().clear();
226cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        MediaItem.getBytesBufferPool().clear();
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
2303957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li    protected void onDestroy() {
2313957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li        super.onDestroy();
2323957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li        mGLRootView.lockRenderThread();
2333957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li        try {
2343957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li            getStateManager().destroy();
2353957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li        } finally {
2363957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li            mGLRootView.unlockRenderThread();
2373957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li        }
238a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        doUnbindBatchService();
2393957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li    }
2403957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li
2413957efd020f2e80d79cd3fed019f2883668a1c9eWu-cheng Li    @Override
242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGLRootView.lockRenderThread();
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            getStateManager().notifyActivityResult(
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    requestCode, resultCode, data);
247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } finally {
248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mGLRootView.unlockRenderThread();
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
2532c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang    public void onBackPressed() {
2542c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        // send the back event to the top sub-state
2552c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        GLRoot root = getGLRoot();
2562c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        root.lockRenderThread();
2572c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        try {
2582c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang            getStateManager().onBackPressed();
2592c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        } finally {
2602c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang            root.unlockRenderThread();
2612c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang        }
2622c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang    }
2632c6173822a612597c79be41b126367ddfbb5d518Chih-Chung Chang
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public GalleryActionBar getGalleryActionBar() {
2658cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen        if (mActionBar == null) {
2668cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen            mActionBar = new GalleryActionBar(this);
2678cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen        }
2688cab3e872dd95e55ba34fdb94269a0c5069e72aeRay Chen        return mActionBar;
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
2704d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting
271655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen    @Override
272655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen    public boolean onOptionsItemSelected(MenuItem item) {
273655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen        GLRoot root = getGLRoot();
274655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen        root.lockRenderThread();
275655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen        try {
276655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen            return getStateManager().itemSelected(item);
277655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen        } finally {
278655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen            root.unlockRenderThread();
279655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen        }
280655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen    }
281655f63f04638dfe31045eab1b6b4c39cc2db10dbRay Chen
282b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li    protected void disableToggleStatusBar() {
283b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li        mDisableToggleStatusBar = true;
284b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li    }
285b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li
2864d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    // Shows status bar in portrait view, hide in landscape view
2874d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    private void toggleStatusBarByOrientation() {
288b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li        if (mDisableToggleStatusBar) return;
289b1db75c15ef546fef26ee7e34321f3087562a0f7Wu-cheng Li
290fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen        Window win = getWindow();
291fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
292fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen            win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
293fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen        } else {
294fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen            win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
295fa011a292ea27fd6a885f980596e959ca83b9a4fRay Chen        }
2964d50f7373a6205e197ffc1b73cdc5ffcbeb79fcaPin Ting    }
297616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
298616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    public TransitionStore getTransitionStore() {
299616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin        return mTransitionStore;
300616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    }
301e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling
302e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling    public PanoramaViewHelper getPanoramaViewHelper() {
303e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling        return mPanoramaViewHelper;
304e3b50f1bfcfa5c8729f31788eac1a6109a88988bSascha Haeberling    }
305a850a543225e9f7a72c5a49bb6099573c7efda13Bobby Georgescu
306a850a543225e9f7a72c5a49bb6099573c7efda13Bobby Georgescu    protected boolean isFullscreen() {
307a850a543225e9f7a72c5a49bb6099573c7efda13Bobby Georgescu        return (getWindow().getAttributes().flags
308a850a543225e9f7a72c5a49bb6099573c7efda13Bobby Georgescu                & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
309a850a543225e9f7a72c5a49bb6099573c7efda13Bobby Georgescu    }
310a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu
311a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    private BatchService mBatchService;
312a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    private boolean mBatchServiceIsBound = false;
313a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
314a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        public void onServiceConnected(ComponentName className, IBinder service) {
315a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            mBatchService = ((BatchService.LocalBinder)service).getService();
316a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        }
317a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu
318a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        public void onServiceDisconnected(ComponentName className) {
319a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            mBatchService = null;
320a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        }
321a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    };
322a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu
323a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    private void doBindBatchService() {
324a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        bindService(new Intent(this, BatchService.class), mBatchServiceConnection, Context.BIND_AUTO_CREATE);
325a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        mBatchServiceIsBound = true;
326a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    }
327a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu
328a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    private void doUnbindBatchService() {
329a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        if (mBatchServiceIsBound) {
330a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            // Detach our existing connection.
331a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            unbindService(mBatchServiceConnection);
332a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            mBatchServiceIsBound = false;
333a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        }
334a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    }
335a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu
336a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    public ThreadPool getBatchServiceThreadPoolIfAvailable() {
337a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        if (mBatchServiceIsBound && mBatchService != null) {
338a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu            return mBatchService.getThreadPool();
339a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        } else {
340d00f521a3138a8f244c91748b0277290edbf61f6Bobby Georgescu            throw new RuntimeException("Batch service unavailable");
341a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu        }
342a2d0d34a90543ee19ea295e72c112fde18fb3828Bobby Georgescu    }
343f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
344