summaryrefslogtreecommitdiffstats
path: root/core/java/android/hardware
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2014-06-17 12:04:07 -0700
committerIgor Murashkin <iam@google.com>2014-06-17 22:55:16 +0000
commit4961bc88d7bab869a5296789d26fcfa31ad5f644 (patch)
tree24fb63dc81e721826259c9d49c1b1dc715d0ec79 /core/java/android/hardware
parent5834ee75038e9095cefe089cdb26795b3ffe9e38 (diff)
downloadframeworks_base-4961bc88d7bab869a5296789d26fcfa31ad5f644.zip
frameworks_base-4961bc88d7bab869a5296789d26fcfa31ad5f644.tar.gz
frameworks_base-4961bc88d7bab869a5296789d26fcfa31ad5f644.tar.bz2
camera2: Map camera characteristics in the managed layer
Change-Id: Ic86c8df3d703e7cf89caa856387e2c0a1b977401
Diffstat (limited to 'core/java/android/hardware')
-rw-r--r--core/java/android/hardware/ICameraService.aidl5
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java104
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java139
-rw-r--r--core/java/android/hardware/camera2/utils/CameraBinderDecorator.java2
4 files changed, 241 insertions, 9 deletions
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 4c50dda..31896f5 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -69,4 +69,9 @@ interface ICameraService
* well-formatted in the generated java method.
*/
int getCameraVendorTagDescriptor(out BinderHolder desc);
+
+ // Writes the camera1 parameters into a single-element array.
+ int getLegacyParameters(int cameraId, out String[] parameters);
+ // Determines if a particular API version is supported; see ICameraService.h for version defines
+ int supportsCameraApi(int cameraId, int apiVersion);
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 0901562..73188ff 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -19,8 +19,10 @@ package android.hardware.camera2;
import android.content.Context;
import android.hardware.ICameraService;
import android.hardware.ICameraServiceListener;
+import android.hardware.CameraInfo;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.legacy.CameraDeviceUserShim;
+import android.hardware.camera2.legacy.LegacyMetadataMapper;
import android.hardware.camera2.utils.CameraBinderDecorator;
import android.hardware.camera2.utils.CameraRuntimeException;
import android.hardware.camera2.utils.BinderHolder;
@@ -57,6 +59,10 @@ public final class CameraManager {
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
private static final int USE_CALLING_UID = -1;
+ @SuppressWarnings("unused")
+ private static final int API_VERSION_1 = 1;
+ private static final int API_VERSION_2 = 2;
+
private final ICameraService mCameraService;
private ArrayList<String> mDeviceIdList;
@@ -142,6 +148,9 @@ public final class CameraManager {
synchronized (mLock) {
mListenerMap.put(listener, handler);
+
+ // TODO: fire the current oldest known state when adding a new listener
+ // (must be done while holding lock)
}
}
@@ -185,16 +194,46 @@ public final class CameraManager {
}
}
- CameraMetadataNative info = new CameraMetadataNative();
- try {
- mCameraService.getCameraCharacteristics(Integer.valueOf(cameraId), info);
- } catch(CameraRuntimeException e) {
- throw e.asChecked();
- } catch(RemoteException e) {
- // impossible
- return null;
+ int id = Integer.valueOf(cameraId);
+
+ /*
+ * Get the camera characteristics from the camera service directly if it supports it,
+ * otherwise get them from the legacy shim instead.
+ */
+
+ if (!supportsCamera2Api(cameraId)) {
+ // Legacy backwards compatibility path; build static info from the camera parameters
+ String[] outParameters = new String[1];
+ try {
+ mCameraService.getLegacyParameters(id, /*out*/outParameters);
+ String parameters = outParameters[0];
+
+ CameraInfo info = new CameraInfo();
+ mCameraService.getCameraInfo(id, /*out*/info);
+
+ return LegacyMetadataMapper.createCharacteristics(parameters, info);
+ } catch (RemoteException e) {
+ // Impossible
+ return null;
+ } catch (CameraRuntimeException e) {
+ throw e.asChecked();
+ }
+
+ } else {
+ // Normal path: Get the camera characteristics directly from the camera service
+ CameraMetadataNative info = new CameraMetadataNative();
+
+ try {
+ mCameraService.getCameraCharacteristics(id, info);
+ } catch(CameraRuntimeException e) {
+ throw e.asChecked();
+ } catch(RemoteException e) {
+ // impossible
+ return null;
+ }
+
+ return new CameraCharacteristics(info);
}
- return new CameraCharacteristics(info);
}
/**
@@ -456,6 +495,53 @@ public final class CameraManager {
}
}
+ /**
+ * Queries the camera service if it supports the camera2 api directly, or needs a shim.
+ *
+ * @param cameraId a non-{@code null} camera identifier
+ * @return {@code false} if the legacy shim needs to be used, {@code true} otherwise.
+ */
+ private boolean supportsCamera2Api(String cameraId) {
+ return supportsCameraApi(cameraId, API_VERSION_2);
+ }
+
+ /**
+ * Queries the camera service if it supports a camera api directly, or needs a shim.
+ *
+ * @param cameraId a non-{@code null} camera identifier
+ * @param apiVersion the version, i.e. {@code API_VERSION_1} or {@code API_VERSION_2}
+ * @return {@code true} if connecting will work for that device version.
+ */
+ private boolean supportsCameraApi(String cameraId, int apiVersion) {
+ int id = Integer.parseInt(cameraId);
+
+ /*
+ * Possible return values:
+ * - NO_ERROR => Camera2 API is supported
+ * - CAMERA_DEPRECATED_HAL => Camera2 API is *not* supported (thrown as an exception)
+ *
+ * Anything else is an unexpected error we don't want to recover from.
+ */
+
+ try {
+ int res = mCameraService.supportsCameraApi(id, apiVersion);
+
+ if (res != CameraBinderDecorator.NO_ERROR) {
+ throw new AssertionError("Unexpected value " + res);
+ }
+
+ return true;
+ } catch (CameraRuntimeException e) {
+ if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
+ return false;
+ } else {
+ throw e;
+ }
+ } catch (RemoteException e) {
+ throw new AssertionError("Camera service unreachable", e);
+ }
+ }
+
// TODO: this class needs unit tests
// TODO: extract class into top level
private class CameraServiceListener extends ICameraServiceListener.Stub {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
new file mode 100644
index 0000000..8bb066f
--- /dev/null
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.legacy;
+
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
+import android.hardware.Camera.Size;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.params.StreamConfiguration;
+import android.hardware.camera2.params.StreamConfigurationDuration;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.android.internal.util.Preconditions.*;
+import static android.hardware.camera2.CameraCharacteristics.*;
+
+/**
+ * Provide legacy-specific implementations of camera2 metadata for legacy devices, such as the
+ * camera characteristics.
+ */
+public class LegacyMetadataMapper {
+ private static final String TAG = "LegacyMetadataMapper";
+ private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+ // from graphics.h
+ private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;
+ private static final int HAL_PIXEL_FORMAT_BLOB = 0x21;
+
+ /**
+ * Create characteristics for a legacy device by mapping the {@code parameters}
+ * and {@code info}
+ *
+ * @param parameters A string parseable by {@link Camera.Parameters#unflatten}
+ * @param info Camera info with camera facing direction and angle of orientation
+ * @return static camera characteristics for a camera device
+ *
+ * @throws NullPointerException if any of the args were {@code null}
+ */
+ public static CameraCharacteristics createCharacteristics(String parameters,
+ android.hardware.CameraInfo info) {
+ checkNotNull(parameters, "parameters must not be null");
+ checkNotNull(info, "info must not be null");
+ checkNotNull(info.info, "info.info must not be null");
+
+ CameraMetadataNative m = new CameraMetadataNative();
+
+ mapCameraInfo(m, info.info);
+
+ Camera.Parameters params = Camera.getEmptyParameters();
+ params.unflatten(parameters);
+ mapCameraParameters(m, params);
+
+ if (VERBOSE) {
+ Log.v(TAG, "createCharacteristics metadata:");
+ Log.v(TAG, "--------------------------------------------------- (start)");
+ m.dumpToLog();
+ Log.v(TAG, "--------------------------------------------------- (end)");
+ }
+
+ return new CameraCharacteristics(m);
+ }
+
+ private static void mapCameraInfo(CameraMetadataNative m, CameraInfo i) {
+ m.set(LENS_FACING, i.facing == CameraInfo.CAMERA_FACING_BACK ?
+ LENS_FACING_BACK : LENS_FACING_FRONT);
+ m.set(SENSOR_ORIENTATION, i.orientation);
+ }
+
+ private static void mapCameraParameters(CameraMetadataNative m, Camera.Parameters p) {
+ mapStreamConfigs(m, p);
+
+ // TODO: map other fields
+ }
+
+ private static void mapStreamConfigs(CameraMetadataNative m, Camera.Parameters p) {
+ // TODO: set non-empty durations
+ m.set(SCALER_AVAILABLE_MIN_FRAME_DURATIONS, new StreamConfigurationDuration[] {} );
+ m.set(SCALER_AVAILABLE_STALL_DURATIONS, new StreamConfigurationDuration[] {} );
+
+ ArrayList<StreamConfiguration> availableStreamConfigs = new ArrayList<>();
+ /*
+ * Implementation-defined (preview, recording, etc) -> use camera1 preview sizes
+ * YUV_420_888 cpu callbacks -> use camera1 preview sizes
+ * Other preview callbacks (CPU) -> use camera1 preview sizes
+ * JPEG still capture -> use camera1 still capture sizes
+ *
+ * Use platform-internal format constants here, since StreamConfigurationMap does the
+ * remapping to public format constants.
+ */
+ List<Size> previewSizes = p.getSupportedPreviewSizes();
+ appendStreamConfig(availableStreamConfigs,
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes);
+ appendStreamConfig(availableStreamConfigs,
+ ImageFormat.YUV_420_888, previewSizes);
+ for (int format : p.getSupportedPreviewFormats()) {
+ if (ImageFormat.isPublicFormat(format)) {
+ appendStreamConfig(availableStreamConfigs, format, previewSizes);
+ } else {
+ /*
+ * Do not add any formats unknown to us
+ * (since it would fail runtime checks in StreamConfigurationMap)
+ */
+ Log.w(TAG,
+ String.format("mapStreamConfigs - Skipping non-public format %x", format));
+ }
+ }
+ appendStreamConfig(availableStreamConfigs,
+ HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes());
+ m.set(SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+ availableStreamConfigs.toArray(new StreamConfiguration[0]));
+ }
+
+ private static void appendStreamConfig(
+ ArrayList<StreamConfiguration> configs, int format, List<Camera.Size> sizes) {
+ for (Camera.Size size : sizes) {
+ StreamConfiguration config =
+ new StreamConfiguration(format, size.width, size.height, /*input*/false);
+ configs.add(config);
+ }
+ }
+}
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index 40cda08..898c746 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -47,6 +47,8 @@ public class CameraBinderDecorator {
* - POLICY_PROHIBITS
* - RESOURCE_BUSY
* - NO_SUCH_DEVICE
+ * - NOT_SUPPORTED
+ * - TOO_MANY_USERS
*/
public static final int EACCES = -13;
public static final int EBUSY = -16;