From c5a4bf269e949441436c6123f313ede43a860a62 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 11 Dec 2013 10:30:48 -0500 Subject: [PATCH] Support camera hardware oreintation offsets --- AndroidManifest.xml | 2 +- .../freeotp/CameraDialogFragment.java | 131 ++++++++++++------ .../fedorahosted/freeotp/MainActivity.java | 25 +--- 3 files changed, 88 insertions(+), 70 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b514f4d..7d9ecc5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -21,7 +21,7 @@ = 0; cameraId--) { + Camera.getCameraInfo(cameraId, mCameraInfo); + if (mCameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) + break; + } + mCameraId = cameraId; + + // Create the decoder thread + mDecodeAsyncTask = new DecodeAsyncTask() { + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + if (result != null) + ((MainActivity) getActivity()).tokenURIReceived(result); + dismiss(); + } + }; } @Override - public void onClick(DialogInterface dialog, int which) { - if (which == AlertDialog.BUTTON_NEUTRAL) { + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // If we have no back facing camera, open the manual dialog + if (mCameraId < 0) { new ManualDialogFragment().show(getFragmentManager(), ManualDialogFragment.FRAGMENT_TAG); + dismiss(); + return; } + + mDecodeAsyncTask.execute(); } @Override - public void onDestroyView() { - if (mDecodeAsyncTask != null) - mDecodeAsyncTask.cancel(true); + public void onDestroy() { + super.onDestroy(); + mDecodeAsyncTask.cancel(true); + } - super.onDestroyView(); + @Override + protected void onViewInflated(View view) { + SurfaceView sv = (SurfaceView) view.findViewById(R.id.camera_surfaceview); + sv.getHolder().addCallback(this); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (which != AlertDialog.BUTTON_NEUTRAL) + return; + + new ManualDialogFragment().show(getFragmentManager(), + ManualDialogFragment.FRAGMENT_TAG); } @Override @@ -73,57 +110,59 @@ public class CameraDialogFragment extends BaseAlertDialogFragment implements Sur if (mCamera == null) return; - WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE); - switch (wm.getDefaultDisplay().getRotation()) { + int rotation = 0; + switch (getActivity().getWindowManager().getDefaultDisplay().getRotation()) { case Surface.ROTATION_0: - mCamera.setDisplayOrientation(90); + rotation = 0; + break; + case Surface.ROTATION_90: + rotation = 90; + break; + case Surface.ROTATION_180: + rotation = 180; break; case Surface.ROTATION_270: - mCamera.setDisplayOrientation(180); + rotation = 270; break; } + mCamera.setDisplayOrientation((mCameraInfo.orientation - rotation + 360) % 360); mCamera.startPreview(); } @Override @TargetApi(14) public void surfaceCreated(SurfaceHolder holder) { + surfaceDestroyed(holder); + try { - mCamera = Camera.open(); + // Open the camera + mCamera = Camera.open(mCameraId); mCamera.setPreviewDisplay(holder); - - // Create the decoder thread - mDecodeAsyncTask = new DecodeAsyncTask() { - @Override - protected void onPostExecute(String result) { - super.onPostExecute(result); - if (result != null) - ((MainActivity) getActivity()).tokenURIReceived(result); - mDecodeAsyncTask = null; - dismiss(); - } - }; - mDecodeAsyncTask.execute(); mCamera.setPreviewCallback(mDecodeAsyncTask); - - // Set auto-focus mode - Parameters params = mCamera.getParameters(); - List modes = params.getSupportedFocusModes(); - if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) - params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); - else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) - params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); - else if (modes.contains(Parameters.FOCUS_MODE_AUTO)) - params.setFocusMode(Parameters.FOCUS_MODE_AUTO); - mCamera.setParameters(params); } catch (Exception e) { - SurfaceView sv = (SurfaceView) getDialog().findViewById(R.id.camera_surfaceview); + e.printStackTrace(); + surfaceDestroyed(holder); + + // Show error message + Dialog d = getDialog(); + SurfaceView sv = (SurfaceView) d.findViewById(R.id.camera_surfaceview); + TextView tv = (TextView) d.findViewById(R.id.camera_textview); sv.setVisibility(View.INVISIBLE); - TextView tv = (TextView) getDialog().findViewById(R.id.camera_textview); tv.setVisibility(View.VISIBLE); - e.printStackTrace(); + return; } + + // Set auto-focus mode + Parameters params = mCamera.getParameters(); + List modes = params.getSupportedFocusModes(); + if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) + params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) + params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + else if (modes.contains(Parameters.FOCUS_MODE_AUTO)) + params.setFocusMode(Parameters.FOCUS_MODE_AUTO); + mCamera.setParameters(params); } @Override diff --git a/src/org/fedorahosted/freeotp/MainActivity.java b/src/org/fedorahosted/freeotp/MainActivity.java index efcdae3..0a65fc4 100644 --- a/src/org/fedorahosted/freeotp/MainActivity.java +++ b/src/org/fedorahosted/freeotp/MainActivity.java @@ -40,10 +40,7 @@ import org.fedorahosted.freeotp.Token.TokenUriInvalidException; import org.fedorahosted.freeotp.adapters.TokenAdapter; import android.app.Activity; -import android.content.pm.PackageManager; import android.database.DataSetObserver; -import android.hardware.Camera; -import android.hardware.Camera.CameraInfo; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; @@ -96,26 +93,8 @@ public class MainActivity extends Activity implements OnMenuItemClickListener { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.action_add: - // Look for a back-facing camera. - boolean backCamera = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); - - // If the above method doesn't return a camera, try to work around it. - // Some buggy implementations return false above even when there is a camera. - for (int i = Camera.getNumberOfCameras() - 1; i >= 0 && !backCamera; i--) { - CameraInfo ci = new CameraInfo(); - Camera.getCameraInfo(i, ci); - backCamera = ci.facing == CameraInfo.CAMERA_FACING_BACK; - } - - // If the device has a camera available, try to scan for QR code - if (backCamera) { - new CameraDialogFragment().show(getFragmentManager(), - CameraDialogFragment.FRAGMENT_TAG); - } else { - new ManualDialogFragment().show(getFragmentManager(), - ManualDialogFragment.FRAGMENT_TAG); - } - + new CameraDialogFragment().show(getFragmentManager(), + CameraDialogFragment.FRAGMENT_TAG); return true; case R.id.action_about: -- 2.43.2