1ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong/*
2ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Copyright (C) 2013 The Android Open Source Project
3ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong *
4ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Licensed under the Apache License, Version 2.0 (the "License");
5ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * you may not use this file except in compliance with the License.
6ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * You may obtain a copy of the License at
7ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong *
8ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong *      http://www.apache.org/licenses/LICENSE-2.0
9ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong *
10ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Unless required by applicable law or agreed to in writing, software
11ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * distributed under the License is distributed on an "AS IS" BASIS,
12ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * See the License for the specific language governing permissions and
14ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * limitations under the License.
15ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong */
16ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
17ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongpackage com.android.camera;
18ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
19ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.app.AlertDialog;
20ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.app.ProgressDialog;
21ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.content.Context;
22ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.content.DialogInterface;
23ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.content.res.Configuration;
24ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.content.res.Resources;
25ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Bitmap;
26ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Canvas;
27ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Matrix;
28ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Point;
29ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Rect;
30ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.SurfaceTexture;
31ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.drawable.BitmapDrawable;
32ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.drawable.Drawable;
33ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.util.Log;
34ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.view.LayoutInflater;
35ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.view.TextureView;
36ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.view.View;
37ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.view.ViewGroup;
38ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.widget.FrameLayout;
39ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.widget.ImageView;
40105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liuimport android.widget.LinearLayout;
41ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.widget.TextView;
42ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
43ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.CameraControls;
44ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.CameraRootView;
45ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
46352b014552d77948193d84ec177c7673552eb1eeDoris Liuimport com.android.camera.util.CameraUtil;
47ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera2.R;
48ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
49ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong/**
50ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * The UI of {@link WideAnglePanoramaModule}.
51ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong */
52ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongpublic class WideAnglePanoramaUI implements
53ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        TextureView.SurfaceTextureListener,
54ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        ShutterButton.OnShutterButtonListener,
55352b014552d77948193d84ec177c7673552eb1eeDoris Liu        CameraRootView.MyDisplayListener,
56ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        View.OnLayoutChangeListener {
57ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
58ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @SuppressWarnings("unused")
59ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private static final String TAG = "CAM_WidePanoramaUI";
60ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
61ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private CameraActivity mActivity;
62ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private WideAnglePanoramaController mController;
63ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
64ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ViewGroup mRootView;
65ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ModuleSwitcher mSwitcher;
66ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private FrameLayout mCaptureLayout;
67ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private View mReviewLayout;
68ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ImageView mReview;
69ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private View mPreviewBorder;
70ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private View mLeftIndicator;
71ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private View mRightIndicator;
72ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private View mCaptureIndicator;
73ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private PanoProgressBar mCaptureProgressBar;
74ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private PanoProgressBar mSavingProgressBar;
75ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private TextView mTooFastPrompt;
76105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu    private View mPreviewLayout;
77105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu    private ViewGroup mReviewControl;
78ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private TextureView mTextureView;
79ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ShutterButton mShutterButton;
80ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private CameraControls mCameraControls;
81ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
82ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private Matrix mProgressDirectionMatrix = new Matrix();
83ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private float[] mProgressAngle = new float[2];
84ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
85ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private DialogHelper mDialogHelper;
86ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
87ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    // Color definitions.
88ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private int mIndicatorColor;
89ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private int mIndicatorColorFast;
90ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private int mReviewBackground;
91ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private SurfaceTexture mSurfaceTexture;
923a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    private View mPreviewCover;
93ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
94ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    /** Constructor. */
95ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public WideAnglePanoramaUI(
96ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            CameraActivity activity,
97ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            WideAnglePanoramaController controller,
98ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            ViewGroup root) {
99ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mActivity = activity;
100ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mController = controller;
101ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRootView = root;
102ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
103ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        createContentView();
104ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher);
105ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setCurrentIndex(ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX);
106ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setSwitchListener(mActivity);
107ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
108ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
109ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onStartCapture() {
110ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        hideSwitcher();
111ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mShutterButton.setImageResource(R.drawable.btn_shutter_recording);
112ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureIndicator.setVisibility(View.VISIBLE);
113ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        showDirectionIndicators(PanoProgressBar.DIRECTION_NONE);
114ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
115ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
116ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showPreviewUI() {
117ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureLayout.setVisibility(View.VISIBLE);
118ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        showUI();
119ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
120ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
121ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onStopCapture() {
122ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureIndicator.setVisibility(View.INVISIBLE);
123ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        hideTooFastIndication();
124ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        hideDirectionIndicators();
125ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
126ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
127ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void hideSwitcher() {
128ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.closePopup();
129ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setVisibility(View.INVISIBLE);
130ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
131ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
132ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void hideUI() {
133ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        hideSwitcher();
134ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCameraControls.setVisibility(View.INVISIBLE);
135ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
136ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
137ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showUI() {
138ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        showSwitcher();
139ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCameraControls.setVisibility(View.VISIBLE);
140ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
141ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
1423044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    public void onPreviewFocusChanged(boolean previewFocused) {
1433044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        if (previewFocused) {
1443044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren            showUI();
1453044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        } else {
1463044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren            hideUI();
1473044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        }
1483044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    }
1493044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren
1503044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    public boolean arePreviewControlsVisible() {
1513044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren        return (mCameraControls.getVisibility() == View.VISIBLE);
1523044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren    }
1533044d8c577432d6e9721fc8b26ac2afbbaf21266Erin Dahlgren
154ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showSwitcher() {
155ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSwitcher.setVisibility(View.VISIBLE);
156ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
157ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
158ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void setCaptureProgressOnDirectionChangeListener(
159ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            PanoProgressBar.OnDirectionChangeListener listener) {
160ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setOnDirectionChangeListener(listener);
161ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
162ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
163ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void resetCaptureProgress() {
164ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.reset();
165ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
166ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
167ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void setMaxCaptureProgress(int max) {
168ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setMaxProgress(max);
169ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
170ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
171ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showCaptureProgress() {
172ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setVisibility(View.VISIBLE);
173ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
174ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
175ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void updateCaptureProgress(
176ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            float panningRateXInDegree, float panningRateYInDegree,
177ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            float progressHorizontalAngle, float progressVerticalAngle,
178ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            float maxPanningSpeed) {
179ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
180ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        if ((Math.abs(panningRateXInDegree) > maxPanningSpeed)
181ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                || (Math.abs(panningRateYInDegree) > maxPanningSpeed)) {
182ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            showTooFastIndication();
183ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        } else {
184ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            hideTooFastIndication();
185ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
186ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
187ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        // progressHorizontalAngle and progressVerticalAngle are relative to the
188ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        // camera. Convert them to UI direction.
189ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mProgressAngle[0] = progressHorizontalAngle;
190ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mProgressAngle[1] = progressVerticalAngle;
191ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mProgressDirectionMatrix.mapPoints(mProgressAngle);
192ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
193ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        int angleInMajorDirection =
194ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                (Math.abs(mProgressAngle[0]) > Math.abs(mProgressAngle[1]))
195ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        ? (int) mProgressAngle[0]
196ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        : (int) mProgressAngle[1];
197ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setProgress((angleInMajorDirection));
198ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
199ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
200ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void setProgressOrientation(int orientation) {
201ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mProgressDirectionMatrix.reset();
202ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mProgressDirectionMatrix.postRotate(orientation);
203ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
204ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
205ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showDirectionIndicators(int direction) {
206ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        switch (direction) {
207ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            case PanoProgressBar.DIRECTION_NONE:
208ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mLeftIndicator.setVisibility(View.VISIBLE);
209ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mRightIndicator.setVisibility(View.VISIBLE);
210ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
211ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            case PanoProgressBar.DIRECTION_LEFT:
212ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mLeftIndicator.setVisibility(View.VISIBLE);
213ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mRightIndicator.setVisibility(View.INVISIBLE);
214ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
215ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            case PanoProgressBar.DIRECTION_RIGHT:
216ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mLeftIndicator.setVisibility(View.INVISIBLE);
217ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mRightIndicator.setVisibility(View.VISIBLE);
218ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
219ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
220ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
221ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
222ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public SurfaceTexture getSurfaceTexture() {
223ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        return mSurfaceTexture;
224ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
225ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
226ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
227ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
228ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSurfaceTexture = surfaceTexture;
229ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mController.onPreviewUIReady();
230ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
231ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
232ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
233ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
234ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
235ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
236ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
237ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
238ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
239ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mController.onPreviewUIDestroyed();
240ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSurfaceTexture = null;
241ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        Log.d(TAG, "surfaceTexture is destroyed");
242ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        return true;
243ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
244ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
245ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
246ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
247fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        // Make sure preview cover is hidden if preview data is available.
248fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        if (mPreviewCover.getVisibility() != View.GONE) {
249fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers            mPreviewCover.setVisibility(View.GONE);
250fccf83bd342a3a83dc284525488e69f25e4667c4Andy Huibers        }
251ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
252ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
253ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private void hideDirectionIndicators() {
254ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mLeftIndicator.setVisibility(View.INVISIBLE);
255ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRightIndicator.setVisibility(View.INVISIBLE);
256ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
257ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
258ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public Point getPreviewAreaSize() {
259ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        return new Point(
260ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mTextureView.getWidth(), mTextureView.getHeight());
261ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
262ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
263ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void reset() {
264ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mShutterButton.setImageResource(R.drawable.btn_new_shutter);
265ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mReviewLayout.setVisibility(View.GONE);
266ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setVisibility(View.INVISIBLE);
267ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
268ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
269ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showFinalMosaic(Bitmap bitmap, int orientation) {
270ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        if (bitmap != null && orientation != 0) {
271ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            Matrix rotateMatrix = new Matrix();
272ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            rotateMatrix.setRotate(orientation);
273ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            bitmap = Bitmap.createBitmap(
274ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
275ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    rotateMatrix, false);
276ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
277ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
278ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mReview.setImageBitmap(bitmap);
279ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureLayout.setVisibility(View.GONE);
280ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mReviewLayout.setVisibility(View.VISIBLE);
281ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
282ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
283ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onConfigurationChanged(
284ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            Configuration newConfig, boolean threadRunning) {
285ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        Drawable lowResReview = null;
286ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        if (threadRunning) lowResReview = mReview.getDrawable();
287ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
288ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        // Change layout in response to configuration change
289ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        LayoutInflater inflater = (LayoutInflater)
290ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
291ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
292105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mReviewControl.removeAllViews();
293105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        inflater.inflate(R.layout.pano_review_control, mReviewControl, true);
294ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
295352b014552d77948193d84ec177c7673552eb1eeDoris Liu        mRootView.bringChildToFront(mCameraControls);
296ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        setViews(mActivity.getResources());
297ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        if (threadRunning) {
298ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mReview.setImageDrawable(lowResReview);
299ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mCaptureLayout.setVisibility(View.GONE);
300ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mReviewLayout.setVisibility(View.VISIBLE);
301ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
302ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
303ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
304ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void resetSavingProgress() {
305ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.reset();
306ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setRightIncreasing(true);
307ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
308ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
309ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void updateSavingProgress(int progress) {
310ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setProgress(progress);
311ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
312ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
313ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
314ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onShutterButtonFocus(boolean pressed) {
315ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        // Do nothing.
316ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
317ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
318ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
319ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onShutterButtonClick() {
320ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mController.onShutterButtonClick();
321ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
322ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
323ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    @Override
324ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onLayoutChange(
325ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            View v, int l, int t, int r, int b,
326ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            int oldl, int oldt, int oldr, int oldb) {
327ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mController.onPreviewUILayoutChange(l, t, r, b);
328ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
329ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
330ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showAlertDialog(
331ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            String title, String failedString,
332ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            String OKString, Runnable runnable) {
333ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mDialogHelper.showAlertDialog(title, failedString, OKString, runnable);
334ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
335ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
336ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void showWaitingDialog(String title) {
337ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mDialogHelper.showWaitingDialog(title);
338ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
339ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
340ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void dismissAllDialogs() {
341ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mDialogHelper.dismissAll();
342ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
343ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
344ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private void createContentView() {
345105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        LayoutInflater inflator = (LayoutInflater) mActivity
346105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
347ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        inflator.inflate(R.layout.panorama_module, mRootView, true);
348105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
349ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        Resources appRes = mActivity.getResources();
350ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mIndicatorColor = appRes.getColor(R.color.pano_progress_indication);
351ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mReviewBackground = appRes.getColor(R.color.review_background);
352ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mIndicatorColorFast = appRes.getColor(R.color.pano_progress_indication_fast);
353ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
3543a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover = mRootView.findViewById(R.id.preview_cover);
355105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mPreviewLayout = mRootView.findViewById(R.id.pano_preview_layout);
356105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mReviewControl = (ViewGroup) mRootView.findViewById(R.id.pano_review_control);
357105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mReviewLayout = mRootView.findViewById(R.id.pano_review_layout);
358105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mReview = (ImageView) mRootView.findViewById(R.id.pano_reviewarea);
359ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureLayout = (FrameLayout) mRootView.findViewById(R.id.panorama_capture_layout);
360ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar = (PanoProgressBar) mRootView.findViewById(R.id.pano_pan_progress_bar);
361ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setBackgroundColor(appRes.getColor(R.color.pano_progress_empty));
362ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setDoneColor(appRes.getColor(R.color.pano_progress_done));
363ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setIndicatorColor(mIndicatorColor);
364ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setIndicatorWidth(20);
365ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
366ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPreviewBorder = mCaptureLayout.findViewById(R.id.pano_preview_area_border);
367ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
368ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mLeftIndicator = mRootView.findViewById(R.id.pano_pan_left_indicator);
369ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRightIndicator = mRootView.findViewById(R.id.pano_pan_right_indicator);
370ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mLeftIndicator.setEnabled(false);
371ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRightIndicator.setEnabled(false);
372ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mTooFastPrompt = (TextView) mRootView.findViewById(R.id.pano_capture_too_fast_textview);
373105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mCaptureIndicator = mRootView.findViewById(R.id.pano_capture_indicator);
374105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
375105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
376105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mShutterButton.setImageResource(R.drawable.btn_new_shutter);
377105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mShutterButton.setOnShutterButtonListener(this);
378105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        // Hide menu and indicators.
379105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mRootView.findViewById(R.id.menu).setVisibility(View.GONE);
380105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mRootView.findViewById(R.id.on_screen_indicators).setVisibility(View.GONE);
381105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mReview.setBackgroundColor(mReviewBackground);
382105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
383105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        // TODO: set display change listener properly.
384105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        ((CameraRootView) mRootView).setDisplayChangeListener(null);
385105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mTextureView = (TextureView) mRootView.findViewById(R.id.pano_preview_textureview);
386105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mTextureView.setSurfaceTextureListener(this);
387105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mTextureView.addOnLayoutChangeListener(this);
388105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
389105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
390105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mDialogHelper = new DialogHelper();
391105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        setViews(appRes);
392105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu    }
393105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
394105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu    private void setViews(Resources appRes) {
395105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        int weight = appRes.getInteger(R.integer.SRI_pano_layout_weight);
396105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
397105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPreviewLayout.getLayoutParams();
398105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        lp.weight = weight;
399105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mPreviewLayout.setLayoutParams(lp);
400105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
401105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        lp = (LinearLayout.LayoutParams) mReview.getLayoutParams();
402105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        lp.weight = weight;
403105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu        mPreviewLayout.setLayoutParams(lp);
404ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
405ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar = (PanoProgressBar) mRootView.findViewById(R.id.pano_saving_progress_bar);
406ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setIndicatorWidth(0);
407ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setMaxProgress(100);
408ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setBackgroundColor(appRes.getColor(R.color.pano_progress_empty));
409ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mSavingProgressBar.setDoneColor(appRes.getColor(R.color.pano_progress_indication));
410ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
411ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        View cancelButton = mRootView.findViewById(R.id.pano_review_cancel_button);
412ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        cancelButton.setOnClickListener(new View.OnClickListener() {
413ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            @Override
414ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            public void onClick(View arg0) {
415ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mController.cancelHighResStitching();
416ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            }
417ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        });
418ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
419105aaf4dd5a381d4c5098fc1d7ace29a3c240c9eDoris Liu
420ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
421ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
422ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private void showTooFastIndication() {
423ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mTooFastPrompt.setVisibility(View.VISIBLE);
424ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        // The PreviewArea also contains the border for "too fast" indication.
425ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPreviewBorder.setVisibility(View.VISIBLE);
426ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setIndicatorColor(mIndicatorColorFast);
427ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mLeftIndicator.setEnabled(true);
428ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRightIndicator.setEnabled(true);
429ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
430ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
431ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private void hideTooFastIndication() {
432ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mTooFastPrompt.setVisibility(View.GONE);
433ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPreviewBorder.setVisibility(View.INVISIBLE);
434ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCaptureProgressBar.setIndicatorColor(mIndicatorColor);
435ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mLeftIndicator.setEnabled(false);
436ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mRightIndicator.setEnabled(false);
437ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
438ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
439352b014552d77948193d84ec177c7673552eb1eeDoris Liu    public void flipPreviewIfNeeded() {
440209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        // Rotation needed to display image correctly clockwise
441209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        int cameraOrientation = mController.getCameraOrientation();
442209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        // Display rotated counter-clockwise
443209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        int displayRotation = CameraUtil.getDisplayRotation(mActivity);
444209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        // Rotation needed to display image correctly on current display
445209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        int rotation = (cameraOrientation - displayRotation + 360) % 360;
446209a165bd776c938cad388fcf0b1ed27eef4ed83Doris Liu        if (rotation >= 180) {
447352b014552d77948193d84ec177c7673552eb1eeDoris Liu            mTextureView.setRotation(180);
448352b014552d77948193d84ec177c7673552eb1eeDoris Liu        } else {
449352b014552d77948193d84ec177c7673552eb1eeDoris Liu            mTextureView.setRotation(0);
450352b014552d77948193d84ec177c7673552eb1eeDoris Liu        }
451352b014552d77948193d84ec177c7673552eb1eeDoris Liu    }
452352b014552d77948193d84ec177c7673552eb1eeDoris Liu
453352b014552d77948193d84ec177c7673552eb1eeDoris Liu    @Override
454352b014552d77948193d84ec177c7673552eb1eeDoris Liu    public void onDisplayChanged() {
455352b014552d77948193d84ec177c7673552eb1eeDoris Liu        mCameraControls.checkLayoutFlip();
456352b014552d77948193d84ec177c7673552eb1eeDoris Liu        flipPreviewIfNeeded();
457352b014552d77948193d84ec177c7673552eb1eeDoris Liu    }
458352b014552d77948193d84ec177c7673552eb1eeDoris Liu
459352b014552d77948193d84ec177c7673552eb1eeDoris Liu    public void initDisplayChangeListener() {
460352b014552d77948193d84ec177c7673552eb1eeDoris Liu        ((CameraRootView) mRootView).setDisplayChangeListener(this);
461352b014552d77948193d84ec177c7673552eb1eeDoris Liu    }
462352b014552d77948193d84ec177c7673552eb1eeDoris Liu
463352b014552d77948193d84ec177c7673552eb1eeDoris Liu    public void removeDisplayChangeListener() {
464352b014552d77948193d84ec177c7673552eb1eeDoris Liu        ((CameraRootView) mRootView).removeDisplayChangeListener();
465352b014552d77948193d84ec177c7673552eb1eeDoris Liu    }
466352b014552d77948193d84ec177c7673552eb1eeDoris Liu
4673a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    public void showPreviewCover() {
4683a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu        mPreviewCover.setVisibility(View.VISIBLE);
4693a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu    }
4703a45c33d74fe0ad0ade9be3d037560a53891c627Doris Liu
471ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private class DialogHelper {
472ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        private ProgressDialog mProgressDialog;
473ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        private AlertDialog mAlertDialog;
474ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
475ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        DialogHelper() {
476ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mProgressDialog = null;
477ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mAlertDialog = null;
478ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
479ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
480ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public void dismissAll() {
481ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            if (mAlertDialog != null) {
482ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mAlertDialog.dismiss();
483ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mAlertDialog = null;
484ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            }
485ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            if (mProgressDialog != null) {
486ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mProgressDialog.dismiss();
487ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mProgressDialog = null;
488ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            }
489ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
490ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
491ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public void showAlertDialog(
492ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                CharSequence title, CharSequence message,
493ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                CharSequence buttonMessage, final Runnable buttonRunnable) {
494ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            dismissAll();
495ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mAlertDialog = (new AlertDialog.Builder(mActivity))
496ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    .setTitle(title)
497ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    .setMessage(message)
498ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    .setNeutralButton(buttonMessage, new DialogInterface.OnClickListener() {
499ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        @Override
500ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        public void onClick(DialogInterface dialogInterface, int i) {
501ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                            buttonRunnable.run();
502ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        }
503ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    })
504ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    .show();
505ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
506ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
507ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public void showWaitingDialog(CharSequence message) {
508ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            dismissAll();
509ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mProgressDialog = ProgressDialog.show(mActivity, null, message, true, false);
510ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
511ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
512ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
513ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private static class FlipBitmapDrawable extends BitmapDrawable {
514ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
515ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public FlipBitmapDrawable(Resources res, Bitmap bitmap) {
516ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            super(res, bitmap);
517ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
518ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
519ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        @Override
520ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public void draw(Canvas canvas) {
521ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            Rect bounds = getBounds();
522ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            int cx = bounds.centerX();
523ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            int cy = bounds.centerY();
524ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            canvas.save(Canvas.MATRIX_SAVE_FLAG);
525ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            canvas.rotate(180, cx, cy);
526ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            super.draw(canvas);
527ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            canvas.restore();
528ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        }
529ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    }
530ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong}
531