148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala/*
248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala *
448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * you may not use this file except in compliance with the License.
648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * You may obtain a copy of the License at
748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala *
848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala *
1048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
1148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
1248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * See the License for the specific language governing permissions and
1448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * limitations under the License.
1548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala */
1648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
1748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalapackage com.android.testingcamera;
1848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
1959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.annotation.SuppressLint;
2048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.app.Activity;
21bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.app.FragmentManager;
2259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.content.res.Resources;
2359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.graphics.ImageFormat;
2448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.hardware.Camera;
25abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.hardware.Camera.Parameters;
26753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvalaimport android.hardware.Camera.ErrorCallback;
27bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.media.CamcorderProfile;
28abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.media.MediaRecorder;
29b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvalaimport android.media.MediaScannerConnection;
30b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvalaimport android.net.Uri;
3148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.os.Bundle;
32abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.os.Environment;
33b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvalaimport android.os.Handler;
3459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.os.SystemClock;
3548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.View;
3648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.SurfaceHolder;
3748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.SurfaceView;
38bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.view.View.OnClickListener;
3948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.AdapterView;
40abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.widget.AdapterView.OnItemSelectedListener;
4148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.ArrayAdapter;
4248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.Button;
43753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvalaimport android.widget.CheckBox;
4459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.widget.LinearLayout;
4548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.LinearLayout.LayoutParams;
4648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.Spinner;
4748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.TextView;
4848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.ToggleButton;
4959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.renderscript.RenderScript;
50abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.text.Layout;
51abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.text.method.ScrollingMovementMethod;
5248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.util.Log;
5359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalaimport android.util.SparseArray;
5448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
55abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.File;
5648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.io.IOException;
57abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.PrintWriter;
58abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.StringWriter;
59abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.text.SimpleDateFormat;
6048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.ArrayList;
61abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.Date;
62abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.HashSet;
6348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.List;
64abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.Set;
6548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
6648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala/**
6748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * A simple test application for the camera API.
6894d24977868e0713cf03f7cec4d6de051f411dcaEino-Ville Talvala *
6994d24977868e0713cf03f7cec4d6de051f411dcaEino-Ville Talvala * The goal of this application is to allow all camera API features to be
70abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala * exercised, and all information provided by the API to be shown.
7148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala */
7259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvalapublic class TestingCamera extends Activity
73753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    implements SurfaceHolder.Callback, Camera.PreviewCallback,
74753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        Camera.ErrorCallback {
7548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
7648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    /** UI elements */
7748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private SurfaceView mPreviewView;
7848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private SurfaceHolder mPreviewHolder;
7959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private LinearLayout mPreviewColumn;
8059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
8159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private SurfaceView mCallbackView;
8259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private SurfaceHolder mCallbackHolder;
8348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
8448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Spinner mCameraSpinner;
85753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private CheckBox mKeepOpenCheckBox;
86bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private Button mInfoButton;
8748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Spinner mPreviewSizeSpinner;
88b2409d280567130723fde8bc2922a43e2976b074David Braun    private Spinner mPreviewFrameRateSpinner;
8948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private ToggleButton mPreviewToggle;
90abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Spinner mAutofocusModeSpinner;
91abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Button mAutofocusButton;
92abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Button mCancelAutofocusButton;
93b2409d280567130723fde8bc2922a43e2976b074David Braun    private TextView mFlashModeSpinnerLabel;
94b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    private Spinner mFlashModeSpinner;
95b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray    private ToggleButton mExposureLockToggle;
96bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private Spinner mSnapshotSizeSpinner;
9748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Button  mTakePictureButton;
98bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private Spinner mCamcorderProfileSpinner;
998bf3e54287366cf790c25577568334b92f67d178Alex Ray    private Spinner mVideoRecordSizeSpinner;
100410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    private Spinner mVideoFrameRateSpinner;
101bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private ToggleButton mRecordToggle;
102753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private CheckBox mRecordHandoffCheckBox;
103faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray    private ToggleButton mRecordStabilizationToggle;
10459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private Spinner mCallbackFormatSpinner;
10559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private ToggleButton mCallbackToggle;
10648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
107abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private TextView mLogView;
108abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
109753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private Set<View> mOpenOnlyControls = new HashSet<View>();
110abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Set<View> mPreviewOnlyControls = new HashSet<View>();
111abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
11259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private SparseArray<String> mFormatNames;
11359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
11448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    /** Camera state */
115753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private int mCameraId;
11648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera mCamera;
11748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera.Parameters mParams;
11848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private List<Camera.Size> mPreviewSizes;
11948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private int mPreviewSize = 0;
120b2409d280567130723fde8bc2922a43e2976b074David Braun    private List<Integer> mPreviewFrameRates;
121b2409d280567130723fde8bc2922a43e2976b074David Braun    private int mPreviewFrameRate = 0;
12259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private List<Integer> mPreviewFormats;
12359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private int mPreviewFormat = 0;
124abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private List<String> mAfModes;
125abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private int mAfMode = 0;
126b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    private List<String> mFlashModes;
127b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    private int mFlashMode = 0;
128bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private List<Camera.Size> mSnapshotSizes;
129bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private int mSnapshotSize = 0;
130bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private List<CamcorderProfile> mCamcorderProfiles;
131bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private int mCamcorderProfile = 0;
1328bf3e54287366cf790c25577568334b92f67d178Alex Ray    private List<Camera.Size> mVideoRecordSizes;
1338bf3e54287366cf790c25577568334b92f67d178Alex Ray    private int mVideoRecordSize = 0;
134410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    private List<Integer> mVideoFrameRates;
135410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    private int mVideoFrameRate = 0;
13648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
137abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private MediaRecorder mRecorder;
138b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    private File mRecordingFile;
139abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
14059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private RenderScript mRS;
14159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
14259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private boolean mCallbacksEnabled = false;
14359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private CallbackProcessor mCallbackProcessor = null;
14459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    long mLastCallbackTimestamp = -1;
14559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    float mCallbackAvgFrameDuration = 30;
14659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    int mCallbackFrameCount = 0;
14759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private static final float MEAN_FPS_HISTORY_COEFF = 0.9f;
14859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private static final float MEAN_FPS_MEASUREMENT_COEFF = 0.1f;
14959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private static final int   FPS_REPORTING_PERIOD = 200; // frames
15059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private static final int CALLBACK_BUFFER_COUNT = 3;
15159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
15248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private static final int CAMERA_UNINITIALIZED = 0;
15348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private static final int CAMERA_OPEN = 1;
15448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private static final int CAMERA_PREVIEW = 2;
15548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private static final int CAMERA_TAKE_PICTURE = 3;
156abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private static final int CAMERA_RECORD = 4;
15748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private int mState = CAMERA_UNINITIALIZED;
15848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
159753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private static final int NO_CAMERA_ID = -1;
16059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
16148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    /** Misc variables */
16248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
16348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private static final String TAG = "TestingCamera";
16448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
165753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
166abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    /** Activity lifecycle */
167abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
16848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    @Override
16948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void onCreate(Bundle savedInstanceState) {
17048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        super.onCreate(savedInstanceState);
17148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
17248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        setContentView(R.layout.main);
17348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
17459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewColumn = (LinearLayout) findViewById(R.id.preview_column);
17559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
17659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewView = (SurfaceView) findViewById(R.id.preview);
17748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewView.getHolder().addCallback(this);
17848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
17959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackView = (SurfaceView)findViewById(R.id.callback_view);
18059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
18148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mCameraSpinner = (Spinner) findViewById(R.id.camera_spinner);
18248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);
18348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
184753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mKeepOpenCheckBox = (CheckBox) findViewById(R.id.keep_open_checkbox);
185753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
186bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mInfoButton = (Button) findViewById(R.id.info_button);
187bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mInfoButton.setOnClickListener(mInfoButtonListener);
188753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mInfoButton);
189bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
19048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewSizeSpinner = (Spinner) findViewById(R.id.preview_size_spinner);
19148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewSizeSpinner.setOnItemSelectedListener(mPreviewSizeListener);
192753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mPreviewSizeSpinner);
19348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
194b2409d280567130723fde8bc2922a43e2976b074David Braun        mPreviewFrameRateSpinner = (Spinner) findViewById(R.id.preview_frame_rate_spinner);
195b2409d280567130723fde8bc2922a43e2976b074David Braun        mPreviewFrameRateSpinner.setOnItemSelectedListener(mPreviewFrameRateListener);
196753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mPreviewFrameRateSpinner);
197b2409d280567130723fde8bc2922a43e2976b074David Braun
19848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewToggle = (ToggleButton) findViewById(R.id.start_preview);
19948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewToggle.setOnClickListener(mPreviewToggleListener);
200753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mPreviewToggle);
20148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
202abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAutofocusModeSpinner = (Spinner) findViewById(R.id.af_mode_spinner);
203abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAutofocusModeSpinner.setOnItemSelectedListener(mAutofocusModeListener);
204753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mAutofocusModeSpinner);
205abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
206abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAutofocusButton = (Button) findViewById(R.id.af_button);
207abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAutofocusButton.setOnClickListener(mAutofocusButtonListener);
208abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewOnlyControls.add(mAutofocusButton);
209abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
210abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mCancelAutofocusButton = (Button) findViewById(R.id.af_cancel_button);
211abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mCancelAutofocusButton.setOnClickListener(mCancelAutofocusButtonListener);
212abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewOnlyControls.add(mCancelAutofocusButton);
213abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
214b2409d280567130723fde8bc2922a43e2976b074David Braun        mFlashModeSpinnerLabel = (TextView) findViewById(R.id.flash_mode_spinner_label);
215b2409d280567130723fde8bc2922a43e2976b074David Braun
216b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        mFlashModeSpinner = (Spinner) findViewById(R.id.flash_mode_spinner);
217b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        mFlashModeSpinner.setOnItemSelectedListener(mFlashModeListener);
218753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mFlashModeSpinner);
219b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
220b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        mExposureLockToggle = (ToggleButton) findViewById(R.id.exposure_lock);
221b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        mExposureLockToggle.setOnClickListener(mExposureLockToggleListener);
222753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mExposureLockToggle);
223b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray
224bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mSnapshotSizeSpinner = (Spinner) findViewById(R.id.snapshot_size_spinner);
225bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mSnapshotSizeSpinner.setOnItemSelectedListener(mSnapshotSizeListener);
226753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mSnapshotSizeSpinner);
227bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
22848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mTakePictureButton = (Button) findViewById(R.id.take_picture);
22948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mTakePictureButton.setOnClickListener(mTakePictureListener);
230abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewOnlyControls.add(mTakePictureButton);
23148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
232bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mCamcorderProfileSpinner = (Spinner) findViewById(R.id.camcorder_profile_spinner);
233bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mCamcorderProfileSpinner.setOnItemSelectedListener(mCamcorderProfileListener);
234753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mCamcorderProfileSpinner);
235bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
2368bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSizeSpinner = (Spinner) findViewById(R.id.video_record_size_spinner);
2378bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSizeSpinner.setOnItemSelectedListener(mVideoRecordSizeListener);
238753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mVideoRecordSizeSpinner);
2398bf3e54287366cf790c25577568334b92f67d178Alex Ray
240410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRateSpinner = (Spinner) findViewById(R.id.video_frame_rate_spinner);
241410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRateSpinner.setOnItemSelectedListener(mVideoFrameRateListener);
242753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mVideoFrameRateSpinner);
243410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
244bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mRecordToggle = (ToggleButton) findViewById(R.id.start_record);
245bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mRecordToggle.setOnClickListener(mRecordToggleListener);
246abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewOnlyControls.add(mRecordToggle);
247bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
248753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mRecordHandoffCheckBox = (CheckBox) findViewById(R.id.record_handoff_checkbox);
249753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
250faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        mRecordStabilizationToggle = (ToggleButton) findViewById(R.id.record_stabilization);
251faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        mRecordStabilizationToggle.setOnClickListener(mRecordStabilizationToggleListener);
252753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mRecordStabilizationToggle);
253faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray
25459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackFormatSpinner = (Spinner) findViewById(R.id.callback_format_spinner);
25559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackFormatSpinner.setOnItemSelectedListener(mCallbackFormatListener);
256753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mCallbackFormatSpinner);
25759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
25859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackToggle = (ToggleButton) findViewById(R.id.enable_callbacks);
25959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackToggle.setOnClickListener(mCallbackToggleListener);
260753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.add(mCallbackToggle);
26159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
262abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mLogView = (TextView) findViewById(R.id.log);
263abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mLogView.setMovementMethod(new ScrollingMovementMethod());
264bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
265753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mOpenOnlyControls.addAll(mPreviewOnlyControls);
266753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
26759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames = new SparseArray<String>(7);
26859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.JPEG, "JPEG");
26959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.NV16, "NV16");
27059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.NV21, "NV21");
27159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.RGB_565, "RGB_565");
27259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.UNKNOWN, "UNKNOWN");
27359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.YUY2, "YUY2");
27459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mFormatNames.append(ImageFormat.YV12, "YV12");
27559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
27648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        int numCameras = Camera.getNumberOfCameras();
277753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        String[] cameraNames = new String[numCameras + 1];
278753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        cameraNames[0] = "None";
27948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        for (int i = 0; i < numCameras; i++) {
280753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            cameraNames[i + 1] = "Camera " + i;
28148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
28248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
28348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mCameraSpinner.setAdapter(
28448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                new ArrayAdapter<String>(this,
28548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                        R.layout.spinner_item, cameraNames));
286753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (numCameras > 0) {
287753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCameraId = 0;
288753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCameraSpinner.setSelection(mCameraId + 1);
289753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        } else {
290753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            resetCamera();
291753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCameraSpinner.setSelection(0);
292753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
29359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
29459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mRS = RenderScript.create(this);
29548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
29648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
29748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    @Override
29848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void onResume() {
29948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        super.onResume();
300753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        log("onResume: Setting up");
30148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewHolder = null;
30248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        setUpCamera();
30348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
30448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
30548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    @Override
30648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void onPause() {
30748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        super.onPause();
308753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mState == CAMERA_RECORD) {
309753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            stopRecording(false);
310753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
311753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mKeepOpenCheckBox.isChecked()) {
312753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            log("onPause: Not releasing camera");
313753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
314753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mState == CAMERA_PREVIEW) {
315753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCamera.stopPreview();
316753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mState = CAMERA_OPEN;
317753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
318753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        } else {
319753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            log("onPause: Releasing camera");
320753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
321753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mCamera != null) {
322753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCamera.release();
323753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
324753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mState = CAMERA_UNINITIALIZED;
325753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
32648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
32748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
328abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    /** SurfaceHolder.Callback methods */
32959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @Override
33048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void surfaceChanged(SurfaceHolder holder,
33148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            int format,
33248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            int width,
33348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            int height) {
33459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (holder == mPreviewView.getHolder()) {
33559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if (mState >= CAMERA_OPEN) {
33659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                final int previewWidth =
33759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        mPreviewSizes.get(mPreviewSize).width;
33859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                final int previewHeight =
33959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        mPreviewSizes.get(mPreviewSize).height;
34059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
34159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                if ( Math.abs((float)previewWidth / previewHeight -
34259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        (float)width/height) > 0.01f) {
34359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    Handler h = new Handler();
34459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    h.post(new Runnable() {
34559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        @Override
34659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        public void run() {
34759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                            layoutPreview();
34859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        }
34959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    });
35059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                }
35159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
35248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
35359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if (mPreviewHolder != null) {
35459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                return;
35559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
35659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            log("Surface holder available: " + width + " x " + height);
35759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mPreviewHolder = holder;
35859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            try {
35959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                if (mCamera != null) {
36059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    mCamera.setPreviewDisplay(holder);
36159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                }
36259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            } catch (IOException e) {
36359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                logE("Unable to set up preview!");
36459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
36559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        } else if (holder == mCallbackView.getHolder()) {
36659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCallbackHolder = holder;
36748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
36848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
36948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
37059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @Override
37148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void surfaceCreated(SurfaceHolder holder) {
37248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
37348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
37448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
37559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @Override
37648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    public void surfaceDestroyed(SurfaceHolder holder) {
377abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewHolder = null;
378abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
37948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
380753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    /** UI controls enable/disable for all open-only controls */
381753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private void enableOpenOnlyControls(boolean enabled) {
382753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        for (View v : mOpenOnlyControls) {
383753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                v.setEnabled(enabled);
384753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
385753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    }
386753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
387753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    /** UI controls enable/disable for all preview-only controls */
388abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private void enablePreviewOnlyControls(boolean enabled) {
389abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        for (View v : mPreviewOnlyControls) {
390abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                v.setEnabled(enabled);
391abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
39248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
39348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
394abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    /** UI listeners */
39548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
39648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
397bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                new AdapterView.OnItemSelectedListener() {
39859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
399bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
40048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                        View view, int pos, long id) {
401753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            int cameraId = pos - 1;
402753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mCameraId != cameraId) {
403753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                resetCamera();
404753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCameraId = cameraId;
405753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mPreviewToggle.setChecked(false);
406bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                setUpCamera();
407bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            }
408bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
40948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
41059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
411abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
4124ae1a87883045d820ffd6e1b8a95c13b1919e00aEino-Ville Talvala
413bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
414bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
415bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
416bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private OnClickListener mInfoButtonListener = new OnClickListener() {
41759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
418bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onClick(View v) {
419753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mCameraId != NO_CAMERA_ID) {
420753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                FragmentManager fm = getFragmentManager();
421753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                InfoDialogFragment infoDialog = new InfoDialogFragment();
422753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                infoDialog.updateInfo(mCameraId, mCamera);
423753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                infoDialog.show(fm, "info_dialog_fragment");
424753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
425bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
426bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
42748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
42848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private AdapterView.OnItemSelectedListener mPreviewSizeListener =
429bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        new AdapterView.OnItemSelectedListener() {
43059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
431bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
432bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                View view, int pos, long id) {
433bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            if (pos == mPreviewSize) return;
434bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            if (mState == CAMERA_PREVIEW) {
43559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                log("Stopping preview and callbacks to switch resolutions");
43659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                stopCallbacks();
437bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                mCamera.stopPreview();
438bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            }
43948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
440bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mPreviewSize = pos;
441bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            int width = mPreviewSizes.get(mPreviewSize).width;
442bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            int height = mPreviewSizes.get(mPreviewSize).height;
443bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mParams.setPreviewSize(width, height);
44448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
445abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Setting preview size to " + width + "x" + height);
446abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
447bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mCamera.setParameters(mParams);
44859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            resizePreview();
44948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
450bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            if (mState == CAMERA_PREVIEW) {
451abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                log("Restarting preview");
452bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                mCamera.startPreview();
453bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            }
454bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
45548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
45659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
457abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
45848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
459bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
460bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
46148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
462b2409d280567130723fde8bc2922a43e2976b074David Braun    private AdapterView.OnItemSelectedListener mPreviewFrameRateListener =
463b2409d280567130723fde8bc2922a43e2976b074David Braun                new AdapterView.OnItemSelectedListener() {
464b2409d280567130723fde8bc2922a43e2976b074David Braun        @Override
465b2409d280567130723fde8bc2922a43e2976b074David Braun        public void onItemSelected(AdapterView<?> parent,
466b2409d280567130723fde8bc2922a43e2976b074David Braun                        View view, int pos, long id) {
467b2409d280567130723fde8bc2922a43e2976b074David Braun            if (pos == mPreviewFrameRate) return;
468b2409d280567130723fde8bc2922a43e2976b074David Braun            mPreviewFrameRate = pos;
469b2409d280567130723fde8bc2922a43e2976b074David Braun            mParams.setPreviewFrameRate(mPreviewFrameRates.get(mPreviewFrameRate));
470b2409d280567130723fde8bc2922a43e2976b074David Braun
471b2409d280567130723fde8bc2922a43e2976b074David Braun            log("Setting preview frame rate to " + ((TextView)view).getText());
472b2409d280567130723fde8bc2922a43e2976b074David Braun
473b2409d280567130723fde8bc2922a43e2976b074David Braun            mCamera.setParameters(mParams);
474b2409d280567130723fde8bc2922a43e2976b074David Braun        }
475b2409d280567130723fde8bc2922a43e2976b074David Braun
476b2409d280567130723fde8bc2922a43e2976b074David Braun        @Override
477b2409d280567130723fde8bc2922a43e2976b074David Braun        public void onNothingSelected(AdapterView<?> parent) {
478b2409d280567130723fde8bc2922a43e2976b074David Braun
479b2409d280567130723fde8bc2922a43e2976b074David Braun        }
480b2409d280567130723fde8bc2922a43e2976b074David Braun    };
481b2409d280567130723fde8bc2922a43e2976b074David Braun
48248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private View.OnClickListener mPreviewToggleListener =
48348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            new View.OnClickListener() {
48459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
48548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onClick(View v) {
48648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            if (mState == CAMERA_TAKE_PICTURE) {
487abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                logE("Can't change preview state while taking picture!");
48848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                return;
48948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            }
49048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            if (mPreviewToggle.isChecked()) {
491abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                log("Starting preview");
49248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mCamera.startPreview();
49348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mState = CAMERA_PREVIEW;
494abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                enablePreviewOnlyControls(true);
49548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            } else {
496abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                log("Stopping preview");
49748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mCamera.stopPreview();
49848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mState = CAMERA_OPEN;
49948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
500abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                enablePreviewOnlyControls(false);
50148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            }
50248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
50348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
50448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
505abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private OnItemSelectedListener mAutofocusModeListener =
506abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                new OnItemSelectedListener() {
50759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
508abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
509abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                        View view, int pos, long id) {
510abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if (pos == mAfMode) return;
511abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
512abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mAfMode = pos;
513abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            String focusMode = mAfModes.get(mAfMode);
514abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Setting focus mode to " + focusMode);
5154c9d0b3b746700dd5398edd65510af1f6db4b752Eino-Ville Talvala            if (focusMode == Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE ||
5164c9d0b3b746700dd5398edd65510af1f6db4b752Eino-Ville Talvala                        focusMode == Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO) {
5174c9d0b3b746700dd5398edd65510af1f6db4b752Eino-Ville Talvala                mCamera.setAutoFocusMoveCallback(mAutofocusMoveCallback);
5184c9d0b3b746700dd5398edd65510af1f6db4b752Eino-Ville Talvala            }
519abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mParams.setFocusMode(focusMode);
520abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
521abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mCamera.setParameters(mParams);
522abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
523abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
52459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
525abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onNothingSelected(AdapterView<?> arg0) {
526abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
527abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
528abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
529abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
530abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private OnClickListener mAutofocusButtonListener =
531abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new View.OnClickListener() {
53259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
533abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onClick(View v) {
534abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Triggering autofocus");
535abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mCamera.autoFocus(mAutofocusCallback);
536abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
537abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
538abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
539abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private OnClickListener mCancelAutofocusButtonListener =
540abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new View.OnClickListener() {
54159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
542abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onClick(View v) {
543abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Cancelling autofocus");
544abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mCamera.cancelAutoFocus();
545abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
546abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
547abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
548abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Camera.AutoFocusCallback mAutofocusCallback =
549abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new Camera.AutoFocusCallback() {
55059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
551abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onAutoFocus(boolean success, Camera camera) {
552abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Autofocus completed: " + (success ? "success" : "failure") );
553abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
554abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
555abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
556abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private Camera.AutoFocusMoveCallback mAutofocusMoveCallback =
557abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new Camera.AutoFocusMoveCallback() {
55859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
559abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onAutoFocusMoving(boolean start, Camera camera) {
560abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Autofocus movement: " + (start ? "starting" : "stopped") );
561abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
562abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
563abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
564b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    private OnItemSelectedListener mFlashModeListener =
565b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray                new OnItemSelectedListener() {
56659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
567b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        public void onItemSelected(AdapterView<?> parent,
568b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray                        View view, int pos, long id) {
569b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            if (pos == mFlashMode) return;
570b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
571b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            mFlashMode = pos;
572b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            String flashMode = mFlashModes.get(mFlashMode);
573b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            log("Setting flash mode to " + flashMode);
574b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            mParams.setFlashMode(flashMode);
575b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray            mCamera.setParameters(mParams);
576b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        }
577b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
57859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
579b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        public void onNothingSelected(AdapterView<?> arg0) {
580b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
581b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        }
582b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    };
583b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
584b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
585bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private AdapterView.OnItemSelectedListener mSnapshotSizeListener =
586abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new AdapterView.OnItemSelectedListener() {
58759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
588bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
589bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                View view, int pos, long id) {
590bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            if (pos == mSnapshotSize) return;
591bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
592bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mSnapshotSize = pos;
593bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            int width = mSnapshotSizes.get(mSnapshotSize).width;
594bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            int height = mSnapshotSizes.get(mSnapshotSize).height;
595abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Setting snapshot size to " + width + " x " + height);
596abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
597bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mParams.setPictureSize(width, height);
598bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
599bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            mCamera.setParameters(mParams);
600bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
601bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
60259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
603abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
604bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
605bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
606bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
607bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
60848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private View.OnClickListener mTakePictureListener =
60948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            new View.OnClickListener() {
61059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
61148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onClick(View v) {
612abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Taking picture");
61348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            if (mState == CAMERA_PREVIEW) {
61448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mState = CAMERA_TAKE_PICTURE;
615abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                enablePreviewOnlyControls(false);
61648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mPreviewToggle.setChecked(false);
61748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
61848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                mCamera.takePicture(mShutterCb, mRawCb, mPostviewCb, mJpegCb);
61948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            } else {
620abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                logE("Can't take picture while not running preview!");
62148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            }
62248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
62348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
62448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
625bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private AdapterView.OnItemSelectedListener mCamcorderProfileListener =
626bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                new AdapterView.OnItemSelectedListener() {
62759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
628bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
629bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala                        View view, int pos, long id) {
63035b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray            if (pos != mCamcorderProfile) {
63135b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray                log("Setting camcorder profile to " + ((TextView)view).getText());
63235b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray                mCamcorderProfile = pos;
63335b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray            }
6348bf3e54287366cf790c25577568334b92f67d178Alex Ray
6358bf3e54287366cf790c25577568334b92f67d178Alex Ray            // Additionally change video recording size to match
6368bf3e54287366cf790c25577568334b92f67d178Alex Ray            mVideoRecordSize = 0; // "default", in case it's not found
6378bf3e54287366cf790c25577568334b92f67d178Alex Ray            int width = mCamcorderProfiles.get(pos).videoFrameWidth;
6388bf3e54287366cf790c25577568334b92f67d178Alex Ray            int height = mCamcorderProfiles.get(pos).videoFrameHeight;
6398bf3e54287366cf790c25577568334b92f67d178Alex Ray            for (int i = 0; i < mVideoRecordSizes.size(); i++) {
6408bf3e54287366cf790c25577568334b92f67d178Alex Ray                Camera.Size s = mVideoRecordSizes.get(i);
6418bf3e54287366cf790c25577568334b92f67d178Alex Ray                if (width == s.width && height == s.height) {
6428bf3e54287366cf790c25577568334b92f67d178Alex Ray                    mVideoRecordSize = i;
6438bf3e54287366cf790c25577568334b92f67d178Alex Ray                    break;
6448bf3e54287366cf790c25577568334b92f67d178Alex Ray                }
6458bf3e54287366cf790c25577568334b92f67d178Alex Ray            }
6468bf3e54287366cf790c25577568334b92f67d178Alex Ray            log("Setting video record size to " + mVideoRecordSize);
6478bf3e54287366cf790c25577568334b92f67d178Alex Ray            mVideoRecordSizeSpinner.setSelection(mVideoRecordSize);
6488bf3e54287366cf790c25577568334b92f67d178Alex Ray        }
6498bf3e54287366cf790c25577568334b92f67d178Alex Ray
65059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
6518bf3e54287366cf790c25577568334b92f67d178Alex Ray        public void onNothingSelected(AdapterView<?> parent) {
6528bf3e54287366cf790c25577568334b92f67d178Alex Ray
6538bf3e54287366cf790c25577568334b92f67d178Alex Ray        }
6548bf3e54287366cf790c25577568334b92f67d178Alex Ray    };
6558bf3e54287366cf790c25577568334b92f67d178Alex Ray
6568bf3e54287366cf790c25577568334b92f67d178Alex Ray    private AdapterView.OnItemSelectedListener mVideoRecordSizeListener =
6578bf3e54287366cf790c25577568334b92f67d178Alex Ray                new AdapterView.OnItemSelectedListener() {
65859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
6598bf3e54287366cf790c25577568334b92f67d178Alex Ray        public void onItemSelected(AdapterView<?> parent,
6608bf3e54287366cf790c25577568334b92f67d178Alex Ray                        View view, int pos, long id) {
6618bf3e54287366cf790c25577568334b92f67d178Alex Ray            if (pos == mVideoRecordSize) return;
6628bf3e54287366cf790c25577568334b92f67d178Alex Ray
6638bf3e54287366cf790c25577568334b92f67d178Alex Ray            log("Setting video record size to " + ((TextView)view).getText());
6648bf3e54287366cf790c25577568334b92f67d178Alex Ray            mVideoRecordSize = pos;
665bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
666bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
66759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
668abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
669bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
670bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
671bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
672bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
673410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    private AdapterView.OnItemSelectedListener mVideoFrameRateListener =
674410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray                new AdapterView.OnItemSelectedListener() {
67559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
676410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        public void onItemSelected(AdapterView<?> parent,
677410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray                        View view, int pos, long id) {
678410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            if (pos == mVideoFrameRate) return;
679410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
680410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            log("Setting video frame rate to " + ((TextView)view).getText());
681410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            mVideoFrameRate = pos;
682410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        }
683410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
68459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
685410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        public void onNothingSelected(AdapterView<?> parent) {
686410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
687410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        }
688410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    };
689410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
690bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private View.OnClickListener mRecordToggleListener =
691abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new View.OnClickListener() {
69259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
693bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        public void onClick(View v) {
694abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mPreviewToggle.setEnabled(false);
695abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if (mState == CAMERA_PREVIEW) {
696abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                startRecording();
697abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            } else if (mState == CAMERA_RECORD) {
698b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                stopRecording(false);
699abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            } else {
700abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                logE("Can't toggle recording in current state!");
701abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
702abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mPreviewToggle.setEnabled(true);
703bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
704bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    };
705bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
706faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray    private View.OnClickListener mRecordStabilizationToggleListener =
707faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            new View.OnClickListener() {
70859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
709faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        public void onClick(View v) {
710faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            boolean on = ((ToggleButton) v).isChecked();
711faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            mParams.setVideoStabilization(on);
71259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
71359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCamera.setParameters(mParams);
714faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        }
715faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray    };
716faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray
71748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera.ShutterCallback mShutterCb = new Camera.ShutterCallback() {
71859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
71948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onShutter() {
720abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Shutter callback received");
72148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
72248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
72348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
72448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera.PictureCallback mRawCb = new Camera.PictureCallback() {
72559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
72648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onPictureTaken(byte[] data, Camera camera) {
727abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Raw callback received");
72848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
72948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
73048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
73148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera.PictureCallback mPostviewCb = new Camera.PictureCallback() {
73259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
73348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onPictureTaken(byte[] data, Camera camera) {
734abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Postview callback received");
73548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
73648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
73748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
73848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    private Camera.PictureCallback mJpegCb = new Camera.PictureCallback() {
73959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
74048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        public void onPictureTaken(byte[] data, Camera camera) {
741abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("JPEG picture callback received");
742bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            FragmentManager fm = getFragmentManager();
743bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            SnapshotDialogFragment snapshotDialog = new SnapshotDialogFragment();
74448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
745b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            snapshotDialog.updateImage(data);
746bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            snapshotDialog.show(fm, "snapshot_dialog_fragment");
74748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
74848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            mPreviewToggle.setEnabled(true);
74948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
75048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala            mState = CAMERA_OPEN;
75148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
75248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    };
75348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
75459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private AdapterView.OnItemSelectedListener mCallbackFormatListener =
75559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            new AdapterView.OnItemSelectedListener() {
75659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        public void onItemSelected(AdapterView<?> parent,
75759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        View view, int pos, long id) {
75859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mPreviewFormat = pos;
75959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
76059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            log("Setting preview format to " +
76159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    mFormatNames.get(mPreviewFormats.get(mPreviewFormat)));
76259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
76359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            switch (mState) {
76459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            case CAMERA_UNINITIALIZED:
76559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                return;
76659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            case CAMERA_OPEN:
76759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                break;
76859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            case CAMERA_PREVIEW:
76959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                if (mCallbacksEnabled) {
77059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    log("Stopping preview and callbacks to switch formats");
77159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    stopCallbacks();
77259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    mCamera.stopPreview();
77359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                }
77459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                break;
77559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            case CAMERA_RECORD:
77659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                logE("Can't update format while recording active");
77759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                return;
77859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
77959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
78059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mParams.setPreviewFormat(mPreviewFormats.get(mPreviewFormat));
78117c9966aeb7dd3bd472e7e9bc70735dee1fc72c8Eino-Ville Talvala            mCamera.setParameters(mParams);
78259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
78359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if (mCallbacksEnabled) {
78459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                if (mState == CAMERA_PREVIEW) {
78559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    mCamera.startPreview();
78659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                }
78759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
78859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
78959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            configureCallbacks(mCallbackView.getWidth(), mCallbackView.getHeight());
79059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
79159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
79259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        public void onNothingSelected(AdapterView<?> parent) {
79359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
79459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
79559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    };
79659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
79759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private View.OnClickListener mCallbackToggleListener =
79859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                new View.OnClickListener() {
79959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        public void onClick(View v) {
80059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if (mCallbacksEnabled) {
80159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                log("Disabling preview callbacks");
80259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                stopCallbacks();
80359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mCallbacksEnabled = false;
80459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                resizePreview();
80559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mCallbackView.setVisibility(View.GONE);
80659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
80759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            } else {
80859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                log("Enabling preview callbacks");
80959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mCallbacksEnabled = true;
81059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                resizePreview();
81159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mCallbackView.setVisibility(View.VISIBLE);
81259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
81359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
81459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    };
81559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
81659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
81748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    // Internal methods
81848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
81948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    void setUpCamera() {
820753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mCameraId == NO_CAMERA_ID) return;
821753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
822abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Setting up camera " + mCameraId);
823abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(1);
824753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
825753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mState < CAMERA_OPEN) {
826753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            log("Opening camera " + mCameraId);
827753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
828753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            try {
829753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCamera = Camera.open(mCameraId);
830753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            } catch (RuntimeException e) {
831753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                logE("Exception opening camera: " + e.getMessage());
832753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                resetCamera();
833753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCameraSpinner.setSelection(0);
834753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                logIndent(-1);
835753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                return;
836753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
837753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mState = CAMERA_OPEN;
83848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
83948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
840753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mCamera.setErrorCallback(this);
84148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mParams = mCamera.getParameters();
842bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
843bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        // Set up preview size selection
844abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
845abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Configuring camera");
846abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(1);
847abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
848abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        updatePreviewSizes(mParams);
849b2409d280567130723fde8bc2922a43e2976b074David Braun        updatePreviewFrameRate(mCameraId);
85059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        updatePreviewFormats(mParams);
851abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        updateAfModes(mParams);
852b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        updateFlashModes(mParams);
853abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        updateSnapshotSizes(mParams);
854abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        updateCamcorderProfile(mCameraId);
8558bf3e54287366cf790c25577568334b92f67d178Alex Ray        updateVideoRecordSize(mCameraId);
856410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        updateVideoFrameRate(mCameraId);
857abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
85835b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray        // Trigger updating video record size to match camcorder profile
85935b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray        mCamcorderProfileSpinner.setSelection(mCamcorderProfile);
86035b1da53ad8a06a062f605b6be83a99df0c3af87Alex Ray
861faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        if (mParams.isVideoStabilizationSupported()) {
862faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            log("Video stabilization is supported");
863faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            mRecordStabilizationToggle.setEnabled(true);
864faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        } else {
865faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            log("Video stabilization not supported");
866faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray            mRecordStabilizationToggle.setEnabled(false);
867faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray        }
868faf0dca8fcd28b16cf984ba26587acbfb915b37fAlex Ray
869b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        if (mParams.isAutoExposureLockSupported()) {
870b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            log("Auto-Exposure locking is supported");
871b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            mExposureLockToggle.setEnabled(true);
872b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        } else {
873b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            log("Auto-Exposure locking is not supported");
874b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            mExposureLockToggle.setEnabled(false);
875b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        }
876b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray
877abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // Update parameters based on above updates
878abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mCamera.setParameters(mParams);
879abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
880abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (mPreviewHolder != null) {
881abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Setting preview display");
882abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            try {
883abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                mCamera.setPreviewDisplay(mPreviewHolder);
884abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            } catch(IOException e) {
885abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                Log.e(TAG, "Unable to set up preview!");
886abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
887abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
888abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
889abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(-1);
890abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
891753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        enableOpenOnlyControls(true);
892abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
89359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        resizePreview();
894abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (mPreviewToggle.isChecked()) {
895abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("Starting preview" );
896abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mCamera.startPreview();
897abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mState = CAMERA_PREVIEW;
898b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        } else {
899b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            mState = CAMERA_OPEN;
900753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            enablePreviewOnlyControls(false);
901abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
902abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(-1);
903abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
904abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
905753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    private void resetCamera() {
906753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mState >= CAMERA_OPEN) {
907753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            log("Closing old camera");
908753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCamera.release();
909753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
910753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mCamera = null;
911753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mCameraId = NO_CAMERA_ID;
912753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mState = CAMERA_UNINITIALIZED;
913753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
914753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        enableOpenOnlyControls(false);
915753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    }
916753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
917abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private void updateAfModes(Parameters params) {
918abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAfModes = params.getSupportedFocusModes();
919abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
920abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAutofocusModeSpinner.setAdapter(
921abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                new ArrayAdapter<String>(this, R.layout.spinner_item,
922abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                        mAfModes.toArray(new String[0])));
923abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
924abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mAfMode = 0;
925abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
926abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        params.setFocusMode(mAfModes.get(mAfMode));
927abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
928abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Setting AF mode to " + mAfModes.get(mAfMode));
929abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
930abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
931b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    private void updateFlashModes(Parameters params) {
932b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray        mFlashModes = params.getSupportedFlashModes();
933b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
934b2409d280567130723fde8bc2922a43e2976b074David Braun        if (mFlashModes != null) {
935b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashModeSpinnerLabel.setVisibility(View.VISIBLE);
936b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashModeSpinner.setVisibility(View.VISIBLE);
937b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashModeSpinner.setAdapter(
938b2409d280567130723fde8bc2922a43e2976b074David Braun                    new ArrayAdapter<String>(this, R.layout.spinner_item,
939b2409d280567130723fde8bc2922a43e2976b074David Braun                            mFlashModes.toArray(new String[0])));
940b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
941b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashMode = 0;
942b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
943b2409d280567130723fde8bc2922a43e2976b074David Braun            params.setFlashMode(mFlashModes.get(mFlashMode));
944b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
945b2409d280567130723fde8bc2922a43e2976b074David Braun            log("Setting Flash mode to " + mFlashModes.get(mFlashMode));
946b2409d280567130723fde8bc2922a43e2976b074David Braun        } else {
947b2409d280567130723fde8bc2922a43e2976b074David Braun            // this camera has no flash
948b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashModeSpinnerLabel.setVisibility(View.GONE);
949b2409d280567130723fde8bc2922a43e2976b074David Braun            mFlashModeSpinner.setVisibility(View.GONE);
950b2409d280567130723fde8bc2922a43e2976b074David Braun        }
951b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray    }
952b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray
953b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray    private View.OnClickListener mExposureLockToggleListener =
954b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            new View.OnClickListener() {
955b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        public void onClick(View v) {
956b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            boolean on = ((ToggleButton) v).isChecked();
957b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            log("Auto-Exposure was " + mParams.getAutoExposureLock());
958b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            mParams.setAutoExposureLock(on);
959b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray            log("Auto-Exposure is now " + mParams.getAutoExposureLock());
960b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray        }
961b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray    };
962b95f05fb03d0e9192926f8d46c02602a8035b721Alex Ray
963abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private void updatePreviewSizes(Camera.Parameters params) {
964abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mPreviewSizes = params.getSupportedPreviewSizes();
96548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
96648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        String[] availableSizeNames = new String[mPreviewSizes.size()];
967bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        int i = 0;
968bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        for (Camera.Size previewSize: mPreviewSizes) {
969bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            availableSizeNames[i++] =
970abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                Integer.toString(previewSize.width) + " x " +
971abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                Integer.toString(previewSize.height);
97248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
97348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewSizeSpinner.setAdapter(
974abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                new ArrayAdapter<String>(
975abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                        this, R.layout.spinner_item, availableSizeNames));
97648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
97748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        mPreviewSize = 0;
97848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
97948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        int width = mPreviewSizes.get(mPreviewSize).width;
98048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        int height = mPreviewSizes.get(mPreviewSize).height;
981abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        params.setPreviewSize(width, height);
982abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Setting preview size to " + width + " x " + height);
983abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
984bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
985b2409d280567130723fde8bc2922a43e2976b074David Braun    private void updatePreviewFrameRate(int cameraId) {
986b2409d280567130723fde8bc2922a43e2976b074David Braun        List<Integer> frameRates = mParams.getSupportedPreviewFrameRates();
987b2409d280567130723fde8bc2922a43e2976b074David Braun        int defaultPreviewFrameRate = mParams.getPreviewFrameRate();
988b2409d280567130723fde8bc2922a43e2976b074David Braun
989b2409d280567130723fde8bc2922a43e2976b074David Braun        List<String> frameRateStrings = new ArrayList<String>();
990b2409d280567130723fde8bc2922a43e2976b074David Braun        mPreviewFrameRates = new ArrayList<Integer>();
991b2409d280567130723fde8bc2922a43e2976b074David Braun
992b2409d280567130723fde8bc2922a43e2976b074David Braun        int currentIndex = 0;
993b2409d280567130723fde8bc2922a43e2976b074David Braun        for (Integer frameRate : frameRates) {
994b2409d280567130723fde8bc2922a43e2976b074David Braun            mPreviewFrameRates.add(frameRate);
995b2409d280567130723fde8bc2922a43e2976b074David Braun            if(frameRate == defaultPreviewFrameRate) {
996b2409d280567130723fde8bc2922a43e2976b074David Braun                frameRateStrings.add(frameRate.toString() + " (Default)");
997b2409d280567130723fde8bc2922a43e2976b074David Braun                mPreviewFrameRate = currentIndex;
998b2409d280567130723fde8bc2922a43e2976b074David Braun            } else {
999b2409d280567130723fde8bc2922a43e2976b074David Braun                frameRateStrings.add(frameRate.toString());
1000b2409d280567130723fde8bc2922a43e2976b074David Braun            }
1001b2409d280567130723fde8bc2922a43e2976b074David Braun            currentIndex++;
1002b2409d280567130723fde8bc2922a43e2976b074David Braun        }
1003b2409d280567130723fde8bc2922a43e2976b074David Braun
1004b2409d280567130723fde8bc2922a43e2976b074David Braun        String[] nameArray = (String[])frameRateStrings.toArray(new String[0]);
1005b2409d280567130723fde8bc2922a43e2976b074David Braun        mPreviewFrameRateSpinner.setAdapter(
1006b2409d280567130723fde8bc2922a43e2976b074David Braun                new ArrayAdapter<String>(
1007b2409d280567130723fde8bc2922a43e2976b074David Braun                        this, R.layout.spinner_item, nameArray));
1008b2409d280567130723fde8bc2922a43e2976b074David Braun
1009b2409d280567130723fde8bc2922a43e2976b074David Braun        mPreviewFrameRateSpinner.setSelection(mPreviewFrameRate);
1010b2409d280567130723fde8bc2922a43e2976b074David Braun        log("Setting preview frame rate to " + nameArray[mPreviewFrameRate]);
1011b2409d280567130723fde8bc2922a43e2976b074David Braun    }
1012b2409d280567130723fde8bc2922a43e2976b074David Braun
101359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private void updatePreviewFormats(Camera.Parameters params) {
101459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewFormats = params.getSupportedPreviewFormats();
101559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
101659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        String[] availableFormatNames = new String[mPreviewFormats.size()];
101759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int i = 0;
101859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        for (Integer previewFormat: mPreviewFormats) {
101959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            availableFormatNames[i++] = mFormatNames.get(previewFormat);
102059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
102159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackFormatSpinner.setAdapter(
102259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                new ArrayAdapter<String>(
102359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        this, R.layout.spinner_item, availableFormatNames));
102459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
102559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewFormat = 0;
102659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbacksEnabled = false;
102759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackToggle.setChecked(false);
102859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackView.setVisibility(View.GONE);
102959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
103059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        params.setPreviewFormat(mPreviewFormats.get(mPreviewFormat));
103159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        log("Setting preview format to " +
103259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mFormatNames.get(mPreviewFormats.get(mPreviewFormat)));
103359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
103459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
1035abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private void updateSnapshotSizes(Camera.Parameters params) {
1036abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        String[] availableSizeNames;
1037abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mSnapshotSizes = params.getSupportedPictureSizes();
1038bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1039bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        availableSizeNames = new String[mSnapshotSizes.size()];
1040abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        int i = 0;
1041bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        for (Camera.Size snapshotSize : mSnapshotSizes) {
1042bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala            availableSizeNames[i++] =
1043abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                Integer.toString(snapshotSize.width) + " x " +
1044abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                Integer.toString(snapshotSize.height);
1045bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
1046bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mSnapshotSizeSpinner.setAdapter(
1047abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                new ArrayAdapter<String>(
1048abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                        this, R.layout.spinner_item, availableSizeNames));
1049bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1050bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mSnapshotSize = 0;
1051bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1052abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        int snapshotWidth = mSnapshotSizes.get(mSnapshotSize).width;
1053abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        int snapshotHeight = mSnapshotSizes.get(mSnapshotSize).height;
1054abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        params.setPictureSize(snapshotWidth, snapshotHeight);
1055abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Setting snapshot size to " + snapshotWidth + " x " + snapshotHeight);
105648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
105748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
1058bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    private void updateCamcorderProfile(int cameraId) {
1059bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        // Have to query all of these individually,
1060bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        final int PROFILES[] = new int[] {
1061abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_1080P,
1062abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_480P,
1063abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_720P,
1064abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_CIF,
1065abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_HIGH,
1066abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_LOW,
1067abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_QCIF,
1068abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_QVGA,
1069abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_1080P,
1070abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_480P,
1071abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_720P,
1072abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
1073abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_HIGH,
1074abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_LOW,
1075abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_QCIF,
1076abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            CamcorderProfile.QUALITY_TIME_LAPSE_QVGA
1077bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        };
1078bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1079bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        final String PROFILE_NAMES[] = new String[] {
1080abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "1080P",
1081abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "480P",
1082abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "720P",
1083abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "CIF",
1084abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "HIGH",
1085abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "LOW",
1086abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "QCIF",
1087abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "QVGA",
1088abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_1080P",
1089abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_480P",
1090abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_720P",
1091abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_CIF",
1092abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_HIGH",
1093abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_LOW",
1094abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_QCIF",
1095abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "TIME_LAPSE_QVGA"
1096bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        };
1097bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1098bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        List<String> availableCamcorderProfileNames = new ArrayList<String>();
1099bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mCamcorderProfiles = new ArrayList<CamcorderProfile>();
1100bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
1101bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        for (int i = 0; i < PROFILES.length; i++) {
1102abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if (CamcorderProfile.hasProfile(cameraId, PROFILES[i])) {
1103abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                availableCamcorderProfileNames.add(PROFILE_NAMES[i]);
1104abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                mCamcorderProfiles.add(CamcorderProfile.get(cameraId, PROFILES[i]));
1105abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
1106bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        }
1107bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        String[] nameArray = (String[])availableCamcorderProfileNames.toArray(new String[0]);
1108bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala        mCamcorderProfileSpinner.setAdapter(
1109abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                new ArrayAdapter<String>(
1110abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                        this, R.layout.spinner_item, nameArray));
1111abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1112abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mCamcorderProfile = 0;
1113abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Setting camcorder profile to " + nameArray[mCamcorderProfile]);
1114abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1115bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala    }
1116bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala
11178bf3e54287366cf790c25577568334b92f67d178Alex Ray    private void updateVideoRecordSize(int cameraId) {
11188bf3e54287366cf790c25577568334b92f67d178Alex Ray        List<Camera.Size> videoSizes = mParams.getSupportedVideoSizes();
11198bf3e54287366cf790c25577568334b92f67d178Alex Ray        if (videoSizes == null) { // TODO: surface this to the user
11208bf3e54287366cf790c25577568334b92f67d178Alex Ray            log("Failed to get video size list, using preview sizes instead");
11218bf3e54287366cf790c25577568334b92f67d178Alex Ray            videoSizes = mParams.getSupportedPreviewSizes();
11228bf3e54287366cf790c25577568334b92f67d178Alex Ray        }
11238bf3e54287366cf790c25577568334b92f67d178Alex Ray
11248bf3e54287366cf790c25577568334b92f67d178Alex Ray        List<String> availableVideoRecordSizes = new ArrayList<String>();
11258bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSizes = new ArrayList<Camera.Size>();
11268bf3e54287366cf790c25577568334b92f67d178Alex Ray
11278bf3e54287366cf790c25577568334b92f67d178Alex Ray        availableVideoRecordSizes.add("Default");
11288bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSizes.add(mCamera.new Size(0,0));
11298bf3e54287366cf790c25577568334b92f67d178Alex Ray
11308bf3e54287366cf790c25577568334b92f67d178Alex Ray        for (Camera.Size s : videoSizes) {
11318bf3e54287366cf790c25577568334b92f67d178Alex Ray              availableVideoRecordSizes.add(s.width + "x" + s.height);
11328bf3e54287366cf790c25577568334b92f67d178Alex Ray              mVideoRecordSizes.add(s);
11338bf3e54287366cf790c25577568334b92f67d178Alex Ray        }
11348bf3e54287366cf790c25577568334b92f67d178Alex Ray        String[] nameArray = (String[])availableVideoRecordSizes.toArray(new String[0]);
11358bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSizeSpinner.setAdapter(
11368bf3e54287366cf790c25577568334b92f67d178Alex Ray                new ArrayAdapter<String>(
11378bf3e54287366cf790c25577568334b92f67d178Alex Ray                        this, R.layout.spinner_item, nameArray));
11388bf3e54287366cf790c25577568334b92f67d178Alex Ray
11398bf3e54287366cf790c25577568334b92f67d178Alex Ray        mVideoRecordSize = 0;
11408bf3e54287366cf790c25577568334b92f67d178Alex Ray        log("Setting video record profile to " + nameArray[mVideoRecordSize]);
11418bf3e54287366cf790c25577568334b92f67d178Alex Ray    }
11428bf3e54287366cf790c25577568334b92f67d178Alex Ray
1143410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    private void updateVideoFrameRate(int cameraId) {
1144410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        // Use preview framerates as video framerates
1145410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        List<Integer> frameRates = mParams.getSupportedPreviewFrameRates();
1146410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
1147410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        List<String> frameRateStrings = new ArrayList<String>();
1148410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRates = new ArrayList<Integer>();
1149410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
1150410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        frameRateStrings.add("Default");
1151410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRates.add(0);
1152410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
1153410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        for (Integer frameRate : frameRates) {
1154410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            frameRateStrings.add(frameRate.toString());
1155410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            mVideoFrameRates.add(frameRate);
1156410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        }
1157410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        String[] nameArray = (String[])frameRateStrings.toArray(new String[0]);
1158410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRateSpinner.setAdapter(
1159410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray                new ArrayAdapter<String>(
1160410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray                        this, R.layout.spinner_item, nameArray));
1161410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
1162410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        mVideoFrameRate = 0;
116359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        log("Setting recording frame rate to " + nameArray[mVideoFrameRate]);
1164410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray    }
1165410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray
116659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    void resizePreview() {
116759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        // Reset preview layout parameters, to trigger layout pass
116859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        // This will eventually call layoutPreview below
116959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        Resources res = getResources();
117059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewView.setLayoutParams(
117159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0,
117259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        mCallbacksEnabled ?
117359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        res.getInteger(R.integer.preview_with_callback_weight):
117459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                        res.getInteger(R.integer.preview_only_weight) ));
117559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
117659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
117759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    void layoutPreview() {
117859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int width = mPreviewSizes.get(mPreviewSize).width;
117959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int height = mPreviewSizes.get(mPreviewSize).height;
118059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        float previewAspect = ((float) width) / height;
118148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
118259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int viewHeight = mPreviewView.getHeight();
118359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int viewWidth = mPreviewView.getWidth();
118459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        float viewAspect = ((float) viewWidth) / viewHeight;
118559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if ( previewAspect > viewAspect) {
118659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            viewHeight = (int) (viewWidth / previewAspect);
118759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        } else {
118859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            viewWidth = (int) (viewHeight * previewAspect);
118959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
119059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mPreviewView.setLayoutParams(
119148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala                new LayoutParams(viewWidth, viewHeight));
119259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
119359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mCallbacksEnabled) {
119459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int callbackHeight = mCallbackView.getHeight();
119559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int callbackWidth = mCallbackView.getWidth();
119659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            float callbackAspect = ((float) callbackWidth) / callbackHeight;
119759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if ( previewAspect > callbackAspect) {
119859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                callbackHeight = (int) (callbackWidth / previewAspect);
119959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            } else {
120059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                callbackWidth = (int) (callbackHeight * previewAspect);
120159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
120259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCallbackView.setLayoutParams(
120359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    new LayoutParams(callbackWidth, callbackHeight));
120459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            configureCallbacks(callbackWidth, callbackHeight);
120548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala        }
120659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
120759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
120859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
120959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private void configureCallbacks(int callbackWidth, int callbackHeight) {
121059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mState >= CAMERA_OPEN && mCallbacksEnabled) {
121159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCamera.setPreviewCallbackWithBuffer(null);
121259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int width = mPreviewSizes.get(mPreviewSize).width;
121359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int height = mPreviewSizes.get(mPreviewSize).height;
121459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int format = mPreviewFormats.get(mPreviewFormat);
121559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
121659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCallbackProcessor = new CallbackProcessor(width, height, format,
121759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    getResources(), mCallbackView,
121859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    callbackWidth, callbackHeight, mRS);
121959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
122059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int size = getCallbackBufferSize(width, height, format);
122159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            log("Configuring callbacks:" + width + " x " + height +
122259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    " , format " + format);
122359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            for (int i = 0; i < CALLBACK_BUFFER_COUNT; i++) {
122459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                mCamera.addCallbackBuffer(new byte[size]);
122559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
122659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCamera.setPreviewCallbackWithBuffer(this);
122759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
122859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mLastCallbackTimestamp = -1;
122959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackFrameCount = 0;
123059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackAvgFrameDuration = 30;
123159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
123259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
123359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    private void stopCallbacks() {
123459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mState >= CAMERA_OPEN) {
123559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCamera.setPreviewCallbackWithBuffer(null);
123659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            if (mCallbackProcessor != null) {
123759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                if (!mCallbackProcessor.stop()) {
123859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    logE("Can't stop preview callback processing!");
123959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                }
124059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            }
124159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
124259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
124359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
124459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @Override
124559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    public void onPreviewFrame(byte[] data, Camera camera) {
124659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        long timestamp = SystemClock.elapsedRealtime();
124759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mLastCallbackTimestamp != -1) {
124859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            long frameDuration = timestamp - mLastCallbackTimestamp;
124959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCallbackAvgFrameDuration =
125059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    mCallbackAvgFrameDuration * MEAN_FPS_HISTORY_COEFF +
125159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    frameDuration * MEAN_FPS_MEASUREMENT_COEFF;
125259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
125359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mLastCallbackTimestamp = timestamp;
125459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mState < CAMERA_PREVIEW || !mCallbacksEnabled) {
125559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            mCamera.addCallbackBuffer(data);
125659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            return;
125759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
125859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackFrameCount++;
125959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        if (mCallbackFrameCount % FPS_REPORTING_PERIOD == 0) {
126059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            log("Got " + FPS_REPORTING_PERIOD + " callback frames, fps "
126159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    + 1e3/mCallbackAvgFrameDuration);
126259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
126359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCallbackProcessor.displayCallback(data);
126448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala
126559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        mCamera.addCallbackBuffer(data);
126648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala    }
1267abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1268753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    @Override
1269753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    public void onError(int error, Camera camera) {
1270753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        String errorName;
1271753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        switch (error) {
1272753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        case Camera.CAMERA_ERROR_SERVER_DIED:
1273753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            errorName = "SERVER_DIED";
1274753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            break;
1275753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        case Camera.CAMERA_ERROR_UNKNOWN:
1276753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            errorName = "UNKNOWN";
1277753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            break;
1278753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        default:
1279753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            errorName = "?";
1280753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            break;
1281753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
1282753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        logE("Camera error received: " + errorName + " (" + error + ")" );
1283753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        logE("Shutting down camera");
1284753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        resetCamera();
1285753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mCameraSpinner.setSelection(0);
1286753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala    }
1287753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1288abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    static final int MEDIA_TYPE_IMAGE = 0;
1289abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    static final int MEDIA_TYPE_VIDEO = 1;
129059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @SuppressLint("SimpleDateFormat")
1291b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    File getOutputMediaFile(int type){
1292abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // To be safe, you should check that the SDCard is mounted
1293abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // using Environment.getExternalStorageState() before doing this.
1294abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1295abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        String state = Environment.getExternalStorageState();
1296abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (!Environment.MEDIA_MOUNTED.equals(state)) {
1297abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                return null;
1298abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1299abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1300abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
1301b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                  Environment.DIRECTORY_DCIM), "TestingCamera");
1302abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // This location works best if you want the created images to be shared
1303abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // between applications and persist after your app has been uninstalled.
1304abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1305abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // Create the storage directory if it does not exist
1306abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (! mediaStorageDir.exists()){
1307abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if (! mediaStorageDir.mkdirs()){
1308abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                logE("Failed to create directory for pictures/video");
1309abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                return null;
1310abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
1311abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1312abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1313abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        // Create a media file name
1314abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
1315abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        File mediaFile;
1316abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (type == MEDIA_TYPE_IMAGE){
1317abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
1318abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "IMG_"+ timeStamp + ".jpg");
1319abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        } else if(type == MEDIA_TYPE_VIDEO) {
1320abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
1321abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            "VID_"+ timeStamp + ".mp4");
1322abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        } else {
1323abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            return null;
1324abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1325abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1326abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        return mediaFile;
1327abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1328abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1329b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    void notifyMediaScannerOfFile(File newFile,
1330b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                final MediaScannerConnection.OnScanCompletedListener listener) {
1331b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        final Handler h = new Handler();
1332b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        MediaScannerConnection.scanFile(this,
1333b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                new String[] { newFile.toString() },
1334b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                null,
1335b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                new MediaScannerConnection.OnScanCompletedListener() {
133659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                    @Override
1337b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                    public void onScanCompleted(final String path, final Uri uri) {
1338b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                        h.post(new Runnable() {
133959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala                            @Override
1340b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                            public void run() {
1341b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                                log("MediaScanner notified: " +
1342b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                                        path + " -> " + uri);
1343b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                                if (listener != null)
1344b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                                    listener.onScanCompleted(path, uri);
1345b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                            }
1346b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                        });
1347b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                    }
1348b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                });
1349b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    }
1350b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala
1351b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    private void deleteFile(File badFile) {
1352b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        if (badFile.exists()) {
1353b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            boolean success = badFile.delete();
1354b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            if (success) log("Deleted file " + badFile.toString());
1355b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            else log("Unable to delete file " + badFile.toString());
1356b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        }
1357b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    }
1358b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala
1359abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private void startRecording() {
1360abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Starting recording");
1361abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(1);
1362abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Configuring MediaRecoder");
1363753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1364753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mRecordHandoffCheckBox.setEnabled(false);
1365753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (mRecordHandoffCheckBox.isChecked()) {
1366753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCamera.release();
1367753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        } else {
1368753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mCamera.unlock();
1369753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
1370753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1371b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        if (mRecorder != null) {
1372b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            mRecorder.release();
1373b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala        }
1374753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1375abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder = new MediaRecorder();
1376abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setOnErrorListener(mRecordingErrorListener);
1377abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setOnInfoListener(mRecordingInfoListener);
1378753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (!mRecordHandoffCheckBox.isChecked()) {
1379753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mRecorder.setCamera(mCamera);
1380753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
1381753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mRecorder.setPreviewDisplay(mPreviewHolder.getSurface());
1382753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1383abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
1384abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
1385abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setProfile(mCamcorderProfiles.get(mCamcorderProfile));
13868bf3e54287366cf790c25577568334b92f67d178Alex Ray        Camera.Size videoRecordSize = mVideoRecordSizes.get(mVideoRecordSize);
13878bf3e54287366cf790c25577568334b92f67d178Alex Ray        if (videoRecordSize.width > 0 && videoRecordSize.height > 0) {
13888bf3e54287366cf790c25577568334b92f67d178Alex Ray            mRecorder.setVideoSize(videoRecordSize.width, videoRecordSize.height);
13898bf3e54287366cf790c25577568334b92f67d178Alex Ray        }
1390410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        if (mVideoFrameRates.get(mVideoFrameRate) > 0) {
1391410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray            mRecorder.setVideoFrameRate(mVideoFrameRates.get(mVideoFrameRate));
1392410aac04ee752c7f3506afb64b4a1e8ab9785cefAlex Ray        }
1393abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        File outputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
1394abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("File name:" + outputFile.toString());
1395abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mRecorder.setOutputFile(outputFile.toString());
1396abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1397abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        boolean ready = false;
1398abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Preparing MediaRecorder");
1399abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        try {
1400abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mRecorder.prepare();
1401abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            ready = true;
1402abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        } catch (Exception e) {
1403abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            StringWriter writer = new StringWriter();
1404abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            e.printStackTrace(new PrintWriter(writer));
1405abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            logE("Exception preparing MediaRecorder:\n" + writer.toString());
1406abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1407abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1408abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (ready) {
1409abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            try {
1410abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                log("Starting MediaRecorder");
1411abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                mRecorder.start();
1412abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                mState = CAMERA_RECORD;
1413abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                log("Recording active");
1414b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                mRecordingFile = outputFile;
1415abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            } catch (Exception e) {
1416abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                StringWriter writer = new StringWriter();
1417abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                e.printStackTrace(new PrintWriter(writer));
1418abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                logE("Exception starting MediaRecorder:\n" + writer.toString());
1419753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                ready = false;
1420753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
1421753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        }
1422753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1423753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        if (!ready) {
1424753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mRecordToggle.setChecked(false);
1425753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            mRecordHandoffCheckBox.setEnabled(true);
1426753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1427753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mRecordHandoffCheckBox.isChecked()) {
1428753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mState = CAMERA_UNINITIALIZED;
1429753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                setUpCamera();
1430abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
1431abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1432abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logIndent(-1);
1433abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1434abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1435abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private MediaRecorder.OnErrorListener mRecordingErrorListener =
1436abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new MediaRecorder.OnErrorListener() {
143759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
1438abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onError(MediaRecorder mr, int what, int extra) {
1439abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            logE("MediaRecorder reports error: " + what + ", extra "
1440abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                    + extra);
1441abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if (mState == CAMERA_RECORD) {
1442b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                stopRecording(true);
1443abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
1444abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1445abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
1446abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1447abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private MediaRecorder.OnInfoListener mRecordingInfoListener =
1448abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            new MediaRecorder.OnInfoListener() {
144959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        @Override
1450abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        public void onInfo(MediaRecorder mr, int what, int extra) {
1451abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            log("MediaRecorder reports info: " + what + ", extra "
1452abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                    + extra);
1453abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1454abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    };
1455abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1456b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    private void stopRecording(boolean error) {
1457abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        log("Stopping recording");
1458753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mRecordHandoffCheckBox.setEnabled(true);
1459753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala        mRecordToggle.setChecked(false);
1460abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (mRecorder != null) {
14611aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar            try {
14621aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar                mRecorder.stop();
14631aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar            } catch (RuntimeException e) {
14641aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar                // this can happen if there were no frames received by recorder
14651aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar                logE("Could not create output file");
14661aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar                error = true;
14671aa04b539399a69710d6b98877655e3bd87920aeLajos Molnar            }
1468753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1469753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            if (mRecordHandoffCheckBox.isChecked()) {
1470753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mState = CAMERA_UNINITIALIZED;
1471753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                setUpCamera();
1472753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            } else {
1473753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mCamera.lock();
1474753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala                mState = CAMERA_PREVIEW;
1475753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala            }
1476753ac7952bbb16004e5dd149dfdbfb70042827ffEino-Ville Talvala
1477b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            if (!error) {
1478b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                notifyMediaScannerOfFile(mRecordingFile, null);
1479b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            } else {
1480b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala                deleteFile(mRecordingFile);
1481b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            }
1482b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala            mRecordingFile = null;
1483abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        } else {
1484abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            logE("Recorder is unexpectedly null!");
1485abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1486abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1487abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
148859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    static int getCallbackBufferSize(int width, int height, int format) {
148959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        int size = -1;
149059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        switch (format) {
149159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.NV21:
149259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            size = width * height * 3 / 2;
149359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            break;
149459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.YV12:
149559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int y_stride = (int) (Math.ceil( width / 16.) * 16);
149659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int y_size = y_stride * height;
149759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int c_stride = (int) (Math.ceil(y_stride / 32.) * 16);
149859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            int c_size = c_stride * height/2;
149959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            size = y_size + c_size * 2;
150059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            break;
150159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.NV16:
150259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.RGB_565:
150359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.YUY2:
150459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            size = 2 * width * height;
150559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            break;
150659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.JPEG:
150759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            Log.e(TAG, "JPEG callback buffers not supported!");
150859c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            size = 0;
150959c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            break;
151059c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        case ImageFormat.UNKNOWN:
151159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            Log.e(TAG, "Unknown-format callback buffers not supported!");
151259c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            size = 0;
151359c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala            break;
151459c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        }
151559c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala        return size;
151659c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    }
151759c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala
1518abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private int mLogIndentLevel = 0;
1519abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    private String mLogIndent = "\t";
1520abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    /** Increment or decrement log indentation level */
1521b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    synchronized void logIndent(int delta) {
1522abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mLogIndentLevel += delta;
1523abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (mLogIndentLevel < 0) mLogIndentLevel = 0;
1524abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        char[] mLogIndentArray = new char[mLogIndentLevel + 1];
1525abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        for (int i = -1; i < mLogIndentLevel; i++) {
1526abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            mLogIndentArray[i + 1] = '\t';
1527abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1528abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mLogIndent = new String(mLogIndentArray);
1529abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1530abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
153159c639e1919e7f7b39758cfbafb1e12b78e7b2d4Eino-Ville Talvala    @SuppressLint("SimpleDateFormat")
1532abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    SimpleDateFormat mDateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
1533abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    /** Log both to log text view and to device logcat */
1534b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    void log(String logLine) {
1535abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        Log.d(TAG, logLine);
1536abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logAndScrollToBottom(logLine, mLogIndent);
1537abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1538abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1539b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    void logE(String logLine) {
1540abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        Log.e(TAG, logLine);
1541abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logAndScrollToBottom(logLine, mLogIndent + "!!! ");
1542abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1543abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala
1544b8dc64f657e9b8aac496379b460c584d958e6919Eino-Ville Talvala    synchronized private void logAndScrollToBottom(String logLine, String logIndent) {
1545abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        StringBuffer logEntry = new StringBuffer(32);
1546abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logEntry.append("\n").append(mDateFormatter.format(new Date())).append(logIndent);
1547abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        logEntry.append(logLine);
1548abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        mLogView.append(logEntry);
1549abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        final Layout layout = mLogView.getLayout();
1550abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        if (layout != null){
1551abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            int scrollDelta = layout.getLineBottom(mLogView.getLineCount() - 1)
1552abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                - mLogView.getScrollY() - mLogView.getHeight();
1553abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            if(scrollDelta > 0) {
1554abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala                mLogView.scrollBy(0, scrollDelta);
1555abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala            }
1556abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala        }
1557abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala    }
1558b18600b1d8df55637a97679f13c26439c35b9efdAlex Ray}
1559