ActivityBase.java revision ae8b4eecd123aae8593b620b9e0783a03a907a98
14d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang/*
24d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Copyright (C) 2009 The Android Open Source Project
34d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang *
44d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
54d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * you may not use this file except in compliance with the License.
64d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * You may obtain a copy of the License at
74d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang *
84d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
94d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang *
104d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software
114d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
124d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * See the License for the specific language governing permissions and
144d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * limitations under the License.
154d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang */
164d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang
174d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Changpackage com.android.camera;
184d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang
19b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.BroadcastReceiver;
20c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.content.ContentResolver;
21b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.Context;
225df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Liimport android.content.Intent;
23b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.IntentFilter;
24c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Liimport android.graphics.Bitmap;
25195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Liimport android.graphics.BitmapFactory;
2678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport android.graphics.Rect;
27296d27772b9543d55820e1d24d900fea959f1b7aPin Tingimport android.hardware.Camera.Parameters;
28c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.os.AsyncTask;
298608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Changimport android.os.Bundle;
30844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Handler;
31844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Message;
32b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.support.v4.content.LocalBroadcastManager;
337d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log;
344c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent;
35c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View;
36a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window;
37892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager;
38525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.AlphaAnimation;
39525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.Animation;
40a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport android.view.animation.DecelerateInterpolator;
41892781804513066b68b4a2fa6f846e862dac252aOwen Lin
42d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Liimport com.android.camera.ui.CameraPicker;
43525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport com.android.camera.ui.LayoutChangeNotifier;
44892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.PopupManager;
45892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.RotateImageView;
46a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.AbstractGalleryActivity;
4778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.app.AppBridge;
48a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.GalleryActionBar;
49a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport com.android.gallery3d.app.PhotoPage;
50c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Liimport com.android.gallery3d.common.ApiHelper;
51c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Liimport com.android.gallery3d.ui.BitmapScreenNail;
5278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.ui.ScreenNail;
53a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils;
544d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang
55aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File;
56aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li
5777c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/**
587673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li * Superclass of Camera and VideoCamera activities.
5977c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */
60525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongpublic abstract class ActivityBase extends AbstractGalleryActivity
61525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong        implements LayoutChangeNotifier.Listener {
62a6b966047b6215b02c502a3f143106070abf6009Angus Kong
637d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    private static final String TAG = "ActivityBase";
6476507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li    private static final boolean LOGV = false;
65c38faeb66a3f2cc96e4c5e951228d9b01e12edb3Chih-Chung Chang    private static final int CAMERA_APP_VIEW_TOGGLE_TIME = 100;  // milliseconds
66b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    private static final String ACTION_DELETE_PICTURE =
67b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            "com.android.gallery3d.action.DELETE_PICTURE";
6847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
695df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    private int mResultCodeForTesting;
705df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    private Intent mResultDataForTesting;
714edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    private OnScreenHint mStorageHint;
72bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    private View mSingleTapArea;
73a6b966047b6215b02c502a3f143106070abf6009Angus Kong
74c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    // The bitmap of the last captured picture thumbnail and the URI of the
75c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    // original picture.
76c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    protected Thumbnail mThumbnail;
778a674bebfba0c4dd4b01018276d20f198f65f19eWu-cheng Li    protected int mThumbnailViewWidth; // layout width of the thumbnail
78c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask;
79d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // An imageview showing the last captured picture thumbnail.
80d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    protected RotateImageView mThumbnailView;
81d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    protected CameraPicker mCameraPicker;
82d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li
83475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected boolean mOpenCameraFail;
84475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected boolean mCameraDisabled;
85475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected CameraManager.CameraProxy mCameraDevice;
86296d27772b9543d55820e1d24d900fea959f1b7aPin Ting    protected Parameters mParameters;
875c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    // The activity is paused. The classes that extend this class should set
885c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    // mPaused the first thing in onResume/onPause.
895c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    protected boolean mPaused;
90a6b966047b6215b02c502a3f143106070abf6009Angus Kong    protected GalleryActionBar mActionBar;
91475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
92475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    // multiple cameras support
93475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected int mNumberOfCameras;
94475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected int mCameraId;
95d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // The activity is going to switch to the specified camera id. This is
96d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // needed because texture copy is done in GL thread. -1 means camera is not
97d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // switching.
98d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    protected int mPendingSwitchCameraId = -1;
99475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
10078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    protected MyAppBridge mAppBridge;
101c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li    protected ScreenNail mCameraScreenNail; // This shows camera preview.
102a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // The view containing only camera related widgets like control panel,
103a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // indicator bar, focus indicator and etc.
104a6b966047b6215b02c502a3f143106070abf6009Angus Kong    protected View mCameraAppView;
1051cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li    protected boolean mShowCameraAppView = true;
10647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private Animation mCameraAppViewFadeIn;
10747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private Animation mCameraAppViewFadeOut;
10847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
109844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
110844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private static final int UPDATE_STORAGE_HINT = 0;
111844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private final Handler mHandler = new Handler() {
112844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            @Override
113844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            public void handleMessage(Message msg) {
114844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                switch (msg.what) {
115844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    case UPDATE_STORAGE_HINT:
116844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                        updateStorageHint();
117844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                        return;
118844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                }
119844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            }
120844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    };
121844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
122844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
123844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        @Override
124844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        public void onReceive(Context context, Intent intent) {
125844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            String action = intent.getAction();
126844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            if (action.equals(Intent.ACTION_MEDIA_MOUNTED)
127844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_UNMOUNTED)
128844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_CHECKING)
129844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
130844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                updateStorageSpaceAndHint();
131844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            }
132844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        }
133844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    };
134844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
135b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    private boolean mUpdateThumbnailDelayed;
136b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    private IntentFilter mDeletePictureFilter =
137b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            new IntentFilter(ACTION_DELETE_PICTURE);
138b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    private BroadcastReceiver mDeletePictureReceiver =
139b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            new BroadcastReceiver() {
140b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                @Override
141b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                public void onReceive(Context context, Intent intent) {
142b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    if (mShowCameraAppView) {
143b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        getLastThumbnailUncached();
144b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    } else {
145b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        mUpdateThumbnailDelayed = true;
146b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    }
147b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                }
148b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            };
149a6b966047b6215b02c502a3f143106070abf6009Angus Kong
150475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected class CameraOpenThread extends Thread {
151475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        @Override
152475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void run() {
153475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            try {
154475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId);
155296d27772b9543d55820e1d24d900fea959f1b7aPin Ting                mParameters = mCameraDevice.getParameters();
156475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            } catch (CameraHardwareException e) {
157475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mOpenCameraFail = true;
158475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            } catch (CameraDisabledException e) {
159475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mCameraDisabled = true;
160475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            }
161475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
162475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
1635df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
1644d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    @Override
1658608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    public void onCreate(Bundle icicle) {
166e5b6a36e64ef2c2cb1435c138a5fc179e9a6bc9aWu-cheng Li        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
1676a4a72b643929701c5d7c8b68b91d762c7277c20Wu-cheng Li        super.disableToggleStatusBar();
168a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // Set a theme with action bar. It is not specified in manifest because
169a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // we want to hide it by default. setTheme must happen before
170a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // setContentView.
171a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        //
172a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // This must be set before we call super.onCreate(), where the window's
173a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // background is removed.
174a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        setTheme(R.style.Theme_Gallery);
175a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
176ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        if (ApiHelper.HAS_ACTION_BAR) {
177ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang            requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
178ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        } else {
179ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang            requestWindowFeature(Window.FEATURE_NO_TITLE);
180ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        }
181a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin
1828608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang        super.onCreate(icicle);
1838608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    }
1848608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang
18505e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong    public boolean isPanoramaActivity() {
18605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        return false;
18705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong    }
18805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong
1898608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    @Override
190b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    protected void onResume() {
191b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        super.onResume();
192b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
193b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        manager.registerReceiver(mDeletePictureReceiver, mDeletePictureFilter);
194844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
195844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        installIntentFilter();
196844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        if(updateStorageHintOnResume()) {
197844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            updateStorageSpace();
198844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            mHandler.sendEmptyMessageDelayed(UPDATE_STORAGE_HINT, 200);
199844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        }
200b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    }
201b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
202b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    @Override
2037d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    protected void onPause() {
2045c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li        super.onPause();
205b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
206b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        manager.unregisterReceiver(mDeletePictureReceiver);
207b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
2087d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller        if (LOGV) Log.v(TAG, "onPause");
209aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        saveThumbnailToFile();
2104edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong
211c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        if (mLoadThumbnailTask != null) {
212c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mLoadThumbnailTask.cancel(true);
213c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mLoadThumbnailTask = null;
214c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        }
215c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
2164edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (mStorageHint != null) {
2174edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.cancel();
2184edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint = null;
2194edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
220844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
221844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        unregisterReceiver(mReceiver);
2227d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    }
2237d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller
2247d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    @Override
22572fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    public void setContentView(int layoutResID) {
22672fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        super.setContentView(layoutResID);
22772fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        // getActionBar() should be after setContentView
22872fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        mActionBar = new GalleryActionBar(this);
22972fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        mActionBar.hide();
23072fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    }
23172fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li
23272fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    @Override
2334d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    public boolean onSearchRequested() {
2344d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang        return false;
2354d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    }
2367673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li
2377673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    @Override
2387673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    public boolean onKeyDown(int keyCode, KeyEvent event) {
2397673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        // Prevent software keyboard or voice search from showing up.
2407673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        if (keyCode == KeyEvent.KEYCODE_SEARCH
2417673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li                || keyCode == KeyEvent.KEYCODE_MENU) {
2427673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li            if (event.isLongPress()) return true;
2437673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        }
2440703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) {
2450703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu            return true;
2460703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        }
2477673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li
2487673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        return super.onKeyDown(keyCode, event);
2497673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    }
2505df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2510703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    @Override
2520703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    public boolean onKeyUp(int keyCode, KeyEvent event) {
2530703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) {
2540703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu            return true;
2550703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        }
2560703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        return super.onKeyUp(keyCode, event);
2570703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    }
2580703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu
2595df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    protected void setResultEx(int resultCode) {
2605df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultCodeForTesting = resultCode;
2615df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        setResult(resultCode);
2625df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2635df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2645df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    protected void setResultEx(int resultCode, Intent data) {
2655df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultCodeForTesting = resultCode;
2665df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultDataForTesting = data;
2675df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        setResult(resultCode, data);
2685df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2695df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2705df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    public int getResultCode() {
2715df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        return mResultCodeForTesting;
2725df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2735df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2745df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    public Intent getResultData() {
2755df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        return mResultDataForTesting;
2765df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2775f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang
2785f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    @Override
2795f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    protected void onDestroy() {
2805f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang        PopupManager.removeInstance(this);
2815f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang        super.onDestroy();
2825f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    }
2837d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller
284844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void installIntentFilter() {
285844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        // install an intent filter to receive SD card related events.
286844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        IntentFilter intentFilter =
287844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
288844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
289844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
290844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING);
291844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addDataScheme("file");
292844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        registerReceiver(mReceiver, intentFilter);
293844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
294844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
295844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageSpace() {
296844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        mStorageSpace = Storage.getAvailableSpace();
297844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
298844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
299844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected long getStorageSpace() {
300844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        return mStorageSpace;
301844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
302844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
303844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageSpaceAndHint() {
304844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageSpace();
305844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageHint(mStorageSpace);
306844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
307844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
308844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageHint() {
309844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageHint(mStorageSpace);
310844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
311844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
312844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected boolean updateStorageHintOnResume() {
313844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        return true;
314844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
315844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
3164edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    protected void updateStorageHint(long storageSpace) {
3174edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        String message = null;
3184edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (storageSpace == Storage.UNAVAILABLE) {
3194edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.no_storage);
3204edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (storageSpace == Storage.PREPARING) {
3214edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.preparing_sd);
3224edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
3234edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.access_sd_fail);
324844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
3254edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.spaceIsLow_content);
3264edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
3274edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong
3284edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (message != null) {
3294edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            if (mStorageHint == null) {
3304edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong                mStorageHint = OnScreenHint.makeText(this, message);
3314edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            } else {
3324edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong                mStorageHint.setText(message);
3334edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            }
3344edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.show();
3354edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (mStorageHint != null) {
3364edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.cancel();
3374edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint = null;
3384edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
3394edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    }
340c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
341a0b7c6b3c61b68db7f4eb33d81c886fb4e095f2cPin Ting    protected void updateThumbnailView() {
342c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        if (mThumbnail != null) {
343c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mThumbnailView.setBitmap(mThumbnail.getBitmap());
344c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mThumbnailView.setVisibility(View.VISIBLE);
345c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        } else {
346c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mThumbnailView.setBitmap(null);
347c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mThumbnailView.setVisibility(View.GONE);
348c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        }
349c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    }
350c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
351c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    protected void getLastThumbnail() {
352c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver());
353c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        // Suppose users tap the thumbnail view, go to the gallery, delete the
354c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        // image, and coming back to the camera. Thumbnail file will be invalid.
355c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        // Since the new thumbnail will be loaded in another thread later, the
356c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        // view should be set to gone to prevent from opening the invalid image.
357c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        updateThumbnailView();
358c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        if (mThumbnail == null) {
359b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            mLoadThumbnailTask = new LoadThumbnailTask(true).execute();
360c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        }
361c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    }
362c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
363b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    protected void getLastThumbnailUncached() {
364b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        if (mLoadThumbnailTask != null) mLoadThumbnailTask.cancel(true);
365b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        mLoadThumbnailTask = new LoadThumbnailTask(false).execute();
366b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    }
367b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
368aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li    private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> {
369b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        private boolean mLookAtCache;
370b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
371b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        public LoadThumbnailTask(boolean lookAtCache) {
372b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            mLookAtCache = lookAtCache;
373b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        }
374b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
375c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        @Override
376c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        protected Thumbnail doInBackground(Void... params) {
377c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            // Load the thumbnail from the file.
378c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            ContentResolver resolver = getContentResolver();
379b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            Thumbnail t = null;
380b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            if (mLookAtCache) {
381b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver);
382b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            }
383c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
384c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            if (isCancelled()) return null;
385c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
386c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            if (t == null) {
387b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                Thumbnail result[] = new Thumbnail[1];
388c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li                // Load the thumbnail from the media provider.
389b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                int code = Thumbnail.getLastThumbnailFromContentResolver(
390b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        resolver, result);
391b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                switch (code) {
392b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    case Thumbnail.THUMBNAIL_FOUND:
393b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        return result[0];
394b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    case Thumbnail.THUMBNAIL_NOT_FOUND:
395b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        return null;
396b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                    case Thumbnail.THUMBNAIL_DELETED:
397b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        cancel(true);
398b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                        return null;
399b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang                }
400c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            }
401c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            return t;
402c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        }
403c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
404c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        @Override
405c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        protected void onPostExecute(Thumbnail thumbnail) {
406b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            if (isCancelled()) return;
407c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            mThumbnail = thumbnail;
408c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li            updateThumbnailView();
409c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li        }
410c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li    }
411aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li
4126899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting    protected void gotoGallery() {
413252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting        // Move the next picture with capture animation. "1" means next.
414252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting        mAppBridge.switchWithCaptureAnimation(1);
4156899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting    }
4166899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting
417aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li    protected void saveThumbnailToFile() {
418aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        if (mThumbnail != null && !mThumbnail.fromFile()) {
419aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            new SaveThumbnailTask().execute(mThumbnail);
420aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        }
421aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li    }
422aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li
423aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li    private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> {
424aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        @Override
425aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        protected Void doInBackground(Thumbnail... params) {
426aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            final int n = params.length;
427aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            final File filesDir = getFilesDir();
428aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            for (int i = 0; i < n; i++) {
429aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li                params[i].saveLastThumbnailToFile(filesDir);
430aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            }
431aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li            return null;
432aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li        }
433aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li    }
434a6b966047b6215b02c502a3f143106070abf6009Angus Kong
435a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // Call this after setContentView.
436a6b966047b6215b02c502a3f143106070abf6009Angus Kong    protected void createCameraScreenNail(boolean getPictures) {
437a6b966047b6215b02c502a3f143106070abf6009Angus Kong        mCameraAppView = findViewById(R.id.camera_app_root);
438a6b966047b6215b02c502a3f143106070abf6009Angus Kong        Bundle data = new Bundle();
439a6b966047b6215b02c502a3f143106070abf6009Angus Kong        String path = "/local/all/";
440a6b966047b6215b02c502a3f143106070abf6009Angus Kong        // Intent mode does not show camera roll. Use 0 as a work around for
441a6b966047b6215b02c502a3f143106070abf6009Angus Kong        // invalid bucket id.
442a6b966047b6215b02c502a3f143106070abf6009Angus Kong        // TODO: add support of empty media set in gallery.
443a6b966047b6215b02c502a3f143106070abf6009Angus Kong        path += (getPictures ? MediaSetUtils.CAMERA_BUCKET_ID : "0");
444a6b966047b6215b02c502a3f143106070abf6009Angus Kong        data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path);
445a6b966047b6215b02c502a3f143106070abf6009Angus Kong        data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path);
446a6b966047b6215b02c502a3f143106070abf6009Angus Kong
44778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // Send an AppBridge to gallery to enable the camera preview.
44878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mAppBridge = new MyAppBridge();
44978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge);
450a6b966047b6215b02c502a3f143106070abf6009Angus Kong        getStateManager().startState(PhotoPage.class, data);
45178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mCameraScreenNail = mAppBridge.getCameraScreenNail();
452a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
453a6b966047b6215b02c502a3f143106070abf6009Angus Kong
45447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private class HideCameraAppView implements Animation.AnimationListener {
4551cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li        @Override
45647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationEnd(Animation animation) {
457f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            // We cannot set this as GONE because we want to receive the
458f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            // onLayoutChange() callback even when we are invisible.
459f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            mCameraAppView.setVisibility(View.INVISIBLE);
4601cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li        }
46147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
46247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        @Override
46347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationRepeat(Animation animation) {
46447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
46547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
46647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        @Override
46747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationStart(Animation animation) {
46847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
4691cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li    }
47078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
471c94cd4a5206b05541de0dc8a4821c64d0edba352Angus Kong    protected void updateCameraAppView() {
47247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        // Initialize the animation.
47347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        if (mCameraAppViewFadeIn == null) {
47447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn = new AlphaAnimation(0f, 1f);
47547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME);
47647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn.setInterpolator(new DecelerateInterpolator());
47747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
47847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut = new AlphaAnimation(1f, 0f);
47947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME);
48047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setInterpolator(new DecelerateInterpolator());
48147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setAnimationListener(new HideCameraAppView());
48247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
48347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
48478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mShowCameraAppView) {
48578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mCameraAppView.setVisibility(View.VISIBLE);
486d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // The "transparent region" is not recomputed when a sibling of
487d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // SurfaceView changes visibility (unless it involves GONE). It's
488d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // been broken since 1.0. Call requestLayout to work around it.
489d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            mCameraAppView.requestLayout();
49047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppView.startAnimation(mCameraAppViewFadeIn);
49178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        } else {
49247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppView.startAnimation(mCameraAppViewFadeOut);
493a6b966047b6215b02c502a3f143106070abf6009Angus Kong        }
494a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
495a6b966047b6215b02c502a3f143106070abf6009Angus Kong
4968e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li    protected void onFullScreenChanged(boolean full) {
49778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mShowCameraAppView == full) return;
49878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mShowCameraAppView = full;
49978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mPaused || isFinishing()) return;
50078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        updateCameraAppView();
501b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
502b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        // If we received DELETE_PICTURE broadcasts while the Camera UI is
503b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        // hidden, we update the thumbnail now.
504b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        if (full && mUpdateThumbnailDelayed) {
505b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            getLastThumbnailUncached();
506b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang            mUpdateThumbnailDelayed = false;
507b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        }
508a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
509a6b966047b6215b02c502a3f143106070abf6009Angus Kong
510a6b966047b6215b02c502a3f143106070abf6009Angus Kong    @Override
511a6b966047b6215b02c502a3f143106070abf6009Angus Kong    public GalleryActionBar getGalleryActionBar() {
512a6b966047b6215b02c502a3f143106070abf6009Angus Kong        return mActionBar;
513a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
5148a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li
51578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    // Preview frame layout has changed.
5168a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li    @Override
517525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong    public void onLayoutChange(View v, int left, int top, int right, int bottom) {
51878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mAppBridge == null) return;
51978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
52040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int width = right - left;
52140d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int height = bottom - top;
522c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        if (ApiHelper.HAS_SURFACE_TEXTURE) {
523c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            CameraScreenNail screenNail = (CameraScreenNail) mCameraScreenNail;
524c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            if (Util.getDisplayRotation(this) % 180 == 0) {
525c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                screenNail.setPreviewFrameLayoutSize(width, height);
526c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            } else {
527c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                // Swap the width and height. Camera screen nail draw() is based on
528c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                // natural orientation, not the view system orientation.
529c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                screenNail.setPreviewFrameLayoutSize(height, width);
530c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            }
53140d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        }
53276507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li
53378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // Find out the coordinates of the preview frame relative to GL
5348a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        // root view.
5358a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        View root = (View) getGLRoot();
5368a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        int[] rootLocation = new int[2];
5378a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        int[] viewLocation = new int[2];
5388a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        root.getLocationInWindow(rootLocation);
5398a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li        v.getLocationInWindow(viewLocation);
54078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
54178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        int l = viewLocation[0] - rootLocation[0];
54278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        int t = viewLocation[1] - rootLocation[1];
54340d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int r = l + width;
54440d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int b = t + height;
545f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang        Rect frame = new Rect(l, t, r, b);
546f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang        Log.d(TAG, "set CameraRelativeFrame as " + frame);
547f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang        mAppBridge.setCameraRelativeFrame(frame);
5488a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li    }
549bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
550bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    protected void setSingleTapUpListener(View singleTapArea) {
551bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        mSingleTapArea = singleTapArea;
552bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
553bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
55478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    private boolean onSingleTapUp(int x, int y) {
55517de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li        // Ignore if listener is null or the camera control is invisible.
55617de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li        if (mSingleTapArea == null || !mShowCameraAppView) return false;
557bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
558bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        int[] relativeLocation = Util.getRelativeLocation((View) getGLRoot(),
559bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li                mSingleTapArea);
560bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        x -= relativeLocation[0];
561bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        y -= relativeLocation[1];
562bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        if (x >= 0 && x < mSingleTapArea.getWidth() && y >= 0
563bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li                && y < mSingleTapArea.getHeight()) {
564bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li            onSingleTapUp(mSingleTapArea, x, y);
565bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li            return true;
566bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        }
567bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        return false;
568bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
569bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
570bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    protected void onSingleTapUp(View view, int x, int y) {
571bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
57278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
573d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang    protected void setSwipingEnabled(boolean enabled) {
574d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        mAppBridge.setSwipingEnabled(enabled);
57578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    }
57678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
577a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang    protected void notifyScreenNailChanged() {
578a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        mAppBridge.notifyScreenNailChanged();
579a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang    }
580a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang
581a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    protected void onPreviewTextureCopied() {
582a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    }
58378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
58478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //////////////////////////////////////////////////////////////////////////
58578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //  The is the communication interface between the Camera Application and
58678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //  the Gallery PhotoPage.
58778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //////////////////////////////////////////////////////////////////////////
58878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
589a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    class MyAppBridge extends AppBridge implements CameraScreenNail.Listener {
590dac1bb32531f7f4d49622bd38c82dde9333c38acAhbong Chang        @SuppressWarnings("hiding")
591c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        private ScreenNail mCameraScreenNail;
59278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        private Server mServer;
59378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
59478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
59578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public ScreenNail attachScreenNail() {
596a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            if (mCameraScreenNail == null) {
597c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                if (ApiHelper.HAS_SURFACE_TEXTURE) {
598c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                    mCameraScreenNail = new CameraScreenNail(this);
599c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                } else {
600195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                    Bitmap b = BitmapFactory.decodeResource(getResources(),
601195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                            R.drawable.wallpaper_picker_preview);
602195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                    mCameraScreenNail = new StaticBitmapScreenNail(b);
603c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                }
604a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            }
60578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return mCameraScreenNail;
60678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
60778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
60878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
60978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void detachScreenNail() {
61078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mCameraScreenNail = null;
61178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
61278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
613c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        public ScreenNail getCameraScreenNail() {
61478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return mCameraScreenNail;
61578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
61678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
61778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // Return true if the tap is consumed.
61878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
61978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public boolean onSingleTapUp(int x, int y) {
62078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return ActivityBase.this.onSingleTapUp(x, y);
62178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
62278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
62378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // This is used to notify that the screen nail will be drawn in full screen
62478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // or not in next draw() call.
62578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
62678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void onFullScreenChanged(boolean full) {
62778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            ActivityBase.this.onFullScreenChanged(full);
62878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
62978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
63078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
63178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void requestRender() {
63278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            getGLRoot().requestRender();
63378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
63478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
63578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
636a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        public void onPreviewTextureCopied() {
637a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li            ActivityBase.this.onPreviewTextureCopied();
638a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        }
639a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li
640a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        @Override
64178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void setServer(Server s) {
64278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mServer = s;
64378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
64478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
64505e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        @Override
64605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        public boolean isPanorama() {
64705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong            return ActivityBase.this.isPanoramaActivity();
64805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        }
64905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong
650a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        @Override
651a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        public boolean isStaticCamera() {
652a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li            return !ApiHelper.HAS_SURFACE_TEXTURE;
653a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        }
654a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li
655f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang        private void setCameraRelativeFrame(Rect frame) {
656f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            if (mServer != null) mServer.setCameraRelativeFrame(frame);
65778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
65878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
65978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        private void switchWithCaptureAnimation(int offset) {
66078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            if (mServer != null) mServer.switchWithCaptureAnimation(offset);
66178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
662d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang
663d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        private void setSwipingEnabled(boolean enabled) {
664d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang            if (mServer != null) mServer.setSwipingEnabled(enabled);
665d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        }
666a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang
667a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        private void notifyScreenNailChanged() {
668a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            if (mServer != null) mServer.notifyScreenNailChanged();
669a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        }
67078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    }
6714d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang}
672