16827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu/*
26432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu * Copyright (C) 2012 The Android Open Source Project
36827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu *
46827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
56827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * you may not use this file except in compliance with the License.
66827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * You may obtain a copy of the License at
76827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu *
86827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
96827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu *
106827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * Unless required by applicable law or agreed to in writing, software
116827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
126827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * See the License for the specific language governing permissions and
146827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu * limitations under the License.
156827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu */
166827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
176827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liupackage com.android.camera;
186827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
196827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.graphics.Bitmap;
20c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.graphics.Color;
216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.Matrix;
226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.SurfaceTexture;
23c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.graphics.drawable.ColorDrawable;
246827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.hardware.Camera.Parameters;
256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.os.Handler;
266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.os.Message;
276827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.util.Log;
286827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.view.Gravity;
296827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.view.SurfaceHolder;
306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.SurfaceView;
316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.TextureView;
326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.TextureView.SurfaceTextureListener;
336827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.view.View;
346827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.view.View.OnClickListener;
356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.View.OnLayoutChangeListener;
366827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.view.ViewGroup;
376827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.widget.FrameLayout.LayoutParams;
386827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.widget.ImageView;
396827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.widget.LinearLayout;
40c3679c0961521165499380c77344acc69072b2acDoris Liuimport android.widget.PopupWindow;
416827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport android.widget.TextView;
426827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
436827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.CameraPreference.OnPreferenceChangedListener;
446827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.ui.AbstractSettingPopup;
456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.CameraControls;
466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.CameraRootView;
47ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
486827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.ui.PieRenderer;
496827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.ui.RenderOverlay;
506827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.ui.RotateLayout;
516827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liuimport com.android.camera.ui.ZoomRenderer;
52b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
538e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
54638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling
55638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.List;
566827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liupublic class VideoUI implements PieRenderer.PieListener,
583bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb        PreviewGestures.SingleTapListener,
596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        CameraRootView.MyDisplayListener,
606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        SurfaceTextureListener, SurfaceHolder.Callback {
61395ee2d6d3c8fa9e16363517dc9e8afc8cbd609eAngus Kong    private static final String TAG = "CAM_VideoUI";
626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final int UPDATE_TRANSFORM_MATRIX = 1;
636827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // module fields
646827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private CameraActivity mActivity;
656827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private View mRootView;
666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private TextureView mTextureView;
676827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // An review image having same size as preview. It is displayed when
686827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // recording is stopped in capture intent.
696827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private ImageView mReviewImage;
706827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private View mReviewCancelButton;
716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private View mReviewDoneButton;
726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private View mReviewPlayButton;
736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private ShutterButton mShutterButton;
74ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ModuleSwitcher mSwitcher;
756827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private TextView mRecordingTimeView;
766827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private LinearLayout mLabelsLinearLayout;
776827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private View mTimeLapseLabel;
786827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private RenderOverlay mRenderOverlay;
796827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private PieRenderer mPieRenderer;
806827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private VideoMenu mVideoMenu;
816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraControls mCameraControls;
82c3679c0961521165499380c77344acc69072b2acDoris Liu    private SettingsPopup mPopup;
836827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private ZoomRenderer mZoomRenderer;
846827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private PreviewGestures mGestures;
856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private View mMenuButton;
86140c263ebb2504fe1a0212a835f0098ce7973a22Sascha Haeberling    private OnScreenIndicators mOnScreenIndicators;
876827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private RotateLayout mRecordingTimeRect;
88fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu    private boolean mRecordingStarted = false;
896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private SurfaceTexture mSurfaceTexture;
906827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private VideoController mController;
916827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private int mZoomMax;
926827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private List<Integer> mZoomRatios;
934f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling    private View mPreviewThumb;
9437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private View mFlashOverlay;
956827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
963a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    private View mPreviewCover;
976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private SurfaceView mSurfaceView = null;
986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mPreviewWidth = 0;
996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mPreviewHeight = 0;
1006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mSurfaceTextureUncroppedWidth;
1016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mSurfaceTextureUncroppedHeight;
1026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private float mAspectRatio = 4f / 3f;
1036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Matrix mMatrix = null;
10437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private final AnimationManager mAnimationManager;
1056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private final Handler mHandler = new Handler() {
1066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        @Override
1076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        public void handleMessage(Message msg) {
1086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            switch (msg.what) {
1096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                case UPDATE_TRANSFORM_MATRIX:
1106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    setTransformMatrix(mPreviewWidth, mPreviewHeight);
1116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    break;
1126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                default:
1136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    break;
1146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
1156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
1166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    };
1176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
1186432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        @Override
1196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        public void onLayoutChange(View v, int left, int top, int right,
1206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
1216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            int width = right - left;
1226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            int height = bottom - top;
1236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            // Full-screen screennail
1246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            int w = width;
1256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            int h = height;
126b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            if (CameraUtil.getDisplayRotation(mActivity) % 180 != 0) {
1276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                w = height;
1286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                h = width;
1296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
1306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mPreviewWidth != width || mPreviewHeight != height) {
1316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mPreviewWidth = width;
1326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mPreviewHeight = height;
1336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                onScreenSizeChanged(width, height, w, h);
1346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
1356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
1366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    };
1376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1383a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    public void showPreviewCover() {
1393a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover.setVisibility(View.VISIBLE);
1403a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    }
1413a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu
142c3679c0961521165499380c77344acc69072b2acDoris Liu    private class SettingsPopup extends PopupWindow {
143c3679c0961521165499380c77344acc69072b2acDoris Liu        public SettingsPopup(View popup) {
144c3679c0961521165499380c77344acc69072b2acDoris Liu            super(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
145c3679c0961521165499380c77344acc69072b2acDoris Liu            setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
146c3679c0961521165499380c77344acc69072b2acDoris Liu            setOutsideTouchable(true);
147c3679c0961521165499380c77344acc69072b2acDoris Liu            setFocusable(true);
148c3679c0961521165499380c77344acc69072b2acDoris Liu            popup.setVisibility(View.VISIBLE);
149c3679c0961521165499380c77344acc69072b2acDoris Liu            setContentView(popup);
150c3679c0961521165499380c77344acc69072b2acDoris Liu            showAtLocation(mRootView, Gravity.CENTER, 0, 0);
151c3679c0961521165499380c77344acc69072b2acDoris Liu        }
152c3679c0961521165499380c77344acc69072b2acDoris Liu
153c3679c0961521165499380c77344acc69072b2acDoris Liu        public void dismiss(boolean topLevelOnly) {
154c3679c0961521165499380c77344acc69072b2acDoris Liu            super.dismiss();
155c3679c0961521165499380c77344acc69072b2acDoris Liu            popupDismissed();
156c3679c0961521165499380c77344acc69072b2acDoris Liu            showUI();
157c3679c0961521165499380c77344acc69072b2acDoris Liu            mVideoMenu.popupDismissed(topLevelOnly);
1584ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling
1594ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling            // Switch back into fullscreen/lights-out mode after popup
1604ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling            // is dimissed.
1614ec139dc81482ebfef1e62a3987c53bd5880c759Sascha Haeberling            mActivity.setSystemBarsVisibility(false);
162c3679c0961521165499380c77344acc69072b2acDoris Liu        }
163c3679c0961521165499380c77344acc69072b2acDoris Liu
164c3679c0961521165499380c77344acc69072b2acDoris Liu        @Override
165c3679c0961521165499380c77344acc69072b2acDoris Liu        public void dismiss() {
166c3679c0961521165499380c77344acc69072b2acDoris Liu            // Called by Framework when touch outside the popup or hit back key
167c3679c0961521165499380c77344acc69072b2acDoris Liu            dismiss(true);
168c3679c0961521165499380c77344acc69072b2acDoris Liu        }
169c3679c0961521165499380c77344acc69072b2acDoris Liu    }
170c3679c0961521165499380c77344acc69072b2acDoris Liu
1716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public VideoUI(CameraActivity activity, VideoController controller, View parent) {
1726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mActivity = activity;
1736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mController = controller;
1746827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRootView = parent;
1756827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mActivity.getLayoutInflater().inflate(R.layout.video_module, (ViewGroup) mRootView, true);
1763a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover = mRootView.findViewById(R.id.preview_cover);
1776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
1786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setSurfaceTextureListener(this);
179bdd198ee9047fc180b8e97e1c3a76132256fd36cDoris Liu        mTextureView.addOnLayoutChangeListener(mLayoutListener);
18037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);
1816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
182ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher);
183ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setCurrentIndex(ModuleSwitcher.VIDEO_MODULE_INDEX);
184ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setSwitchListener(mActivity);
1856827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        initializeMiscControls();
1866827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        initializeControlByIntent();
1876827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        initializeOverlay();
18837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager = new AnimationManager();
1896827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
1906827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
1916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void initializeSurfaceView() {
1936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceView = new SurfaceView(mActivity);
1946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        ((ViewGroup) mRootView).addView(mSurfaceView, 0);
1956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceView.getHolder().addCallback(this);
1966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
1976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1986827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private void initializeControlByIntent() {
1992a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        mMenuButton = mRootView.findViewById(R.id.menu);
2006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton.setOnClickListener(new OnClickListener() {
2016827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            @Override
2026827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            public void onClick(View v) {
2036827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                if (mPieRenderer != null) {
2046827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                    mPieRenderer.showInCenter();
2056827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                }
2066827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            }
2076827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        });
2086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2092a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
210eb8adc1754fc668435ee57d1be2235b80fc8c009Michael Kolb        mOnScreenIndicators = new OnScreenIndicators(mActivity,
2112a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                mRootView.findViewById(R.id.on_screen_indicators));
212140c263ebb2504fe1a0212a835f0098ce7973a22Sascha Haeberling        mOnScreenIndicators.resetToDefault();
2136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mController.isVideoCaptureIntent()) {
2146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            hideSwitcher();
2156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mActivity.getLayoutInflater().inflate(R.layout.review_module_control,
2166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (ViewGroup) mCameraControls);
2176827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            // Cannot use RotateImageView for "done" and "cancel" button because
2186827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            // the tablet layout uses RotateLayout, which cannot be cast to
2196827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            // RotateImageView.
2202a7f44cac888de5683d05bef5708f846ee950f43Doris Liu            mReviewDoneButton = mRootView.findViewById(R.id.btn_done);
2212a7f44cac888de5683d05bef5708f846ee950f43Doris Liu            mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel);
2222a7f44cac888de5683d05bef5708f846ee950f43Doris Liu            mReviewPlayButton = mRootView.findViewById(R.id.btn_play);
2236827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mReviewCancelButton.setVisibility(View.VISIBLE);
2246827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mReviewDoneButton.setOnClickListener(new OnClickListener() {
2256827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                @Override
2266827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                public void onClick(View v) {
2276827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                    mController.onReviewDoneClicked(v);
2286827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                }
2296827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            });
2306827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mReviewCancelButton.setOnClickListener(new OnClickListener() {
2316827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                @Override
2326827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                public void onClick(View v) {
2336827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                    mController.onReviewCancelClicked(v);
2346827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                }
2356827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            });
2366827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mReviewPlayButton.setOnClickListener(new OnClickListener() {
2376827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                @Override
2386827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                public void onClick(View v) {
2396827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                    mController.onReviewPlayClicked(v);
2406827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                }
2416827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            });
2426827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
2436827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
2446827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
2456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setPreviewSize(int width, int height) {
2466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (width == 0 || height == 0) {
2476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            Log.w(TAG, "Preview size should not be 0.");
2486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            return;
2496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (width > height) {
2516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mAspectRatio = (float) width / height;
2526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
2536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mAspectRatio = (float) height / width;
2546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
2566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getPreviewWidth() {
2596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mPreviewWidth;
2606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getPreviewHeight() {
2636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mPreviewHeight;
2646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) {
2676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setTransformMatrix(width, height);
2686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
2696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setTransformMatrix(int width, int height) {
2716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMatrix = mTextureView.getTransform(mMatrix);
272b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        int orientation = CameraUtil.getDisplayRotation(mActivity);
2736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        float scaleX = 1f, scaleY = 1f;
2746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        float scaledTextureWidth, scaledTextureHeight;
2756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (width > height) {
2766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureWidth = Math.max(width,
2776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (height * mAspectRatio));
2786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureHeight = Math.max(height,
2796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int)(width / mAspectRatio));
2806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
2816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureWidth = Math.max(width,
2826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (height / mAspectRatio));
2836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            scaledTextureHeight = Math.max(height,
2846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    (int) (width * mAspectRatio));
2856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
2886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
2896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSurfaceTextureUncroppedWidth = scaledTextureWidth;
2906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSurfaceTextureUncroppedHeight = scaledTextureHeight;
2916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
2926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        scaleX = scaledTextureWidth / width;
2936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        scaleY = scaledTextureHeight / height;
2946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2);
2956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setTransform(mMatrix);
2966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
2976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mSurfaceView != null && mSurfaceView.getVisibility() == View.VISIBLE) {
2986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            LayoutParams lp = (LayoutParams) mSurfaceView.getLayoutParams();
2996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            lp.width = (int) mSurfaceTextureUncroppedWidth;
3006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            lp.height = (int) mSurfaceTextureUncroppedHeight;
3016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            lp.gravity = Gravity.CENTER;
3026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSurfaceView.requestLayout();
3036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
3046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
30637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    /**
30737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     * Starts a flash animation
30837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     */
30937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    public void animateFlash() {
31037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager.startFlashAnimation(mFlashOverlay);
31137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
31237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
31337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    /**
31437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     * Starts a capture animation
3153973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu     */
3163973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu    public void animateCapture() {
3173973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        Bitmap bitmap = null;
3183973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        if (mTextureView != null) {
3193973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu            bitmap = mTextureView.getBitmap((int) mSurfaceTextureUncroppedWidth / 2,
3203973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu                    (int) mSurfaceTextureUncroppedHeight / 2);
3213973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        }
3223973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        animateCapture(bitmap);
3233973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu    }
3243973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu
3253973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu    /**
3263973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu     * Starts a capture animation
32737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     * @param bitmap the captured image that we shrink and slide in the animation
32837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     */
32937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    public void animateCapture(Bitmap bitmap) {
3303973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        if (bitmap == null) {
3313973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu            Log.e(TAG, "No valid bitmap for capture animation.");
3323973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu            return;
3333973deba115d398a25f0b74c2aea2ff4079355a5Doris Liu        }
33437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        ((ImageView) mPreviewThumb).setImageBitmap(bitmap);
33537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager.startCaptureAnimation(mPreviewThumb);
33637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
33737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
33837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    /**
33937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     * Cancels on-going animations
34037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling     */
34137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    public void cancelAnimations() {
34237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mAnimationManager.cancelAnimations();
34337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
34437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void hideUI() {
3466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.setVisibility(View.INVISIBLE);
3476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSwitcher.closePopup();
3486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
3506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void showUI() {
3516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.setVisibility(View.VISIBLE);
3526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
3543044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    public boolean arePreviewControlsVisible() {
3553044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        return (mCameraControls.getVisibility() == View.VISIBLE);
3563044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    }
3573044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren
3586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void hideSwitcher() {
3596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSwitcher.closePopup();
3606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSwitcher.setVisibility(View.INVISIBLE);
3616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
3636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void showSwitcher() {
3646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSwitcher.setVisibility(View.VISIBLE);
3656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
3666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
3676827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public boolean collapseCameraControls() {
3686827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        boolean ret = false;
3696827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPopup != null) {
3706827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            dismissPopup(false);
3716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            ret = true;
3726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
3736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        return ret;
3746827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
3756827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
3766827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public boolean removeTopLevelPopup() {
3776827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPopup != null) {
3786827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            dismissPopup(true);
3796827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            return true;
3806827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
3816827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        return false;
3826827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
3836827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
3846827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void enableCameraControls(boolean enable) {
3856827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mGestures != null) {
3866827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mGestures.setZoomOnly(!enable);
3876827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
3886827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPieRenderer != null && mPieRenderer.showsItems()) {
3896827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mPieRenderer.hide();
3906827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
3916827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
3926827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
39359390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    public void initDisplayChangeListener() {
39459390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu        ((CameraRootView) mRootView).setDisplayChangeListener(this);
39559390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    }
39659390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu
39759390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    public void removeDisplayChangeListener() {
39859390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu        ((CameraRootView) mRootView).removeDisplayChangeListener();
39959390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu    }
40059390061e26d3d481c6e0c9b22fb3ee8ec8387b0Doris Liu
4016827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void overrideSettings(final String... keyvalues) {
4026827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mVideoMenu.overrideSettings(keyvalues);
4036827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4046827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4056827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void setOrientationIndicator(int orientation, boolean animation) {
4066827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // We change the orientation of the linearlayout only for phone UI
4076827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // because when in portrait the width is not enough.
4086827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mLabelsLinearLayout != null) {
4096827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            if (((orientation / 90) & 1) == 0) {
4106827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                mLabelsLinearLayout.setOrientation(LinearLayout.VERTICAL);
4116827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            } else {
4126827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                mLabelsLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
4136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            }
4146827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
4156827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRecordingTimeRect.setOrientation(0, animation);
4166827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4176827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4186827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public SurfaceHolder getSurfaceHolder() {
4196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSurfaceView.getHolder();
4206827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4216827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4226827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void hideSurfaceView() {
4236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceView.setVisibility(View.GONE);
4246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setVisibility(View.VISIBLE);
4256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setTransformMatrix(mPreviewWidth, mPreviewHeight);
4266827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4276827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4286827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void showSurfaceView() {
4296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceView.setVisibility(View.VISIBLE);
4306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mTextureView.setVisibility(View.GONE);
4316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setTransformMatrix(mPreviewWidth, mPreviewHeight);
4326827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4336827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4346827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private void initializeOverlay() {
4356827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);
4366827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPieRenderer == null) {
4376827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mPieRenderer = new PieRenderer(mActivity);
4386827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer);
4396827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mPieRenderer.setPieListener(this);
4406827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
4416827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRenderOverlay.addRenderer(mPieRenderer);
4426827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mZoomRenderer == null) {
4436827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mZoomRenderer = new ZoomRenderer(mActivity);
4446827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
4456827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRenderOverlay.addRenderer(mZoomRenderer);
4466827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mGestures == null) {
4476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer);
4486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mRenderOverlay.setGestures(mGestures);
4496827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
4506827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mGestures.setRenderOverlay(mRenderOverlay);
4514f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling
4522a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        mPreviewThumb = mRootView.findViewById(R.id.preview_thumb);
4534f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling        mPreviewThumb.setOnClickListener(new OnClickListener() {
4544f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling            @Override
4554f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling            public void onClick(View v) {
456fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu                // Do not allow navigation to filmstrip during video recording
457fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu                if (!mRecordingStarted) {
458fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu                    mActivity.gotoGallery();
459fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu                }
4604f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling            }
4614f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling        });
4626827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4636827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4646827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void setPrefChangedListener(OnPreferenceChangedListener listener) {
4656827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mVideoMenu.setListener(listener);
4666827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4676827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4686827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private void initializeMiscControls() {
4696827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mReviewImage = (ImageView) mRootView.findViewById(R.id.review_image);
4706827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
4716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.setOnShutterButtonListener(mController);
4726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.setVisibility(View.VISIBLE);
4736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.requestFocus();
4746827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.enableTouch(true);
4756827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRecordingTimeView = (TextView) mRootView.findViewById(R.id.recording_time);
4766827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRecordingTimeRect = (RotateLayout) mRootView.findViewById(R.id.recording_time_rect);
4776827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mTimeLapseLabel = mRootView.findViewById(R.id.time_lapse_label);
4786827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // The R.id.labels can only be found in phone layout.
4796827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // That is, mLabelsLinearLayout should be null in tablet layout.
4806827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels);
4816827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4826827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4838788079a51a90255dce330e56afcb6674deccbf7Michael Kolb    public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) {
484140c263ebb2504fe1a0212a835f0098ce7973a22Sascha Haeberling      mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode());
4858788079a51a90255dce330e56afcb6674deccbf7Michael Kolb      boolean location = RecordLocationPreference.get(
4868788079a51a90255dce330e56afcb6674deccbf7Michael Kolb              prefs, mActivity.getContentResolver());
4878788079a51a90255dce330e56afcb6674deccbf7Michael Kolb      mOnScreenIndicators.updateLocationIndicator(location);
4888788079a51a90255dce330e56afcb6674deccbf7Michael Kolb
4896827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4906827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4916827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void setAspectRatio(double ratio) {
4926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu      //  mPreviewFrameLayout.setAspectRatio(ratio);
4936827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
4946827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
4956827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void showTimeLapseUI(boolean enable) {
4966827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mTimeLapseLabel != null) {
4976827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mTimeLapseLabel.setVisibility(enable ? View.VISIBLE : View.GONE);
4986827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
4996827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5006827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5013bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    private void openMenu() {
5023bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb        if (mPieRenderer != null) {
5033bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb            mPieRenderer.showInCenter();
5043bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb        }
5053bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    }
5063bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb
507c3679c0961521165499380c77344acc69072b2acDoris Liu    public void dismissPopup(boolean topLevelOnly) {
508c3679c0961521165499380c77344acc69072b2acDoris Liu        // In review mode, we do not want to bring up the camera UI
509c3679c0961521165499380c77344acc69072b2acDoris Liu        if (mController.isInReviewMode()) return;
510c3679c0961521165499380c77344acc69072b2acDoris Liu        if (mPopup != null) {
511c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.dismiss(topLevelOnly);
512c3679c0961521165499380c77344acc69072b2acDoris Liu        }
5136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5146827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
515c3679c0961521165499380c77344acc69072b2acDoris Liu    private void popupDismissed() {
516c3679c0961521165499380c77344acc69072b2acDoris Liu        mPopup = null;
5176827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5186827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
519c3679c0961521165499380c77344acc69072b2acDoris Liu    public void showPopup(AbstractSettingPopup popup) {
520c3679c0961521165499380c77344acc69072b2acDoris Liu        hideUI();
52169ef5ea6ed838cf6fba834811f01122d349a61cfDoris Liu
5226827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPopup != null) {
523c3679c0961521165499380c77344acc69072b2acDoris Liu            mPopup.dismiss(false);
5246827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
525c3679c0961521165499380c77344acc69072b2acDoris Liu        mPopup = new SettingsPopup(popup);
5266827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5276827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5286827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void onShowSwitcherPopup() {
5296827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        hidePieRenderer();
5306827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5316827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5326827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public boolean hidePieRenderer() {
5336827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mPieRenderer != null && mPieRenderer.showsItems()) {
5346827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mPieRenderer.hide();
5356827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            return true;
5366827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
5376827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        return false;
5386827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5396827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
54061f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu    // disable preview gestures after shutter is pressed
54161f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu    public void setShutterPressed(boolean pressed) {
54261f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu        if (mGestures == null) return;
54361f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu        mGestures.setEnabled(!pressed);
54461f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu    }
54561f2b082014fe4402dd208029e9378dd5cb1fd1dDoris Liu
5466827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void enableShutter(boolean enable) {
5476827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mShutterButton != null) {
5486827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mShutterButton.setEnabled(enable);
5496827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
5506827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5516827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5526827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // PieListener
5536827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    @Override
5546827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void onPieOpened(int centerX, int centerY) {
5556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setSwipingEnabled(false);
556249653e41763cffbd9bd5ef2298c5120488897fbAndy Huibers        // Close module selection menu when pie menu is opened.
557249653e41763cffbd9bd5ef2298c5120488897fbAndy Huibers        mSwitcher.closePopup();
5586827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5596827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5606827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    @Override
5616827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void onPieClosed() {
5626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setSwipingEnabled(true);
5636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
5646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
5656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
5666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mActivity.setSwipingEnabled(enable);
5676827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5686827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5696827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void showPreviewBorder(boolean enable) {
5706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu       // TODO: mPreviewFrameLayout.showBorder(enable);
5716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // SingleTapListener
5746827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    // Preview area is touched. Take a picture.
5756827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    @Override
5766827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void onSingleTapUp(View view, int x, int y) {
5776827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mController.onSingleTapUp(view, x, y);
5786827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5796827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
580fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu    public void showRecordingUI(boolean recording) {
581fe6596c3474f0ffbf03a2b7a7d89ea9cc9d9d61dDoris Liu        mRecordingStarted = recording;
5826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton.setVisibility(recording ? View.GONE : View.VISIBLE);
5836827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mOnScreenIndicators.setVisibility(recording ? View.GONE : View.VISIBLE);
5846827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (recording) {
5856827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mShutterButton.setImageResource(R.drawable.btn_shutter_video_recording);
5866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            hideSwitcher();
5876827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mRecordingTimeView.setText("");
5886827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mRecordingTimeView.setVisibility(View.VISIBLE);
5896827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        } else {
5906827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
5912a7f44cac888de5683d05bef5708f846ee950f43Doris Liu            if (!mController.isVideoCaptureIntent()) {
5922a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                showSwitcher();
5932a7f44cac888de5683d05bef5708f846ee950f43Doris Liu            }
5946827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mRecordingTimeView.setVisibility(View.GONE);
5956827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
5966827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
5976827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
5986827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void showReviewImage(Bitmap bitmap) {
5996827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mReviewImage.setImageBitmap(bitmap);
6006827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mReviewImage.setVisibility(View.VISIBLE);
6016827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6026827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6036827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void showReviewControls() {
604b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeOut(mShutterButton);
605b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeIn(mReviewDoneButton);
606b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeIn(mReviewPlayButton);
6076827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mReviewImage.setVisibility(View.VISIBLE);
6086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton.setVisibility(View.GONE);
6096827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mOnScreenIndicators.setVisibility(View.GONE);
6106827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6116827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6126827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void hideReviewUI() {
6136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mReviewImage.setVisibility(View.GONE);
6146827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.setEnabled(true);
6156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMenuButton.setVisibility(View.VISIBLE);
6166827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mOnScreenIndicators.setVisibility(View.VISIBLE);
617b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeOut(mReviewDoneButton);
618b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeOut(mReviewPlayButton);
619b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.fadeIn(mShutterButton);
6206827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6216827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6226827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private void setShowMenu(boolean show) {
6236827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mOnScreenIndicators != null) {
6246827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
6256827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
6266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mMenuButton != null) {
6276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE);
6286827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
6296827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6306827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6317b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui    public void onPreviewFocusChanged(boolean previewFocused) {
6327b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui        if (previewFocused) {
6336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            showUI();
6346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
6356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            hideUI();
6366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6376827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mGestures != null) {
6387b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui            mGestures.setEnabled(previewFocused);
6396827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
6406827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        if (mRenderOverlay != null) {
6416827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            // this can not happen in capture mode
6427b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui            mRenderOverlay.setVisibility(previewFocused ? View.VISIBLE : View.GONE);
6436827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
6447b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui        setShowMenu(previewFocused);
6456827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6466827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6476827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void initializePopup(PreferenceGroup pref) {
6486827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mVideoMenu.initialize(pref);
6496827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6506827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6516827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void initializeZoom(Parameters param) {
6526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (param == null || !param.isZoomSupported()) {
6536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mGestures.setZoomEnabled(false);
6546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            return;
6556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mGestures.setZoomEnabled(true);
6576827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomMax = param.getMaxZoom();
6586827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomRatios = param.getZoomRatios();
6596827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // Currently we use immediate zoom for fast zooming to get better UX and
6606827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        // there is no plan to take advantage of the smooth zoom.
6616827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomRenderer.setZoomMax(mZoomMax);
6626827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomRenderer.setZoom(param.getZoom());
6636827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomRenderer.setZoomValue(mZoomRatios.get(param.getZoom()));
6646827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener());
6656827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6666827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6676827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void clickShutter() {
6686827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.performClick();
6696827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6706827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6716827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void pressShutter(boolean pressed) {
6726827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mShutterButton.setPressed(pressed);
6736827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6746827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public View getShutterButton() {
6766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mShutterButton;
6776827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6786827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6796827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void setRecordingTime(String text) {
6806827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRecordingTimeView.setText(text);
6816827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6826827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6836827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    public void setRecordingTimeTextColor(int color) {
6846827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        mRecordingTimeView.setTextColor(color);
6856827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
6866827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
6876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isVisible() {
688285a5be7ce327eb4c169e60ecc4a9cd8d583e65dztenghui        return mCameraControls.getVisibility() == View.VISIBLE;
6896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
6906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
6917b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui    @Override
6926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDisplayChanged() {
6936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCameraControls.checkLayoutFlip();
6946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mController.updateCameraOrientation();
6956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
6966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
6976827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener {
6986827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        @Override
6996827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        public void onZoomValueChanged(int index) {
7006827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            int newZoom = mController.onZoomChanged(index);
7016827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            if (mZoomRenderer != null) {
7026827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu                mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom));
7036827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu            }
7046827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
7056827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
7066827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        @Override
7076827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        public void onZoomStart() {
7086827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
7096827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu
7106827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        @Override
7116827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        public void onZoomEnd() {
7126827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu        }
7136827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu    }
7143bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb
7156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public SurfaceTexture getSurfaceTexture() {
7166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSurfaceTexture;
7173bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb    }
7183bc96b2d1106fc5ebec6fda6aad3bca4d62e81c0Michael Kolb
7196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // SurfaceTexture callbacks
7206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
722395ee2d6d3c8fa9e16363517dc9e8afc8cbd609eAngus Kong        mSurfaceTexture = surface;
723395ee2d6d3c8fa9e16363517dc9e8afc8cbd609eAngus Kong        mController.onPreviewUIReady();
7244f91ab5d099632afd84dd7bd80a804cbbe1f3588Sascha Haeberling    }
7256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
7286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mSurfaceTexture = null;
729395ee2d6d3c8fa9e16363517dc9e8afc8cbd609eAngus Kong        mController.onPreviewUIDestroyed();
7306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Log.d(TAG, "surfaceTexture is destroyed");
7316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return true;
7326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
7366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
740fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        // Make sure preview cover is hidden if preview data is available.
741fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        if (mPreviewCover.getVisibility() != View.GONE) {
742fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers            mPreviewCover.setVisibility(View.GONE);
743fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        }
7446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // SurfaceHolder callbacks
7476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
7496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Log.v(TAG, "Surface changed. width=" + width + ". height=" + height);
7506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void surfaceCreated(SurfaceHolder holder) {
7546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Log.v(TAG, "Surface created");
7556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
7576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void surfaceDestroyed(SurfaceHolder holder) {
7596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Log.v(TAG, "Surface destroyed");
7606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mController.stopPreview();
7616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
7626827ce281bd3a83ca2ffa552cd090e2b427c5f83Doris Liu}
763