Add camera characteristics checker

Those classes consist of 1 abstract class, which provide a factory for
2 classes each of which implements different behaviors according to
the Android API version.
This commit is contained in:
jif 2018-03-01 18:35:45 +01:00
parent 32601baf5c
commit b419b78c94
3 changed files with 182 additions and 0 deletions

View File

@ -0,0 +1,20 @@
package org.fdroid.fdroid.views.swap.device.camera;
import android.content.Context;
public abstract class CameraCharacteristicsChecker {
public static CameraCharacteristicsChecker getInstance(final Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
return new CameraCharacteristicsMinApiLevel21(context);
} else
return new CameraCharacteristicsMaxApiLevel20();
}
public abstract boolean hasAutofocus();
class FDroidDeviceException extends Exception {
FDroidDeviceException(final String message, final Throwable cause) {
super(message, cause);
}
}
}

View File

@ -0,0 +1,50 @@
package org.fdroid.fdroid.views.swap.device.camera;
import android.hardware.Camera;
import android.util.Log;
import java.util.List;
public class CameraCharacteristicsMaxApiLevel20 extends CameraCharacteristicsChecker {
private static final String TAG = "CameraCharMaxApiLevel20";
protected CameraCharacteristicsMaxApiLevel20() {
}
@Override
public boolean hasAutofocus() {
boolean hasAutofocus = false;
try {
hasAutofocus = hasDeviceAutofocusCapability();
} catch (FDroidDeviceException e) {
Log.e(TAG, e.getMessage(), e);
}
return hasAutofocus;
}
private boolean hasDeviceAutofocusCapability() throws FDroidDeviceException {
try {
final int numberOfCameras = Camera.getNumberOfCameras();
if (numberOfCameras == 0) {
Log.i(TAG, "No camera on device");
return false;
}
boolean hasAutofocus = false;
for (int cameraId = 0; cameraId < numberOfCameras; cameraId++) {
Camera camera = Camera.open(cameraId);
Camera.Parameters parameters = camera.getParameters();
List<String> availableAFModes = parameters.getSupportedFocusModes();
hasAutofocus = availableAFModes.contains(Camera.Parameters.FOCUS_MODE_AUTO);
}
return hasAutofocus;
} catch (Exception e) {
String msg = "Exception accessing device camera";
Log.e(TAG, msg, e);
throw new FDroidDeviceException(msg, e);
}
}
}

View File

@ -0,0 +1,112 @@
package org.fdroid.fdroid.views.swap.device.camera;
import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.Log;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class CameraCharacteristicsMinApiLevel21 extends CameraCharacteristicsChecker {
private static final String TAG = "CameraCharMinApiLevel21";
final private CameraManager cameraManager;
protected CameraCharacteristicsMinApiLevel21(final Context context) {
this.cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
}
@Override
public boolean hasAutofocus() {
boolean hasAutofocus = false;
try {
hasAutofocus = hasDeviceAutofocus();
} catch (FDroidDeviceException e) {
Log.e(TAG, e.getMessage(), e);
}
return hasAutofocus;
}
private boolean hasDeviceAutofocus() throws FDroidDeviceException {
try {
boolean deviceHasAutofocus = false;
final String[] cameraIdList = getCameraIdList();
for (final String cameraId : cameraIdList) {
if (isLensFacingBack(cameraId)) {
deviceHasAutofocus = testAutofocusModeForCamera(cameraId);
break;
}
}
return deviceHasAutofocus;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
throw new FDroidDeviceException("Exception accessing the camera list", e);
}
}
@NonNull
private String[] getCameraIdList() throws FDroidDeviceException {
try {
return cameraManager.getCameraIdList();
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage(), e);
throw new FDroidDeviceException("Exception accessing the camera list", e);
}
}
private boolean isLensFacingBack(final String cameraId) throws FDroidDeviceException {
final Integer lensFacing = getCameraCharacteristics(cameraId).get(CameraCharacteristics.LENS_FACING);
return lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK;
}
@NonNull
private CameraCharacteristics getCameraCharacteristics(final String cameraId) throws FDroidDeviceException {
try {
return cameraManager.getCameraCharacteristics(cameraId);
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage(), e);
throw new FDroidDeviceException("Exception accessing the camera id = " + cameraId, e);
}
}
private boolean testAutofocusModeForCamera(final String cameraId) throws FDroidDeviceException {
try {
boolean hasAutofocusMode = false;
final int[] autoFocusModes = getAvailableAFModes(cameraId);
if (autoFocusModes != null) {
hasAutofocusMode = testAvailableMode(autoFocusModes);
}
return hasAutofocusMode;
} catch (FDroidDeviceException e) {
Log.e(TAG, e.getMessage(), e);
throw new FDroidDeviceException("Exception accessing the camera id = " + cameraId, e);
}
}
private int[] getAvailableAFModes(final String cameraId) throws FDroidDeviceException {
return getCameraCharacteristics(cameraId).get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
}
private boolean testAvailableMode(final int[] autoFocusModes) {
boolean hasAutofocusMode = false;
for (final int mode : autoFocusModes) {
boolean afMode = isAutofocus(mode);
hasAutofocusMode |= afMode;
}
return hasAutofocusMode;
}
private boolean isAutofocus(final int mode) {
return mode != android.hardware.camera2.CameraMetadata.CONTROL_AF_MODE_OFF;
}
}