ActivityBase.java revision ed19156e705efb982b351653a3ea9b15f5a08df7
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;
2888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Liimport android.net.Uri;
29c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.os.AsyncTask;
308608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Changimport android.os.Bundle;
31844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Handler;
32844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Message;
33b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.support.v4.content.LocalBroadcastManager;
347d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log;
354c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent;
36c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View;
37a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window;
38892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager;
39525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.AlphaAnimation;
40525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.Animation;
41a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport android.view.animation.DecelerateInterpolator;
42892781804513066b68b4a2fa6f846e862dac252aOwen Lin
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;
5178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.ui.ScreenNail;
52a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils;
534d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang
54aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File;
55aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li
5677c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/**
57ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li * Superclass of camera activity.
5877c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */
59525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongpublic abstract class ActivityBase extends AbstractGalleryActivity
60525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong        implements LayoutChangeNotifier.Listener {
61a6b966047b6215b02c502a3f143106070abf6009Angus Kong
627d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    private static final String TAG = "ActivityBase";
63c38faeb66a3f2cc96e4c5e951228d9b01e12edb3Chih-Chung Chang    private static final int CAMERA_APP_VIEW_TOGGLE_TIME = 100;  // milliseconds
6488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
6588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
6653b11253fde509b01851ba022d9178c7c6f13ddeWu-cheng Li    public static final String ACTION_IMAGE_CAPTURE_SECURE =
67ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            "android.media.action.IMAGE_CAPTURE_SECURE";
6888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // The intent extra for camera from secure lock screen. True if the gallery
6988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // should only show newly captured pictures. sSecureAlbumId does not
7088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // increment. This is used when switching between camera, camcorder, and
7188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // panorama. If the extra is not set, it is in the normal camera mode.
7288e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    public static final String SECURE_CAMERA_EXTRA = "secure_camera";
7347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
745df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    private int mResultCodeForTesting;
755df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    private Intent mResultDataForTesting;
764edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    private OnScreenHint mStorageHint;
77bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    private View mSingleTapArea;
78a6b966047b6215b02c502a3f143106070abf6009Angus Kong
79475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected boolean mOpenCameraFail;
80475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected boolean mCameraDisabled;
81475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected CameraManager.CameraProxy mCameraDevice;
82296d27772b9543d55820e1d24d900fea959f1b7aPin Ting    protected Parameters mParameters;
835c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    // The activity is paused. The classes that extend this class should set
845c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    // mPaused the first thing in onResume/onPause.
855c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li    protected boolean mPaused;
86a6b966047b6215b02c502a3f143106070abf6009Angus Kong    protected GalleryActionBar mActionBar;
87475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
88475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    // multiple cameras support
89475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected int mNumberOfCameras;
90475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected int mCameraId;
91d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // The activity is going to switch to the specified camera id. This is
92d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // needed because texture copy is done in GL thread. -1 means camera is not
93d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    // switching.
94d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li    protected int mPendingSwitchCameraId = -1;
95475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
9678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    protected MyAppBridge mAppBridge;
97c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li    protected ScreenNail mCameraScreenNail; // This shows camera preview.
98a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // The view containing only camera related widgets like control panel,
99a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // indicator bar, focus indicator and etc.
100a6b966047b6215b02c502a3f143106070abf6009Angus Kong    protected View mCameraAppView;
1011cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li    protected boolean mShowCameraAppView = true;
10247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private Animation mCameraAppViewFadeIn;
10347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private Animation mCameraAppViewFadeOut;
10488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // Secure album id. This should be incremented every time the camera is
10588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // launched from the secure lock screen. The id should be the same when
10688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    // switching between camera, camcorder, and panorama.
10788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    protected static int sSecureAlbumId;
108ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li    // True if the camera is started from secure lock screen.
10988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    protected boolean mSecureCamera;
1107717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    private static boolean sFirstStartAfterScreenOn = true;
11147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
112844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
113844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private static final int UPDATE_STORAGE_HINT = 0;
114844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private final Handler mHandler = new Handler() {
115844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            @Override
116844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            public void handleMessage(Message msg) {
117844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                switch (msg.what) {
118844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    case UPDATE_STORAGE_HINT:
119844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                        updateStorageHint();
120844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                        return;
121844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                }
122844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            }
123844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    };
124844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
125844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
126844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        @Override
127844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        public void onReceive(Context context, Intent intent) {
128844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            String action = intent.getAction();
129844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            if (action.equals(Intent.ACTION_MEDIA_MOUNTED)
130844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_UNMOUNTED)
131844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_CHECKING)
132844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                    || action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
133844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                updateStorageSpaceAndHint();
134844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            }
135844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        }
136844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    };
137844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
138d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li    // close activity when screen turns off
139d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
140d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        @Override
141d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        public void onReceive(Context context, Intent intent) {
142d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li            finish();
143d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        }
144d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li    };
145d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li
1467717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    private static BroadcastReceiver sScreenOffReceiver;
1477717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    private static class ScreenOffReceiver extends BroadcastReceiver {
1487717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        @Override
1497717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        public void onReceive(Context context, Intent intent) {
1507717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li            sFirstStartAfterScreenOn = true;
1517717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        }
1527717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    }
1537717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li
1547717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    public static boolean isFirstStartAfterScreenOn() {
1557717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        return sFirstStartAfterScreenOn;
1567717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    }
1577717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li
1587717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    public static void resetFirstStartAfterScreenOn() {
1597717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        sFirstStartAfterScreenOn = false;
1607717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    }
1617717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li
162475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    protected class CameraOpenThread extends Thread {
163475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        @Override
164475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void run() {
165475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            try {
166475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId);
167296d27772b9543d55820e1d24d900fea959f1b7aPin Ting                mParameters = mCameraDevice.getParameters();
168475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            } catch (CameraHardwareException e) {
169475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mOpenCameraFail = true;
170475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            } catch (CameraDisabledException e) {
171475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                mCameraDisabled = true;
172475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            }
173475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
174475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
1755df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
1764d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    @Override
1778608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    public void onCreate(Bundle icicle) {
1786a4a72b643929701c5d7c8b68b91d762c7277c20Wu-cheng Li        super.disableToggleStatusBar();
179a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // Set a theme with action bar. It is not specified in manifest because
180a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // we want to hide it by default. setTheme must happen before
181a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // setContentView.
182a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        //
183a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // This must be set before we call super.onCreate(), where the window's
184a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        // background is removed.
185a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        setTheme(R.style.Theme_Gallery);
186a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
187ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        if (ApiHelper.HAS_ACTION_BAR) {
188ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang            requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
189ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        } else {
190ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang            requestWindowFeature(Window.FEATURE_NO_TITLE);
191ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang        }
192a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin
19388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        // Check if this is in the secure camera mode.
19488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        Intent intent = getIntent();
195ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        String action = intent.getAction();
196ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) {
19788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            mSecureCamera = true;
19888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            // Use a new album when this is started from the lock screen.
19988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            sSecureAlbumId++;
200ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        } else if (ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
201ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            mSecureCamera = true;
20288e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        } else {
20388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
20488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        }
205d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        if (mSecureCamera) {
2067717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
2077717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li            registerReceiver(mScreenOffReceiver, filter);
2087717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li            if (sScreenOffReceiver == null) {
2097717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li                sScreenOffReceiver = new ScreenOffReceiver();
2107717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li                getApplicationContext().registerReceiver(sScreenOffReceiver, filter);
2117717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li            }
212d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        }
2138608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang        super.onCreate(icicle);
2148608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    }
2158608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang
21605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong    public boolean isPanoramaActivity() {
21705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        return false;
21805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong    }
21905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong
2208608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang    @Override
221b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    protected void onResume() {
222b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang        super.onResume();
223844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
224844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        installIntentFilter();
225844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        if(updateStorageHintOnResume()) {
226844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            updateStorageSpace();
227844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu            mHandler.sendEmptyMessageDelayed(UPDATE_STORAGE_HINT, 200);
228844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        }
229b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    }
230b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang
231b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang    @Override
2327d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    protected void onPause() {
2335c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li        super.onPause();
234c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
2354edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (mStorageHint != null) {
2364edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.cancel();
2374edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint = null;
2384edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
239844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
240844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        unregisterReceiver(mReceiver);
2417d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    }
2427d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller
2437d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller    @Override
24472fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    public void setContentView(int layoutResID) {
24572fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        super.setContentView(layoutResID);
24672fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        // getActionBar() should be after setContentView
24772fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        mActionBar = new GalleryActionBar(this);
24872fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li        mActionBar.hide();
24972fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    }
25072fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li
25172fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li    @Override
2524d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    public boolean onSearchRequested() {
2534d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang        return false;
2544d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang    }
2557673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li
2567673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    @Override
2577673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    public boolean onKeyDown(int keyCode, KeyEvent event) {
2587673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        // Prevent software keyboard or voice search from showing up.
2597673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        if (keyCode == KeyEvent.KEYCODE_SEARCH
2607673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li                || keyCode == KeyEvent.KEYCODE_MENU) {
2617673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li            if (event.isLongPress()) return true;
2627673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        }
2630703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) {
2640703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu            return true;
2650703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        }
2667673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li
2677673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li        return super.onKeyDown(keyCode, event);
2687673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li    }
2695df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2700703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    @Override
2710703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    public boolean onKeyUp(int keyCode, KeyEvent event) {
2720703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) {
2730703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu            return true;
2740703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        }
2750703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu        return super.onKeyUp(keyCode, event);
2760703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu    }
2770703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu
2785df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    protected void setResultEx(int resultCode) {
2795df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultCodeForTesting = resultCode;
2805df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        setResult(resultCode);
2815df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2825df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2835df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    protected void setResultEx(int resultCode, Intent data) {
2845df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultCodeForTesting = resultCode;
2855df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        mResultDataForTesting = data;
2865df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        setResult(resultCode, data);
2875df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2885df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2895df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    public int getResultCode() {
2905df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        return mResultCodeForTesting;
2915df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2925df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li
2935df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    public Intent getResultData() {
2945df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li        return mResultDataForTesting;
2955df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li    }
2965f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang
2975f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    @Override
2985f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    protected void onDestroy() {
2995f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang        PopupManager.removeInstance(this);
300d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li        if (mSecureCamera) unregisterReceiver(mScreenOffReceiver);
3015f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang        super.onDestroy();
3025f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang    }
3037d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller
304844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void installIntentFilter() {
305844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        // install an intent filter to receive SD card related events.
306844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        IntentFilter intentFilter =
307844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu                new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
308844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
309844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
310844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING);
311844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        intentFilter.addDataScheme("file");
312844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        registerReceiver(mReceiver, intentFilter);
313844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
314844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
315844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageSpace() {
316844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        mStorageSpace = Storage.getAvailableSpace();
317844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
318844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
319844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected long getStorageSpace() {
320844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        return mStorageSpace;
321844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
322844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
323844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageSpaceAndHint() {
324844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageSpace();
325844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageHint(mStorageSpace);
326844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
327844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
328844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected void updateStorageHint() {
329844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        updateStorageHint(mStorageSpace);
330844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
331844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
332844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    protected boolean updateStorageHintOnResume() {
333844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        return true;
334844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu    }
335844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu
3364edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    protected void updateStorageHint(long storageSpace) {
3374edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        String message = null;
3384edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (storageSpace == Storage.UNAVAILABLE) {
3394edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.no_storage);
3404edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (storageSpace == Storage.PREPARING) {
3414edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.preparing_sd);
3424edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
3434edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.access_sd_fail);
344844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
3454edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            message = getString(R.string.spaceIsLow_content);
3464edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
3474edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong
3484edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        if (message != null) {
3494edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            if (mStorageHint == null) {
3504edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong                mStorageHint = OnScreenHint.makeText(this, message);
3514edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            } else {
3524edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong                mStorageHint.setText(message);
3534edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            }
3544edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.show();
3554edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        } else if (mStorageHint != null) {
3564edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint.cancel();
3574edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong            mStorageHint = null;
3584edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong        }
3594edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong    }
360c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li
3616899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting    protected void gotoGallery() {
362252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting        // Move the next picture with capture animation. "1" means next.
363252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting        mAppBridge.switchWithCaptureAnimation(1);
3646899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting    }
3656899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting
366a6b966047b6215b02c502a3f143106070abf6009Angus Kong    // Call this after setContentView.
367e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount    public ScreenNail createCameraScreenNail(boolean getPictures) {
368a6b966047b6215b02c502a3f143106070abf6009Angus Kong        mCameraAppView = findViewById(R.id.camera_app_root);
369a6b966047b6215b02c502a3f143106070abf6009Angus Kong        Bundle data = new Bundle();
37088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        String path;
371ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        if (getPictures) {
372ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            if (mSecureCamera) {
373ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li                path = "/secure/all/" + sSecureAlbumId;
374ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            } else {
375ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li                path = "/local/all/" + MediaSetUtils.CAMERA_BUCKET_ID;
376ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            }
37788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        } else {
378ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            path = "/local/all/0"; // Use 0 so gallery does not show anything.
37988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        }
380a6b966047b6215b02c502a3f143106070abf6009Angus Kong        data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path);
381a6b966047b6215b02c502a3f143106070abf6009Angus Kong        data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path);
382ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        data.putBoolean(PhotoPage.KEY_SHOW_WHEN_LOCKED, mSecureCamera);
383a6b966047b6215b02c502a3f143106070abf6009Angus Kong
38478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // Send an AppBridge to gallery to enable the camera preview.
3859a4b58dbf402cf0565e718803d2b18d9c0c7b9dcGeorge Mount        if (mAppBridge != null) {
3869a4b58dbf402cf0565e718803d2b18d9c0c7b9dcGeorge Mount            mCameraScreenNail.recycle();
3879a4b58dbf402cf0565e718803d2b18d9c0c7b9dcGeorge Mount        }
38878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mAppBridge = new MyAppBridge();
38978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge);
3908e887b3911f3c182011c20d709832755d96a5959Doris Liu        if (getStateManager().getStateCount() == 0) {
3918e887b3911f3c182011c20d709832755d96a5959Doris Liu            getStateManager().startState(PhotoPage.class, data);
3928e887b3911f3c182011c20d709832755d96a5959Doris Liu        } else {
3938e887b3911f3c182011c20d709832755d96a5959Doris Liu            getStateManager().switchState(getStateManager().getTopState(),
3948e887b3911f3c182011c20d709832755d96a5959Doris Liu                    PhotoPage.class, data);
3958e887b3911f3c182011c20d709832755d96a5959Doris Liu        }
39678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mCameraScreenNail = mAppBridge.getCameraScreenNail();
397e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount        return mCameraScreenNail;
398a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
399a6b966047b6215b02c502a3f143106070abf6009Angus Kong
400d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // Call this after setContentView.
401e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount    protected ScreenNail reuseCameraScreenNail(boolean getPictures) {
402d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCameraAppView = findViewById(R.id.camera_app_root);
403d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        Bundle data = new Bundle();
404d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        String path;
405ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        if (getPictures) {
406ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            if (mSecureCamera) {
407ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li                path = "/secure/all/" + sSecureAlbumId;
408ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            } else {
409ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li                path = "/local/all/" + MediaSetUtils.CAMERA_BUCKET_ID;
410ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            }
411d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        } else {
412ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li            path = "/local/all/0"; // Use 0 so gallery does not show anything.
413d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
414d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path);
415d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path);
416ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li        data.putBoolean(PhotoPage.KEY_SHOW_WHEN_LOCKED, mSecureCamera);
417d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
418d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        // Send an AppBridge to gallery to enable the camera preview.
419d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        if (mAppBridge == null) {
420d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            mAppBridge = new MyAppBridge();
421d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
422d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge);
423d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        if (getStateManager().getStateCount() == 0) {
424d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            getStateManager().startState(PhotoPage.class, data);
425d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
426d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCameraScreenNail = mAppBridge.getCameraScreenNail();
427e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount        return mCameraScreenNail;
428d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
429d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
43047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang    private class HideCameraAppView implements Animation.AnimationListener {
4311cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li        @Override
43247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationEnd(Animation animation) {
433f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            // We cannot set this as GONE because we want to receive the
434f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            // onLayoutChange() callback even when we are invisible.
435f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            mCameraAppView.setVisibility(View.INVISIBLE);
4361cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li        }
43747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
43847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        @Override
43947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationRepeat(Animation animation) {
44047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
44147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
44247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        @Override
44347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        public void onAnimationStart(Animation animation) {
44447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
4451cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li    }
44678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
447c94cd4a5206b05541de0dc8a4821c64d0edba352Angus Kong    protected void updateCameraAppView() {
44847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        // Initialize the animation.
44947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        if (mCameraAppViewFadeIn == null) {
45047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn = new AlphaAnimation(0f, 1f);
45147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME);
45247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeIn.setInterpolator(new DecelerateInterpolator());
45347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
45447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut = new AlphaAnimation(1f, 0f);
45547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME);
45647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setInterpolator(new DecelerateInterpolator());
45747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppViewFadeOut.setAnimationListener(new HideCameraAppView());
45847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang        }
45947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang
46078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mShowCameraAppView) {
46178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mCameraAppView.setVisibility(View.VISIBLE);
462d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // The "transparent region" is not recomputed when a sibling of
463d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // SurfaceView changes visibility (unless it involves GONE). It's
464d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            // been broken since 1.0. Call requestLayout to work around it.
465d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li            mCameraAppView.requestLayout();
46647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppView.startAnimation(mCameraAppViewFadeIn);
46778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        } else {
46847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang            mCameraAppView.startAnimation(mCameraAppViewFadeOut);
469a6b966047b6215b02c502a3f143106070abf6009Angus Kong        }
470a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
471a6b966047b6215b02c502a3f143106070abf6009Angus Kong
4728e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li    protected void onFullScreenChanged(boolean full) {
47378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mShowCameraAppView == full) return;
47478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        mShowCameraAppView = full;
47578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mPaused || isFinishing()) return;
47678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        updateCameraAppView();
477a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
478a6b966047b6215b02c502a3f143106070abf6009Angus Kong
479a6b966047b6215b02c502a3f143106070abf6009Angus Kong    @Override
480a6b966047b6215b02c502a3f143106070abf6009Angus Kong    public GalleryActionBar getGalleryActionBar() {
481a6b966047b6215b02c502a3f143106070abf6009Angus Kong        return mActionBar;
482a6b966047b6215b02c502a3f143106070abf6009Angus Kong    }
4838a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li
48478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    // Preview frame layout has changed.
4858a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li    @Override
486525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong    public void onLayoutChange(View v, int left, int top, int right, int bottom) {
48778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        if (mAppBridge == null) return;
48878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
48940d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int width = right - left;
49040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        int height = bottom - top;
491c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        if (ApiHelper.HAS_SURFACE_TEXTURE) {
492c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            CameraScreenNail screenNail = (CameraScreenNail) mCameraScreenNail;
493c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            if (Util.getDisplayRotation(this) % 180 == 0) {
494c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                screenNail.setPreviewFrameLayoutSize(width, height);
495c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            } else {
496c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                // Swap the width and height. Camera screen nail draw() is based on
497c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                // natural orientation, not the view system orientation.
498c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                screenNail.setPreviewFrameLayoutSize(height, width);
499c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            }
50040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li        }
5018a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li    }
502bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
503bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    protected void setSingleTapUpListener(View singleTapArea) {
504bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        mSingleTapArea = singleTapArea;
505bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
506bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
50778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    private boolean onSingleTapUp(int x, int y) {
50817de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li        // Ignore if listener is null or the camera control is invisible.
50917de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li        if (mSingleTapArea == null || !mShowCameraAppView) return false;
510bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
511bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        int[] relativeLocation = Util.getRelativeLocation((View) getGLRoot(),
512bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li                mSingleTapArea);
513bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        x -= relativeLocation[0];
514bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        y -= relativeLocation[1];
515bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        if (x >= 0 && x < mSingleTapArea.getWidth() && y >= 0
516bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li                && y < mSingleTapArea.getHeight()) {
517bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li            onSingleTapUp(mSingleTapArea, x, y);
518bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li            return true;
519bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        }
520bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li        return false;
521bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
522bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li
523bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    protected void onSingleTapUp(View view, int x, int y) {
524bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li    }
52578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
526cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount    public void setSwipingEnabled(boolean enabled) {
527d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        mAppBridge.setSwipingEnabled(enabled);
52878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    }
52978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
530e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount    public void notifyScreenNailChanged() {
531a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        mAppBridge.notifyScreenNailChanged();
532a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang    }
533a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang
534a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    protected void onPreviewTextureCopied() {
535a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    }
53678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
537d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    protected void onCaptureTextureCopied() {
538d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    }
539d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount
54088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    protected void addSecureAlbumItemIfNeeded(boolean isVideo, Uri uri) {
54188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        if (mSecureCamera) {
54288e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            int id = Integer.parseInt(uri.getLastPathSegment());
54388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            mAppBridge.addSecureAlbumItem(isVideo, id);
54488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        }
54588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li    }
54688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li
5477717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    public boolean isSecureCamera() {
5487717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li        return mSecureCamera;
5497717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li    }
5507717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li
55178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //////////////////////////////////////////////////////////////////////////
55278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //  The is the communication interface between the Camera Application and
55378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //  the Gallery PhotoPage.
55478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    //////////////////////////////////////////////////////////////////////////
55578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
556a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li    class MyAppBridge extends AppBridge implements CameraScreenNail.Listener {
557dac1bb32531f7f4d49622bd38c82dde9333c38acAhbong Chang        @SuppressWarnings("hiding")
558c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        private ScreenNail mCameraScreenNail;
55978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        private Server mServer;
56078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
56178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
56278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public ScreenNail attachScreenNail() {
563a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            if (mCameraScreenNail == null) {
564c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                if (ApiHelper.HAS_SURFACE_TEXTURE) {
565c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                    mCameraScreenNail = new CameraScreenNail(this);
566c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                } else {
567195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                    Bitmap b = BitmapFactory.decodeResource(getResources(),
568195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                            R.drawable.wallpaper_picker_preview);
569195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li                    mCameraScreenNail = new StaticBitmapScreenNail(b);
570c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                }
571a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            }
57278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return mCameraScreenNail;
57378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
57478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
57578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
57678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void detachScreenNail() {
57778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mCameraScreenNail = null;
57878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
57978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
580c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        public ScreenNail getCameraScreenNail() {
58178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return mCameraScreenNail;
58278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
58378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
58478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // Return true if the tap is consumed.
58578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
58678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public boolean onSingleTapUp(int x, int y) {
58778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            return ActivityBase.this.onSingleTapUp(x, y);
58878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
58978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
59078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // This is used to notify that the screen nail will be drawn in full screen
59178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        // or not in next draw() call.
59278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
59378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void onFullScreenChanged(boolean full) {
59478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            ActivityBase.this.onFullScreenChanged(full);
59578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
59678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
59778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
59878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void requestRender() {
59978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            getGLRoot().requestRender();
60078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
60178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
60278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        @Override
603a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        public void onPreviewTextureCopied() {
604a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li            ActivityBase.this.onPreviewTextureCopied();
605a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        }
606a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li
607a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li        @Override
608d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount        public void onCaptureTextureCopied() {
609d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount            ActivityBase.this.onCaptureTextureCopied();
610d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount        }
611d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount
612d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount        @Override
61378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        public void setServer(Server s) {
61478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            mServer = s;
61578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
61678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
61705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        @Override
61805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        public boolean isPanorama() {
61905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong            return ActivityBase.this.isPanoramaActivity();
62005e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong        }
62105e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong
622a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        @Override
623a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        public boolean isStaticCamera() {
624a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li            return !ApiHelper.HAS_SURFACE_TEXTURE;
625a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li        }
626a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li
62788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        public void addSecureAlbumItem(boolean isVideo, int id) {
62888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li            if (mServer != null) mServer.addSecureAlbumItem(isVideo, id);
62988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li        }
63088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li
631f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang        private void setCameraRelativeFrame(Rect frame) {
632f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang            if (mServer != null) mServer.setCameraRelativeFrame(frame);
63378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
63478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang
63578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        private void switchWithCaptureAnimation(int offset) {
63678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang            if (mServer != null) mServer.switchWithCaptureAnimation(offset);
63778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang        }
638d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang
639d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        private void setSwipingEnabled(boolean enabled) {
640d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang            if (mServer != null) mServer.setSwipingEnabled(enabled);
641d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang        }
642a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang
643a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        private void notifyScreenNailChanged() {
644a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang            if (mServer != null) mServer.notifyScreenNailChanged();
645a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang        }
64678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang    }
6474d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang}
648