PhotoUI.java revision f55f3c461c5a6ae6b61fa75562ca01683aa93f9a
1d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb/*
26432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu * Copyright (C) 2012 The Android Open Source Project
3d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb *
4d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * you may not use this file except in compliance with the License.
6d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * You may obtain a copy of the License at
7d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb *
8d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb *
10d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * Unless required by applicable law or agreed to in writing, software
11d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * See the License for the specific language governing permissions and
14d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * limitations under the License.
15d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb */
16d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
17d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
18d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbpackage com.android.camera;
19d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
206a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liuimport android.app.AlertDialog;
216a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liuimport android.content.DialogInterface;
2237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.graphics.Bitmap;
23c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.graphics.Color;
246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.Matrix;
2536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liuimport android.graphics.RectF;
266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.SurfaceTexture;
27c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.graphics.drawable.ColorDrawable;
28d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.hardware.Camera;
29d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.hardware.Camera.Face;
3037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.os.AsyncTask;
31d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.util.Log;
32d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.Gravity;
336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.TextureView;
34d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.View;
35d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.View.OnClickListener;
36d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.View.OnLayoutChangeListener;
37d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.ViewGroup;
38d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.ViewStub;
39d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.widget.FrameLayout.LayoutParams;
4037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.widget.ImageView;
41c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.widget.PopupWindow;
42d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.widget.Toast;
43d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
44d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.CameraPreference.OnPreferenceChangedListener;
45d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.FocusOverlayManager.FocusUI;
4620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.app.CameraManager;
47d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.AbstractSettingPopup;
486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.CameraControls;
499e76552adff6ecf8b8e4070ecd61699cb6d18269Angus Kongimport com.android.camera.ui.CameraRootView;
50d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.CountDownView;
51d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
52d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.FaceView;
53d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.FocusIndicator;
54d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.PieRenderer;
55d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.PieRenderer.PieListener;
56d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.RenderOverlay;
57d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.ZoomRenderer;
58b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
598e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
60b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong
61b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport java.util.List;
62d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
63d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbpublic class PhotoUI implements PieListener,
64d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    PreviewGestures.SingleTapListener,
656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    FocusUI, TextureView.SurfaceTextureListener,
6621c21a62aaed42cb0d4c2c91a735f08e40f8cd07Erin Dahlgren    CameraRootView.MyDisplayListener,
679e76552adff6ecf8b8e4070ecd61699cb6d18269Angus Kong    CameraManager.CameraFaceDetectionCallback {
68d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
69d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private static final String TAG = "CAM_UI";
7037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private static final int DOWN_SAMPLE_FACTOR = 4;
7137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private final AnimationManager mAnimationManager;
72d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private CameraActivity mActivity;
73d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private PhotoController mController;
74d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
75d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private View mRootView;
76dcccc510652b835fdbd39310a07849af8203052aAngus Kong    private SurfaceTexture mSurfaceTexture;
77d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
78c3679c0961521165499380c77344acc69072b2acDoris Liu    private PopupWindow mPopup;
79d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private ShutterButton mShutterButton;
80d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private CountDownView mCountDownView;
81d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
82d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private FaceView mFaceView;
83d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private RenderOverlay mRenderOverlay;
84d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private View mReviewCancelButton;
85d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private View mReviewDoneButton;
86d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private View mReviewRetakeButton;
8736e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    private ImageView mReviewImage;
8836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    private DecodeImageForReview mDecodeTaskForReview = null;
89d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
90d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private View mMenuButton;
91d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private PhotoMenu mMenu;
926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraControls mCameraControls;
936a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu    private AlertDialog mLocationDialog;
94d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // Small indicators which show the camera settings in the viewfinder.
96c7965e2bc8f69006de09b4be6fad61c4d2313e07Sascha Haeberling    private OnScreenIndicators mOnScreenIndicators;
97d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
98d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private PieRenderer mPieRenderer;
99d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private ZoomRenderer mZoomRenderer;
100d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private Toast mNotSelectableToast;
101d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
102d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private int mZoomMax;
103d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private List<Integer> mZoomRatios;
104d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
105d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private int mPreviewWidth = 0;
106d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private int mPreviewHeight = 0;
1076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mSurfaceTextureUncroppedWidth;
1086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mSurfaceTextureUncroppedHeight;
1096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private ImageView mPreviewThumb;
111c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu    private View mFlashOverlay;
112d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
1136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private SurfaceTextureSizeChangedListener mSurfaceTextureSizeListener;
1146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private TextureView mTextureView;
1156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Matrix mMatrix = null;
1166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mAspectRatio = 4f / 3f;
1173a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    private View mPreviewCover;
118b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren    private final Object mSurfaceTextureLock = new Object();
1196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public interface SurfaceTextureSizeChangedListener {
1216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight);
1226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
1236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
124d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
125d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        @Override
126d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onLayoutChange(View v, int left, int top, int right,
127d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
128d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            int width = right - left;
129d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            int height = bottom - top;
1306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mPreviewWidth != width || mPreviewHeight != height) {
1316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mPreviewWidth = width;
1326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mPreviewHeight = height;
13313ca71ebdbb2eb9c492da16262311b1290474f7dDoris Liu                setTransformMatrix(width, height);
134d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
135d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
136d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    };
137d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
13836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    private class DecodeTask extends AsyncTask<Void, Void, Bitmap> {
13937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        private final byte [] mData;
140ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu        private int mOrientation;
14129da2db13029f8896018836693139a05d1139362Doris Liu        private boolean mMirror;
142c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu
14329da2db13029f8896018836693139a05d1139362Doris Liu        public DecodeTask(byte[] data, int orientation, boolean mirror) {
14437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mData = data;
145ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu            mOrientation = orientation;
14629da2db13029f8896018836693139a05d1139362Doris Liu            mMirror = mirror;
147c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu        }
148c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu
149c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu        @Override
15036e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        protected Bitmap doInBackground(Void... params) {
15137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            // Decode image in background.
152ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu            Bitmap bitmap = CameraUtil.downSample(mData, DOWN_SAMPLE_FACTOR);
15329da2db13029f8896018836693139a05d1139362Doris Liu            if (mOrientation != 0 || mMirror) {
154ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu                Matrix m = new Matrix();
15529da2db13029f8896018836693139a05d1139362Doris Liu                if (mMirror) {
15629da2db13029f8896018836693139a05d1139362Doris Liu                    // Flip horizontally
15729da2db13029f8896018836693139a05d1139362Doris Liu                    m.setScale(-1f, 1f);
15829da2db13029f8896018836693139a05d1139362Doris Liu                }
159cec75e408a2d451b90bac5f06e10906ffcafff33Andy Huibers                m.preRotate(mOrientation);
160ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu                return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m,
161ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu                        false);
162ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu            }
163ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu            return bitmap;
16437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
165c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu
166c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu        @Override
16737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        protected void onPostExecute(Bitmap bitmap) {
16837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mPreviewThumb.setImageBitmap(bitmap);
16937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mAnimationManager.startCaptureAnimation(mPreviewThumb);
17037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
17137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
172c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu
17336e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    private class DecodeImageForReview extends DecodeTask {
17436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        public DecodeImageForReview(byte[] data, int orientation, boolean mirror) {
17536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            super(data, orientation, mirror);
17636e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        }
17736e56fba281292255a01ee00b4bee067fa09ab59Doris Liu
17836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        @Override
17936e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        protected void onPostExecute(Bitmap bitmap) {
18036e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            if (isCancelled()) {
18136e56fba281292255a01ee00b4bee067fa09ab59Doris Liu                return;
18236e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            }
18336e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            mReviewImage.setImageBitmap(bitmap);
18436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            mReviewImage.setVisibility(View.VISIBLE);
18536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            mDecodeTaskForReview = null;
18636e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        }
18736e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    }
18836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu
189d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public PhotoUI(CameraActivity activity, PhotoController controller, View parent) {
190d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mActivity = activity;
191d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mController = controller;
192d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mRootView = parent;
193d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
194f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu        ViewGroup moduleRoot = (ViewGroup) mRootView.findViewById(R.id.module_layout);
195d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mActivity.getLayoutInflater().inflate(R.layout.photo_module,
196f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu                 (ViewGroup) moduleRoot, true);
197d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);
198c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu        mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);
1993a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover = mRootView.findViewById(R.id.preview_cover);
2006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // display the view
2016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
2026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setSurfaceTextureListener(this);
2036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.addOnLayoutChangeListener(mLayoutListener);
204d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        initIndicators();
205d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
206f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu        mSurfaceTexture = mTextureView.getSurfaceTexture();
207f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu        if (mSurfaceTexture != null) {
208f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu            setTransformMatrix(mTextureView.getWidth(), mTextureView.getHeight());
209f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu            mPreviewCover.setVisibility(View.GONE);
210f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu        }
2116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
2126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton = mRootView.findViewById(R.id.menu);
213638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling        ViewStub faceViewStub = (ViewStub) mRootView
214638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling                .findViewById(R.id.face_view_stub);
215638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling        if (faceViewStub != null) {
216638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling            faceViewStub.inflate();
217638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling            mFaceView = (FaceView) mRootView.findViewById(R.id.face_view);
218638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling            setSurfaceTextureSizeChangedListener(mFaceView);
2196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
22137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager = new AnimationManager();
2226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {
2256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceTextureSizeListener = listener;
2266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
228d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu    public void updatePreviewAspectRatio(float aspectRatio) {
229d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        if (aspectRatio <= 0) {
230d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            Log.e(TAG, "Invalid aspect ratio: " + aspectRatio);
231d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            return;
232d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        }
233d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        if (aspectRatio < 1f) {
234d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            aspectRatio = 1f / aspectRatio;
235d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        }
236d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu
237d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        if (mAspectRatio != aspectRatio) {
238d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            mAspectRatio = aspectRatio;
239d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            // Update transform matrix with the new aspect ratio.
240d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            if (mPreviewWidth != 0 && mPreviewHeight != 0) {
241d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu                setTransformMatrix(mPreviewWidth, mPreviewHeight);
242d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu            }
243d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu        }
244d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu    }
245d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu
2466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setTransformMatrix(int width, int height) {
2476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMatrix = mTextureView.getTransform(mMatrix);
2486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        float scaleX = 1f, scaleY = 1f;
2496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        float scaledTextureWidth, scaledTextureHeight;
2506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (width > height) {
2516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureWidth = Math.max(width,
2526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (height * mAspectRatio));
2536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureHeight = Math.max(height,
2546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int)(width / mAspectRatio));
2556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
2566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureWidth = Math.max(width,
2576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (height / mAspectRatio));
2586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureHeight = Math.max(height,
2596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (width * mAspectRatio));
2606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
2636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
2646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSurfaceTextureUncroppedWidth = scaledTextureWidth;
2656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSurfaceTextureUncroppedHeight = scaledTextureHeight;
2666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mSurfaceTextureSizeListener != null) {
2676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
2686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                        (int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight);
269d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
270d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
2716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        scaleX = scaledTextureWidth / width;
2726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        scaleY = scaledTextureHeight / height;
2736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2);
2746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setTransform(mMatrix);
27536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu
27636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        // Calculate the new preview rectangle.
27736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        RectF previewRect = new RectF(0, 0, width, height);
27836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        mMatrix.mapRect(previewRect);
27936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        mController.onPreviewRectChanged(CameraUtil.rectFToRect(previewRect));
2806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
282b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren    protected Object getSurfaceTextureLock() {
283b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren        return mSurfaceTextureLock;
284b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren    }
285b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren
286dcccc510652b835fdbd39310a07849af8203052aAngus Kong    @Override
2876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
288b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren        synchronized (mSurfaceTextureLock) {
289b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            Log.v(TAG, "SurfaceTexture ready.");
290b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            mSurfaceTexture = surface;
291b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            mController.onPreviewUIReady();
292b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            // Workaround for b/11168275, see b/10981460 for more details
293b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            if (mPreviewWidth != 0 && mPreviewHeight != 0) {
294b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren                // Re-apply transform matrix for new surface texture
295b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren                setTransformMatrix(mPreviewWidth, mPreviewHeight);
296b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            }
29718f20b9f460a8e329dd5af1e035d23931e7e1910Doris Liu        }
2986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
299d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
300dcccc510652b835fdbd39310a07849af8203052aAngus Kong    @Override
3016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
3026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Ignored, Camera does all the work for us
3036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
305dcccc510652b835fdbd39310a07849af8203052aAngus Kong    @Override
3066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
307b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren        synchronized (mSurfaceTextureLock) {
308b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            mSurfaceTexture = null;
309b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            mController.onPreviewUIDestroyed();
310b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            Log.w(TAG, "SurfaceTexture destroyed");
311b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren            return true;
312b09b53efcd179d55836014dcd054cff6f7d688d8Erin Dahlgren        }
3136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
3157b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui    @Override
3166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
317fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        // Make sure preview cover is hidden if preview data is available.
318fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        if (mPreviewCover.getVisibility() != View.GONE) {
319fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers            mPreviewCover.setVisibility(View.GONE);
320fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        }
321d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
322d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
323d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public View getRootView() {
324d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return mRootView;
325d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
326d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
327d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private void initIndicators() {
328eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        mOnScreenIndicators = new OnScreenIndicators(mActivity,
3296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mRootView.findViewById(R.id.on_screen_indicators));
330d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
331d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
332d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onCameraOpened(PreferenceGroup prefGroup, ComboPreferences prefs,
333d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            Camera.Parameters params, OnPreferenceChangedListener listener) {
334d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mPieRenderer == null) {
335d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mPieRenderer = new PieRenderer(mActivity);
336d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mPieRenderer.setPieListener(this);
337e3974bb4614d027e88ad915f70c4c05fb5ff76b1Michael Kolb            mRenderOverlay.addRenderer(mPieRenderer);
338d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
3396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
340d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mMenu == null) {
341d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mMenu = new PhotoMenu(mActivity, this, mPieRenderer);
342d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mMenu.setListener(listener);
343d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
344d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mMenu.initialize(prefGroup);
345d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
346d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mZoomRenderer == null) {
347d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mZoomRenderer = new ZoomRenderer(mActivity);
348e3974bb4614d027e88ad915f70c4c05fb5ff76b1Michael Kolb            mRenderOverlay.addRenderer(mZoomRenderer);
349d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
350f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu        mRenderOverlay.setGestures(null);
351d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
352d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        initializeZoom(params);
353eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        updateOnScreenIndicators(params, prefGroup, prefs);
354d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
355d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
35629da2db13029f8896018836693139a05d1139362Doris Liu    public void animateCapture(final byte[] jpegData, int orientation, boolean mirror) {
35737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        // Decode jpeg byte array and then animate the jpeg
35829da2db13029f8896018836693139a05d1139362Doris Liu        DecodeTask task = new DecodeTask(jpegData, orientation, mirror);
35937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        task.execute();
36037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
36137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3623bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    private void openMenu() {
3633bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb        if (mPieRenderer != null) {
3643bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            // If autofocus is not finished, cancel autofocus so that the
3653bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            // subsequent touch can be handled by PreviewGestures
3663bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            if (mController.getCameraState() == PhotoController.FOCUSING) {
3673bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb                    mController.cancelAutoFocus();
3683bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            }
3693bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            mPieRenderer.showInCenter();
3703bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb        }
3713bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    }
3723bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb
373d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void initializeControlByIntent() {
37437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPreviewThumb = (ImageView) mRootView.findViewById(R.id.preview_thumb);
37578a5b224eca3c702f4ecf8abd072779e32e26641Michael Kolb        mPreviewThumb.setOnClickListener(new OnClickListener() {
37678a5b224eca3c702f4ecf8abd072779e32e26641Michael Kolb            @Override
37778a5b224eca3c702f4ecf8abd072779e32e26641Michael Kolb            public void onClick(View v) {
378734598c39e6a9d809982dae2907dc7d10e0b0e9fAngus Kong                mActivity.gotoGallery();
37978a5b224eca3c702f4ecf8abd072779e32e26641Michael Kolb            }
38078a5b224eca3c702f4ecf8abd072779e32e26641Michael Kolb        });
3816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton = mRootView.findViewById(R.id.menu);
382d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mMenuButton.setOnClickListener(new OnClickListener() {
383d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            @Override
384d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            public void onClick(View v) {
3853bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb                openMenu();
386d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
387d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        });
388d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mController.isImageCaptureIntent()) {
3896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            ViewGroup cameraControls = (ViewGroup) mRootView.findViewById(R.id.camera_controls);
390d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mActivity.getLayoutInflater().inflate(R.layout.review_module_control, cameraControls);
391d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
3926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mReviewDoneButton = mRootView.findViewById(R.id.btn_done);
3936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel);
3946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mReviewRetakeButton = mRootView.findViewById(R.id.btn_retake);
39536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            mReviewImage = (ImageView) mRootView.findViewById(R.id.review_image);
396d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mReviewCancelButton.setVisibility(View.VISIBLE);
397d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
398d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mReviewDoneButton.setOnClickListener(new OnClickListener() {
399d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                @Override
400d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                public void onClick(View v) {
401d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                    mController.onCaptureDone();
402d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                }
403d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            });
404d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mReviewCancelButton.setOnClickListener(new OnClickListener() {
405d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                @Override
406d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                public void onClick(View v) {
407d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                    mController.onCaptureCancelled();
408d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                }
409d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            });
410d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
411d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mReviewRetakeButton.setOnClickListener(new OnClickListener() {
412d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                @Override
413d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                public void onClick(View v) {
414d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                    mController.onCaptureRetake();
415d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                }
416d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            });
417d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
418d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
419d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
4206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void hideUI() {
4216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.setVisibility(View.INVISIBLE);
4226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
4236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
4246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void showUI() {
4256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.setVisibility(View.VISIBLE);
4266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
4276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
4283044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    public boolean arePreviewControlsVisible() {
4293044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        return (mCameraControls.getVisibility() == View.VISIBLE);
4303044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    }
4313044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren
432d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    // called from onResume but only the first time
433d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public  void initializeFirstTime() {
434d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // Initialize shutter button.
435d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mShutterButton.setImageResource(R.drawable.btn_new_shutter);
436d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mShutterButton.setOnShutterButtonListener(mController);
437d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mShutterButton.setVisibility(View.VISIBLE);
438d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
439d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
440d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    // called from onResume every other time
441d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void initializeSecondTime(Camera.Parameters params) {
442d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        initializeZoom(params);
443d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mController.isImageCaptureIntent()) {
444d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            hidePostCaptureAlert();
445d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
446d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mMenu != null) {
447d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mMenu.reloadPreferences();
448d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
449d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
450d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
4516a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu    public void showLocationDialog() {
4526a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu        mLocationDialog = new AlertDialog.Builder(mActivity)
4536a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .setTitle(R.string.remember_location_title)
4546a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .setMessage(R.string.remember_location_prompt)
4556a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .setPositiveButton(R.string.remember_location_yes,
4566a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        new DialogInterface.OnClickListener() {
4576a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            @Override
4586a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            public void onClick(DialogInterface dialog, int arg1) {
4596a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                                mController.enableRecordingLocation(true);
4606a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                                mLocationDialog = null;
4616a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            }
4626a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        })
4636a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .setNegativeButton(R.string.remember_location_no,
4646a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        new DialogInterface.OnClickListener() {
4656a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            @Override
4666a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            public void onClick(DialogInterface dialog, int arg1) {
4676a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                                dialog.cancel();
4686a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                            }
4696a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        })
4706a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .setOnCancelListener(new DialogInterface.OnCancelListener() {
4716a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                    @Override
4726a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                    public void onCancel(DialogInterface dialog) {
4736a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        mController.enableRecordingLocation(false);
4746a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                        mLocationDialog = null;
4756a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                    }
4766a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                })
4776a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu                .show();
4786a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu    }
4796a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu
480d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void initializeZoom(Camera.Parameters params) {
481d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if ((params == null) || !params.isZoomSupported()
482d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                || (mZoomRenderer == null)) return;
483d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mZoomMax = params.getMaxZoom();
484d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mZoomRatios = params.getZoomRatios();
485d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // Currently we use immediate zoom for fast zooming to get better UX and
486d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // there is no plan to take advantage of the smooth zoom.
487d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mZoomRenderer != null) {
488d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mZoomRenderer.setZoomMax(mZoomMax);
489d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mZoomRenderer.setZoom(params.getZoom());
490d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mZoomRenderer.setZoomValue(mZoomRatios.get(params.getZoom()));
491d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener());
492d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
493d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
494d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
495d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void overrideSettings(final String ... keyvalues) {
496d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mMenu.overrideSettings(keyvalues);
497d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
498d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
499d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void updateOnScreenIndicators(Camera.Parameters params,
500eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb            PreferenceGroup group, ComboPreferences prefs) {
501d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (params == null) return;
502c7965e2bc8f69006de09b4be6fad61c4d2313e07Sascha Haeberling        mOnScreenIndicators.updateSceneOnScreenIndicator(params.getSceneMode());
503c7965e2bc8f69006de09b4be6fad61c4d2313e07Sascha Haeberling        mOnScreenIndicators.updateExposureOnScreenIndicator(params,
504d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                CameraSettings.readExposure(prefs));
505c7965e2bc8f69006de09b4be6fad61c4d2313e07Sascha Haeberling        mOnScreenIndicators.updateFlashOnScreenIndicator(params.getFlashMode());
506eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        int wbIndex = 2;
507eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        ListPreference pref = group.findPreference(CameraSettings.KEY_WHITE_BALANCE);
508eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        if (pref != null) {
509eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb            wbIndex = pref.getCurrentIndex();
510eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        }
511eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        mOnScreenIndicators.updateWBIndicator(wbIndex);
5128788079a51a90255dce330e56afcb6674deccbf7Michael Kolb        boolean location = RecordLocationPreference.get(
5138788079a51a90255dce330e56afcb6674deccbf7Michael Kolb                prefs, mActivity.getContentResolver());
514eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        mOnScreenIndicators.updateLocationIndicator(location);
515d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
516d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
517d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void setCameraState(int state) {
518d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
519d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
520c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu    public void animateFlash() {
52137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager.startFlashAnimation(mFlashOverlay);
522c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu    }
523c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu
5246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // forward from preview gestures to controller
5256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
5266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSingleTapUp(View view, int x, int y) {
5276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mController.onSingleTapUp(view, x, y);
528d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
529d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
530d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public boolean onBackPressed() {
531d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mPieRenderer != null && mPieRenderer.showsItems()) {
532d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mPieRenderer.hide();
533d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            return true;
534d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
535d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // In image capture mode, back button should:
536d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // 1) if there is any popup, dismiss them, 2) otherwise, get out of
537d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // image capture
538d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mController.isImageCaptureIntent()) {
539c3679c0961521165499380c77344acc69072b2acDoris Liu            mController.onCaptureCancelled();
540d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            return true;
541d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        } else if (!mController.isCameraIdle()) {
542d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            // ignore backs while we're taking a picture
543d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            return true;
544d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        } else {
545c3679c0961521165499380c77344acc69072b2acDoris Liu            return false;
546d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
547d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
548d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
5497b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui    public void onPreviewFocusChanged(boolean previewFocused) {
5507b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui        if (previewFocused) {
5516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            showUI();
5526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
5536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            hideUI();
5546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
555d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) {
5567b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui            mFaceView.setBlockDraw(!previewFocused);
557d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
558d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mRenderOverlay != null) {
559d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            // this can not happen in capture mode
5607b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui            mRenderOverlay.setVisibility(previewFocused ? View.VISIBLE : View.GONE);
561d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
562d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mPieRenderer != null) {
5637b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui            mPieRenderer.setBlockFocus(!previewFocused);
564d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
5657b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui        setShowMenu(previewFocused);
5667b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui        if (!previewFocused && mCountDownView != null) mCountDownView.cancelCountDown();
567d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
568d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
569d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void showPopup(AbstractSettingPopup popup) {
5706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        hideUI();
571d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
572c3679c0961521165499380c77344acc69072b2acDoris Liu        if (mPopup == null) {
573c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup = new PopupWindow(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
574c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
575c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.setOutsideTouchable(true);
576c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.setFocusable(true);
577c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
578c3679c0961521165499380c77344acc69072b2acDoris Liu                @Override
579c3679c0961521165499380c77344acc69072b2acDoris Liu                public void onDismiss() {
580c3679c0961521165499380c77344acc69072b2acDoris Liu                    mPopup = null;
581c3679c0961521165499380c77344acc69072b2acDoris Liu                    mMenu.popupDismissed();
582c3679c0961521165499380c77344acc69072b2acDoris Liu                    showUI();
5834ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling
5844ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling                    // Switch back into fullscreen/lights-out mode after popup
5854ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling                    // is dimissed.
5864ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling                    mActivity.setSystemBarsVisibility(false);
587c3679c0961521165499380c77344acc69072b2acDoris Liu                }
588c3679c0961521165499380c77344acc69072b2acDoris Liu            });
589c3679c0961521165499380c77344acc69072b2acDoris Liu        }
590c3679c0961521165499380c77344acc69072b2acDoris Liu        popup.setVisibility(View.VISIBLE);
591c3679c0961521165499380c77344acc69072b2acDoris Liu        mPopup.setContentView(popup);
592c3679c0961521165499380c77344acc69072b2acDoris Liu        mPopup.showAtLocation(mRootView, Gravity.CENTER, 0, 0);
593d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
594d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
595c3679c0961521165499380c77344acc69072b2acDoris Liu    public void dismissPopup() {
596c3679c0961521165499380c77344acc69072b2acDoris Liu        if (mPopup != null && mPopup.isShowing()) {
597c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.dismiss();
598d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
599d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
600d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
601d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onShowSwitcherPopup() {
602d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mPieRenderer != null && mPieRenderer.showsItems()) {
603d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mPieRenderer.hide();
604d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
605d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
606d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
607d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private void setShowMenu(boolean show) {
608d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mOnScreenIndicators != null) {
609d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
610d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
611d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mMenuButton != null) {
612d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE);
613d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
614d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
615d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
616d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public boolean collapseCameraControls() {
617d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // Remove all the popups/dialog boxes
618d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        boolean ret = false;
619d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mPopup != null) {
6207048972374474dfca142856583833d8168d3b1b6Michael Kolb            dismissPopup();
621d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            ret = true;
622d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
623b16bae90dbb99892c6b3209c13c53c44cb69deb4Michael Kolb        onShowSwitcherPopup();
624d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return ret;
625d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
626d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
62736e56fba281292255a01ee00b4bee067fa09ab59Doris Liu    protected void showCapturedImageForReview(byte[] jpegData, int orientation, boolean mirror) {
62836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        mDecodeTaskForReview = new DecodeImageForReview(jpegData, orientation, mirror);
62936e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        mDecodeTaskForReview.execute();
630d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mOnScreenIndicators.setVisibility(View.GONE);
631d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mMenuButton.setVisibility(View.GONE);
632b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeIn(mReviewDoneButton);
633d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mShutterButton.setVisibility(View.INVISIBLE);
634b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeIn(mReviewRetakeButton);
635d31cdfeb1035df8ba939e877031769f0df247aa6Doris Liu        pauseFaceDetection();
636d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
637d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
638d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    protected void hidePostCaptureAlert() {
63936e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        if (mDecodeTaskForReview != null) {
64036e56fba281292255a01ee00b4bee067fa09ab59Doris Liu            mDecodeTaskForReview.cancel(true);
64136e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        }
64236e56fba281292255a01ee00b4bee067fa09ab59Doris Liu        mReviewImage.setVisibility(View.GONE);
643d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mOnScreenIndicators.setVisibility(View.VISIBLE);
644d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mMenuButton.setVisibility(View.VISIBLE);
645b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeOut(mReviewDoneButton);
646d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mShutterButton.setVisibility(View.VISIBLE);
647b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeOut(mReviewRetakeButton);
648d31cdfeb1035df8ba939e877031769f0df247aa6Doris Liu        resumeFaceDetection();
649d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
650d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
651d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void setDisplayOrientation(int orientation) {
652d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) {
653d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mFaceView.setDisplayOrientation(orientation);
654d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
655d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
656d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
657d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    // shutter button handling
658d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
659d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public boolean isShutterPressed() {
660d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return mShutterButton.isPressed();
661d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
662d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
6638890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling    /**
6648890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling     * Enables or disables the shutter button.
6658890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling     */
6666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void enableShutter(boolean enabled) {
6676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mShutterButton != null) {
6686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mShutterButton.setEnabled(enabled);
6696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
671d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
6726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void pressShutterButton() {
6736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mShutterButton.isInTouchMode()) {
6746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mShutterButton.requestFocusFromTouch();
6756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
6766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mShutterButton.requestFocus();
6776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mShutterButton.setPressed(true);
6796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
680d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
681d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener {
682d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        @Override
683d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onZoomValueChanged(int index) {
684d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            int newZoom = mController.onZoomChanged(index);
685d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            if (mZoomRenderer != null) {
686d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom));
687d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
688d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
689d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
690d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        @Override
691d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onZoomStart() {
692d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            if (mPieRenderer != null) {
693d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mPieRenderer.setBlockFocus(true);
694d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
695d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
696d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
697d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        @Override
698d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onZoomEnd() {
699d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            if (mPieRenderer != null) {
700d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mPieRenderer.setBlockFocus(false);
701d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            }
702d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
703d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
704d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
705d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
706d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onPieOpened(int centerX, int centerY) {
7076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setSwipingEnabled(false);
708d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) {
709d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mFaceView.setBlockDraw(true);
710d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
711d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
712d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
713d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
714d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onPieClosed() {
7156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setSwipingEnabled(true);
716d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) {
717d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mFaceView.setBlockDraw(false);
718d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
719d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
720d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
7216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
7226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mActivity.setSwipingEnabled(enable);
723d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
724d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
725dcccc510652b835fdbd39310a07849af8203052aAngus Kong    public SurfaceTexture getSurfaceTexture() {
726d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return mSurfaceTexture;
727d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
728d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
7296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // Countdown timer
730d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
7316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void initializeCountDown() {
7326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mActivity.getLayoutInflater().inflate(R.layout.count_down_to_capture,
7336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                (ViewGroup) mRootView, true);
7346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCountDownView = (CountDownView) (mRootView.findViewById(R.id.count_down_to_capture));
7356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCountDownView.setCountDownFinishedListener((OnCountDownFinishedListener) mController);
736d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
737d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
738d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public boolean isCountingDown() {
7396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mCountDownView != null && mCountDownView.isCountingDown();
740d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
741d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
742d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void cancelCountDown() {
7436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mCountDownView == null) return;
744d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mCountDownView.cancelCountDown();
745d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
746d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
747d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void startCountDown(int sec, boolean playSound) {
7486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mCountDownView == null) initializeCountDown();
749d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mCountDownView.startCountDown(sec, playSound);
750d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
751d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
752d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void showPreferencesToast() {
753d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mNotSelectableToast == null) {
754d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            String str = mActivity.getResources().getString(R.string.not_selectable_in_scene_mode);
755d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mNotSelectableToast = Toast.makeText(mActivity, str, Toast.LENGTH_SHORT);
756d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        }
757d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mNotSelectableToast.show();
758d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
759d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
7603a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    public void showPreviewCover() {
7613a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover.setVisibility(View.VISIBLE);
7623a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    }
7633a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu
764d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onPause() {
7656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        cancelCountDown();
766d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
767d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        // Clear UI.
768d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        collapseCameraControls();
769d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) mFaceView.clear();
770d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
7716a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu        if (mLocationDialog != null && mLocationDialog.isShowing()) {
7726a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu            mLocationDialog.dismiss();
7736a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu        }
7746a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu        mLocationDialog = null;
775d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
776d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
77759390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    public void initDisplayChangeListener() {
77859390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu        ((CameraRootView) mRootView).setDisplayChangeListener(this);
77959390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    }
78059390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu
78159390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    public void removeDisplayChangeListener() {
78259390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu        ((CameraRootView) mRootView).removeDisplayChangeListener();
78359390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    }
78459390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu
785d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    // focus UI implementation
786d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
787d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    private FocusIndicator getFocusIndicator() {
788d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return (mFaceView != null && mFaceView.faceExists()) ? mFaceView : mPieRenderer;
789d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
790d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
791d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
792d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public boolean hasFaces() {
793d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        return (mFaceView != null && mFaceView.faceExists());
794d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
795d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
796d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void clearFaces() {
797d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) mFaceView.clear();
798d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
799d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
800d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
801d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void clearFocus() {
8022441ada50f4bfa3a6c59472ebd3b6339778b8b6bMichael Kolb        FocusIndicator indicator = getFocusIndicator();
8032441ada50f4bfa3a6c59472ebd3b6339778b8b6bMichael Kolb        if (indicator != null) indicator.clear();
804d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
805d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
806d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
807d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void setFocusPosition(int x, int y) {
808d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mPieRenderer.setFocus(x, y);
809d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
810d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
811d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
812d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onFocusStarted() {
813d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        getFocusIndicator().showStart();
814d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
815d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
816d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
817d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onFocusSucceeded(boolean timeout) {
818d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        getFocusIndicator().showSuccess(timeout);
819d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
820d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
821d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
822d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onFocusFailed(boolean timeout) {
823d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        getFocusIndicator().showFail(timeout);
824d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
825d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
826d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
827d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void pauseFaceDetection() {
828d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) mFaceView.pause();
829d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
830d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
831d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
832d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void resumeFaceDetection() {
833d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mFaceView != null) mFaceView.resume();
834d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
835d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
836d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public void onStartFaceDetection(int orientation, boolean mirror) {
837d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.clear();
838d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.setVisibility(View.VISIBLE);
839d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.setDisplayOrientation(orientation);
840d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.setMirror(mirror);
841d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.resume();
842d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
843d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
844d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    @Override
8459e76552adff6ecf8b8e4070ecd61699cb6d18269Angus Kong    public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) {
846d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mFaceView.setFaces(faces);
847d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
848d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
8497b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui    @Override
8506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDisplayChanged() {
8510ba8eaaa5d26f0a806e7bc987676bbc29ad1085cDoris Liu        Log.d(TAG, "Device flip detected.");
8526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.checkLayoutFlip();
8536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mController.updateCameraOrientation();
8543bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    }
8553bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb
856d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb}
857