1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.ui.mediapicker;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.Manifest;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.pm.PackageManager;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.graphics.Rect;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.hardware.Camera;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.SystemClock;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.LayoutInflater;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.MotionEvent;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.ViewGroup;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.animation.AlphaAnimation;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.animation.Animation;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.animation.AnimationSet;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.Chronometer;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.ImageButton;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MediaPickerMessagePartData;
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.mediapicker.CameraManager.MediaCallback;
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.ui.mediapicker.camerafocus.RenderOverlay;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil;
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.OsUtil;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UiUtils;
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Chooser which allows the user to take pictures or video without leaving the current app/activity
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddclass CameraMediaChooser extends MediaChooser implements
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.CameraManagerListener {
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private CameraPreview.CameraPreviewHost mCameraPreviewHost;
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ImageButton mFullScreenButton;
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ImageButton mSwapCameraButton;
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ImageButton mSwapModeButton;
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ImageButton mCaptureButton;
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ImageButton mCancelVideoButton;
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Chronometer mVideoCounter;
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private boolean mVideoCancelled;
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private int mErrorToast;
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private View mEnabledView;
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private View mMissingPermissionView;
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    CameraMediaChooser(final MediaPicker mediaPicker) {
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super(mediaPicker);
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public int getSupportedMediaTypes() {
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (CameraManager.get().hasAnyCamera()) {
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return MediaPicker.MEDIA_TYPE_IMAGE | MediaPicker.MEDIA_TYPE_VIDEO;
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else {
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return MediaPicker.MEDIA_TYPE_NONE;
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public View destroyView() {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().closeCamera();
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setListener(null);
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setSubscriptionDataProvider(null);
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return super.destroyView();
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected View createView(final ViewGroup container) {
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setListener(this);
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setSubscriptionDataProvider(this);
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setVideoMode(false);
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final LayoutInflater inflater = getLayoutInflater();
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final CameraMediaChooserView view = (CameraMediaChooserView) inflater.inflate(
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.layout.mediapicker_camera_chooser,
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                container /* root */,
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                false /* attachToRoot */);
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCameraPreviewHost = (CameraPreview.CameraPreviewHost) view.findViewById(
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.id.camera_preview);
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCameraPreviewHost.getView().setOnTouchListener(new View.OnTouchListener() {
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public boolean onTouch(final View view, final MotionEvent motionEvent) {
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (CameraManager.get().isVideoMode()) {
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // Prevent the swipe down in video mode because video is always captured in
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    // full screen
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return true;
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return false;
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final View shutterVisual = view.findViewById(R.id.camera_shutter_visual);
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mFullScreenButton = (ImageButton) view.findViewById(R.id.camera_fullScreen_button);
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mFullScreenButton.setOnClickListener(new View.OnClickListener() {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onClick(final View view) {
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mMediaPicker.setFullScreen(true);
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapCameraButton = (ImageButton) view.findViewById(R.id.camera_swapCamera_button);
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapCameraButton.setOnClickListener(new View.OnClickListener() {
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onClick(final View view) {
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                CameraManager.get().swapCamera();
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCaptureButton = (ImageButton) view.findViewById(R.id.camera_capture_button);
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCaptureButton.setOnClickListener(new View.OnClickListener() {
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onClick(final View v) {
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final float heightPercent = Math.min(mMediaPicker.getViewPager().getHeight() /
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        (float) mCameraPreviewHost.getView().getHeight(), 1);
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (CameraManager.get().isRecording()) {
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    CameraManager.get().stopVideo();
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } else {
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final CameraManager.MediaCallback callback = new CameraManager.MediaCallback() {
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        @Override
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        public void onMediaReady(
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                final Uri uriToVideo, final String contentType,
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                final int width, final int height) {
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            mVideoCounter.stop();
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            if (mVideoCancelled || uriToVideo == null) {
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                mVideoCancelled = false;
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            } else {
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                final Rect startRect = new Rect();
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                // It's possible to throw out the chooser while taking the
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                // picture/video.  In that case, still use the attachment, just
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                // skip the startRect
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                if (mView != null) {
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                    mView.getGlobalVisibleRect(startRect);
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                }
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                mMediaPicker.dispatchItemsSelected(
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                        new MediaPickerMessagePartData(startRect, contentType,
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                                uriToVideo, width, height),
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                        true /* dismissMediaPicker */);
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            }
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            updateViewState();
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        @Override
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        public void onMediaFailed(final Exception exception) {
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            UiUtils.showToastAtBottom(R.string.camera_media_failure);
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            updateViewState();
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        @Override
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        public void onMediaInfo(final int what) {
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            if (what == MediaCallback.MEDIA_NO_DATA) {
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                UiUtils.showToastAtBottom(R.string.camera_media_failure);
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            }
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            updateViewState();
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    };
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    if (CameraManager.get().isVideoMode()) {
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        CameraManager.get().startVideo(callback);
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        mVideoCounter.setBase(SystemClock.elapsedRealtime());
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        mVideoCounter.start();
178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        updateViewState();
179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } else {
180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        showShutterEffect(shutterVisual);
181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        CameraManager.get().takePicture(heightPercent, callback);
182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        updateViewState();
183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton = (ImageButton) view.findViewById(R.id.camera_swap_mode_button);
189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton.setOnClickListener(new View.OnClickListener() {
190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onClick(final View view) {
192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final boolean isSwitchingToVideo = !CameraManager.get().isVideoMode();
193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (isSwitchingToVideo && !OsUtil.hasRecordAudioPermission()) {
194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    requestRecordAudioPermission();
195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                } else {
196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    onSwapMode();
197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCancelVideoButton = (ImageButton) view.findViewById(R.id.camera_cancel_button);
202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCancelVideoButton.setOnClickListener(new View.OnClickListener() {
203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onClick(final View view) {
205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mVideoCancelled = true;
206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                CameraManager.get().stopVideo();
207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mMediaPicker.dismiss(true);
208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mVideoCounter = (Chronometer) view.findViewById(R.id.camera_video_counter);
212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setRenderOverlay((RenderOverlay) view.findViewById(R.id.focus_visual));
214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mEnabledView = view.findViewById(R.id.mediapicker_enabled);
216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mMissingPermissionView = view.findViewById(R.id.missing_permission_view);
217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Must set mView before calling updateViewState because it operates on mView
219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mView = view;
220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateViewState();
221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateForPermissionState(CameraManager.hasCameraPermission());
222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return view;
223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public int getIconResource() {
227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return R.drawable.ic_camera_light;
228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public int getIconDescriptionResource() {
232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return R.string.mediapicker_cameraChooserDescription;
233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Updates the view when entering or leaving full-screen camera mode
237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param fullScreen
238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    void onFullScreenChanged(final boolean fullScreen) {
241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.onFullScreenChanged(fullScreen);
242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (!fullScreen && CameraManager.get().isVideoMode()) {
243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            CameraManager.get().setVideoMode(false);
244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateViewState();
246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Initializes the control to a default state when it is opened / closed
250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param open True if the control is opened
251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    void onOpenedChanged(final boolean open) {
254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.onOpenedChanged(open);
255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateViewState();
256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected void setSelected(final boolean selected) {
260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.setSelected(selected);
261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (selected) {
262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (CameraManager.hasCameraPermission()) {
263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // If an error occurred before the chooser was selected, show it now
264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                showErrorToastIfNeeded();
265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                requestCameraPermission();
267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void requestCameraPermission() {
272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mMediaPicker.requestPermissions(new String[] { Manifest.permission.CAMERA },
273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                MediaPicker.CAMERA_PERMISSION_REQUEST_CODE);
274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void requestRecordAudioPermission() {
277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mMediaPicker.requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO },
278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                MediaPicker.RECORD_AUDIO_PERMISSION_REQUEST_CODE);
279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    protected void onRequestPermissionsResult(
283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int requestCode, final String permissions[], final int[] grantResults) {
284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (requestCode == MediaPicker.CAMERA_PERMISSION_REQUEST_CODE) {
285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final boolean permissionGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            updateForPermissionState(permissionGranted);
287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (permissionGranted) {
288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mCameraPreviewHost.onCameraPermissionGranted();
289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else if (requestCode == MediaPicker.RECORD_AUDIO_PERMISSION_REQUEST_CODE) {
291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            Assert.isFalse(CameraManager.get().isVideoMode());
292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Switch to video mode
294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                onSwapMode();
295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } else {
296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // Stay in still-photo mode
297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void updateForPermissionState(final boolean granted) {
302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // onRequestPermissionsResult can sometimes get called before createView().
303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mEnabledView == null) {
304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return;
305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mEnabledView.setVisibility(granted ? View.VISIBLE : View.GONE);
308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mMissingPermissionView.setVisibility(granted ? View.GONE : View.VISIBLE);
309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public boolean canSwipeDown() {
313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (CameraManager.get().isVideoMode()) {
314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return true;
315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return super.canSwipeDown();
317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Handles an error from the camera manager by showing the appropriate error message to the user
321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param errorCode One of the CameraManager.ERROR_* constants
322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @param e The exception which caused the error, if any
323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onCameraError(final int errorCode, final Exception e) {
326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        switch (errorCode) {
327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case CameraManager.ERROR_OPENING_CAMERA:
328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case CameraManager.ERROR_SHOWING_PREVIEW:
329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mErrorToast = R.string.camera_error_opening;
330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                break;
331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case CameraManager.ERROR_INITIALIZING_VIDEO:
332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mErrorToast = R.string.camera_error_video_init_fail;
333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                updateViewState();
334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                break;
335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case CameraManager.ERROR_STORAGE_FAILURE:
336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mErrorToast = R.string.camera_error_storage_fail;
337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                updateViewState();
338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                break;
339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case CameraManager.ERROR_TAKING_PICTURE:
340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mErrorToast = R.string.camera_error_failure_taking_picture;
341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                break;
342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            default:
343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mErrorToast = R.string.camera_error_unknown;
344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.w(LogUtil.BUGLE_TAG, "Unknown camera error:" + errorCode);
345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                break;
346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        showErrorToastIfNeeded();
348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void showErrorToastIfNeeded() {
351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mErrorToast != 0 && mSelected) {
352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            UiUtils.showToastAtBottom(mErrorToast);
353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mErrorToast = 0;
354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onCameraChanged() {
359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateViewState();
360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void onSwapMode() {
363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        CameraManager.get().setVideoMode(!CameraManager.get().isVideoMode());
364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (CameraManager.get().isVideoMode()) {
365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mMediaPicker.setFullScreen(true);
366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // For now we start recording immediately
368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.performClick();
369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        updateViewState();
371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void showShutterEffect(final View shutterVisual) {
374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final float maxAlpha = getContext().getResources().getFraction(
375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.fraction.camera_shutter_max_alpha, 1 /* base */, 1 /* pBase */);
376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Divide by 2 so each half of the animation adds up to the full duration
378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final int animationDuration = getContext().getResources().getInteger(
379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.integer.camera_shutter_duration) / 2;
380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final AnimationSet animation = new AnimationSet(false /* shareInterpolator */);
382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Animation alphaInAnimation = new AlphaAnimation(0.0f, maxAlpha);
383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        alphaInAnimation.setDuration(animationDuration);
384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        animation.addAnimation(alphaInAnimation);
385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Animation alphaOutAnimation = new AlphaAnimation(maxAlpha, 0.0f);
387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        alphaOutAnimation.setStartOffset(animationDuration);
388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        alphaOutAnimation.setDuration(animationDuration);
389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        animation.addAnimation(alphaOutAnimation);
390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        animation.setAnimationListener(new Animation.AnimationListener() {
392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onAnimationStart(final Animation animation) {
394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                shutterVisual.setVisibility(View.VISIBLE);
395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onAnimationEnd(final Animation animation) {
399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                shutterVisual.setVisibility(View.GONE);
400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onAnimationRepeat(final Animation animation) {
404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        shutterVisual.startAnimation(animation);
407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /** Updates the state of the buttons and overlays based on the current state of the view */
410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private void updateViewState() {
411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mView == null) {
412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return;
413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Context context = getContext();
416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (context == null) {
417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            // Context is null if the fragment was already removed from the activity
418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return;
419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final boolean fullScreen = mMediaPicker.isFullScreen();
421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final boolean videoMode = CameraManager.get().isVideoMode();
422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final boolean isRecording = CameraManager.get().isRecording();
423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final boolean isCameraAvailable = isCameraAvailable();
424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Camera.CameraInfo cameraInfo = CameraManager.get().getCameraInfo();
425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final boolean frontCamera = cameraInfo != null && cameraInfo.facing ==
426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                Camera.CameraInfo.CAMERA_FACING_FRONT;
427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mView.setSystemUiVisibility(
429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                fullScreen ? View.SYSTEM_UI_FLAG_LOW_PROFILE :
430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                View.SYSTEM_UI_FLAG_VISIBLE);
431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mFullScreenButton.setVisibility(!fullScreen ? View.VISIBLE : View.GONE);
433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mFullScreenButton.setEnabled(isCameraAvailable);
434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapCameraButton.setVisibility(
435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                fullScreen && !isRecording && CameraManager.get().hasFrontAndBackCamera() ?
436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        View.VISIBLE : View.GONE);
437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapCameraButton.setImageResource(frontCamera ?
438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.drawable.ic_camera_front_light :
439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.drawable.ic_camera_rear_light);
440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapCameraButton.setEnabled(isCameraAvailable);
441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCancelVideoButton.setVisibility(isRecording ? View.VISIBLE : View.GONE);
443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mVideoCounter.setVisibility(isRecording ? View.VISIBLE : View.GONE);
444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton.setImageResource(videoMode ?
446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.drawable.ic_mp_camera_small_light :
447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.drawable.ic_mp_video_small_light);
448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton.setContentDescription(context.getString(videoMode ?
449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                R.string.camera_switch_to_still_mode : R.string.camera_switch_to_video_mode));
450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton.setVisibility(isRecording ? View.GONE : View.VISIBLE);
451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mSwapModeButton.setEnabled(isCameraAvailable);
452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (isRecording) {
454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setImageResource(R.drawable.ic_mp_capture_stop_large_light);
455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setContentDescription(context.getString(
456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.string.camera_stop_recording));
457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else if (videoMode) {
458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setImageResource(R.drawable.ic_mp_video_large_light);
459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setContentDescription(context.getString(
460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.string.camera_start_recording));
461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else {
462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setImageResource(R.drawable.ic_checkmark_large_light);
463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mCaptureButton.setContentDescription(context.getString(
464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    R.string.camera_take_picture));
465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mCaptureButton.setEnabled(isCameraAvailable);
467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    int getActionBarTitleResId() {
471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return 0;
472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Returns if the camera is currently ready camera is loaded and not taking a picture.
476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * otherwise we should avoid taking another picture, swapping camera or recording video.
477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private boolean isCameraAvailable() {
479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return CameraManager.get().isCameraAvailable();
480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
482