4 * Authors: Nathaniel McCallum <npmccallum@redhat.com>
6 * Copyright (C) 2013 Nathaniel McCallum, Red Hat
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 package org.fedorahosted.freeotp;
23 import java.util.List;
25 import android.annotation.TargetApi;
26 import android.app.AlertDialog;
27 import android.app.Dialog;
28 import android.content.DialogInterface;
29 import android.hardware.Camera;
30 import android.hardware.Camera.CameraInfo;
31 import android.hardware.Camera.Parameters;
32 import android.os.Bundle;
33 import android.view.Surface;
34 import android.view.SurfaceHolder;
35 import android.view.SurfaceView;
36 import android.view.View;
37 import android.widget.TextView;
39 public class CameraDialogFragment extends BaseAlertDialogFragment implements SurfaceHolder.Callback {
40 public static final String FRAGMENT_TAG = "fragment_camera";
42 private final CameraInfo mCameraInfo = new CameraInfo();
43 private final DecodeAsyncTask mDecodeAsyncTask;
44 private final int mCameraId;
45 private Camera mCamera;
47 public CameraDialogFragment() {
48 super(R.string.scan_qr_code, R.layout.camera,
49 android.R.string.cancel, R.string.manual_entry, 0);
51 // Find a back-facing camera
53 for (cameraId = Camera.getNumberOfCameras() - 1; cameraId >= 0; cameraId--) {
54 Camera.getCameraInfo(cameraId, mCameraInfo);
55 if (mCameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
60 // Create the decoder thread
61 mDecodeAsyncTask = new DecodeAsyncTask() {
63 protected void onPostExecute(String result) {
64 super.onPostExecute(result);
66 ((MainActivity) getActivity()).tokenURIReceived(result);
73 public void onCreate(Bundle savedInstanceState) {
74 super.onCreate(savedInstanceState);
76 // If we have no back facing camera, open the manual dialog
78 new ManualDialogFragment().show(getFragmentManager(),
79 ManualDialogFragment.FRAGMENT_TAG);
84 mDecodeAsyncTask.execute();
88 public void onDestroy() {
90 mDecodeAsyncTask.cancel(true);
94 protected void onViewInflated(View view) {
95 SurfaceView sv = (SurfaceView) view.findViewById(R.id.camera_surfaceview);
96 sv.getHolder().addCallback(this);
100 public void onClick(DialogInterface dialog, int which) {
101 if (which != AlertDialog.BUTTON_NEUTRAL)
104 new ManualDialogFragment().show(getFragmentManager(),
105 ManualDialogFragment.FRAGMENT_TAG);
109 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
114 switch (getActivity().getWindowManager().getDefaultDisplay().getRotation()) {
115 case Surface.ROTATION_0:
118 case Surface.ROTATION_90:
121 case Surface.ROTATION_180:
124 case Surface.ROTATION_270:
129 mCamera.setDisplayOrientation((mCameraInfo.orientation - rotation + 360) % 360);
130 mCamera.startPreview();
135 public void surfaceCreated(SurfaceHolder holder) {
136 surfaceDestroyed(holder);
140 mCamera = Camera.open(mCameraId);
141 mCamera.setPreviewDisplay(holder);
142 mCamera.setPreviewCallback(mDecodeAsyncTask);
143 } catch (Exception e) {
145 surfaceDestroyed(holder);
147 // Show error message
148 Dialog d = getDialog();
149 SurfaceView sv = (SurfaceView) d.findViewById(R.id.camera_surfaceview);
150 TextView tv = (TextView) d.findViewById(R.id.camera_textview);
151 sv.setVisibility(View.INVISIBLE);
152 tv.setVisibility(View.VISIBLE);
156 // Set auto-focus mode
157 Parameters params = mCamera.getParameters();
158 List<String> modes = params.getSupportedFocusModes();
159 if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
160 params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
161 else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
162 params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
163 else if (modes.contains(Parameters.FOCUS_MODE_AUTO))
164 params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
165 mCamera.setParameters(params);
169 public void surfaceDestroyed(SurfaceHolder holder) {
173 mCamera.stopPreview();
174 mCamera.setPreviewCallback(null);