Merge "Camera2: Switch to auto-gen C++ binder interfaces" into nyc-dev am: 74989b4d3f
am: 72071de87c
* commit '72071de87c62717cc85937b319df8df10cf4b7e9':
Camera2: Switch to auto-gen C++ binder interfaces
diff --git a/Android.mk b/Android.mk
index b29a153..c344879 100644
--- a/Android.mk
+++ b/Android.mk
@@ -150,14 +150,14 @@
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
core/java/android/database/IContentObserver.aidl \
- core/java/android/hardware/ICameraService.aidl \
- core/java/android/hardware/ICameraServiceListener.aidl \
- core/java/android/hardware/ICameraServiceProxy.aidl \
- core/java/android/hardware/ICamera.aidl \
- core/java/android/hardware/ICameraClient.aidl \
+ ../av/camera/aidl/android/hardware/ICameraService.aidl \
+ ../av/camera/aidl/android/hardware/ICameraServiceListener.aidl \
+ ../av/camera/aidl/android/hardware/ICameraServiceProxy.aidl \
+ ../av/camera/aidl/android/hardware/ICamera.aidl \
+ ../av/camera/aidl/android/hardware/ICameraClient.aidl \
+ ../av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl \
+ ../av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
core/java/android/hardware/IConsumerIrService.aidl \
- core/java/android/hardware/camera2/ICameraDeviceUser.aidl \
- core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
core/java/android/hardware/ISerialManager.aidl \
core/java/android/hardware/display/IDisplayManager.aidl \
core/java/android/hardware/display/IDisplayManagerCallback.aidl \
@@ -455,6 +455,10 @@
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
frameworks/native/aidl/binder
+LOCAL_AIDL_INCLUDES += \
+ frameworks/av/camera/aidl \
+ frameworks/native/aidl/gui
+
LOCAL_INTERMEDIATE_SOURCES := \
$(framework_res_source_path)/android/R.java \
$(framework_res_source_path)/android/Manifest.java \
@@ -575,7 +579,7 @@
frameworks/base/core/java/android/view/Display.aidl \
frameworks/base/core/java/android/view/InputDevice.aidl \
frameworks/base/core/java/android/view/InputEvent.aidl \
- frameworks/base/core/java/android/view/Surface.aidl \
+ frameworks/native/aidl/gui/android/view/Surface.aidl \
frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
frameworks/base/core/java/android/view/inputmethod/InputMethodSubtype.aidl \
frameworks/base/core/java/android/view/inputmethod/CursorAnchorInfo.aidl \
diff --git a/core/java/android/hardware/CameraInfo.aidl b/core/java/android/hardware/CameraInfo.aidl
deleted file mode 100644
index e21e694..0000000
--- a/core/java/android/hardware/CameraInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/** @hide */
-parcelable CameraInfo;
diff --git a/core/java/android/hardware/ICamera.aidl b/core/java/android/hardware/ICamera.aidl
deleted file mode 100644
index d4f64f8..0000000
--- a/core/java/android/hardware/ICamera.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/** @hide */
-interface ICamera
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICamera.h
- */
- void disconnect();
-}
diff --git a/core/java/android/hardware/ICameraClient.aidl b/core/java/android/hardware/ICameraClient.aidl
deleted file mode 100644
index d7877b4..0000000
--- a/core/java/android/hardware/ICameraClient.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/** @hide */
-interface ICameraClient
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraClient.h
- */
- // TODO: consider implementing this.
-}
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
deleted file mode 100644
index 0b165cd..0000000
--- a/core/java/android/hardware/ICameraService.aidl
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.hardware.ICamera;
-import android.hardware.ICameraClient;
-import android.hardware.camera2.ICameraDeviceUser;
-import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.utils.BinderHolder;
-import android.hardware.ICameraServiceListener;
-import android.hardware.CameraInfo;
-
-/**
- * Binder interface for the native camera service running in mediaserver.
- *
- * @hide
- */
-interface ICameraService
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraService.h
- */
- int getNumberOfCameras(int type);
-
- // rest of 'int' return values in this file are actually status_t
-
- int getCameraInfo(int cameraId, out CameraInfo info);
-
- int connect(ICameraClient client, int cameraId,
- String opPackageName,
- int clientUid,
- // Container for an ICamera object
- out BinderHolder device);
-
- int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
- String opPackageName,
- int clientUid,
- // Container for an ICameraDeviceUser object
- out BinderHolder device);
-
- int addListener(ICameraServiceListener listener);
- int removeListener(ICameraServiceListener listener);
-
- int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
-
- /**
- * The java stubs for this method are not intended to be used. Please use
- * the native stub in frameworks/av/include/camera/ICameraService.h instead.
- * The BinderHolder output is being used as a placeholder, and will not be
- * 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);
-
- int connectLegacy(ICameraClient client, int cameraId,
- int halVersion,
- String opPackageName,
- int clientUid,
- // Container for an ICamera object
- out BinderHolder device);
-
- int setTorchMode(String CameraId, boolean enabled, IBinder clientBinder);
-
- /**
- * Notify the camera service of a system event. Should only be called from system_server.
- *
- * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
- */
- oneway void notifySystemEvent(int eventId, in int[] args);
-}
diff --git a/core/java/android/hardware/ICameraServiceListener.aidl b/core/java/android/hardware/ICameraServiceListener.aidl
deleted file mode 100644
index 49278b6..0000000
--- a/core/java/android/hardware/ICameraServiceListener.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/** @hide */
-interface ICameraServiceListener
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraServiceListener.h
- */
- void onStatusChanged(int status, int cameraId);
-
- void onTorchStatusChanged(int status, String cameraId);
-}
diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl
deleted file mode 100644
index 0e654d5..0000000
--- a/core/java/android/hardware/ICameraServiceProxy.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-/**
- * Binder interface for the camera service proxy running in system_server.
- *
- * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
- *
- * @hide
- */
-interface ICameraServiceProxy
-{
- /**
- * Ping the service proxy to update the valid users for the camera service.
- */
- oneway void pingForUserUpdate();
-
- /**
- * Update the status of a camera device
- */
- oneway void notifyCameraState(String cameraId, int newCameraState);
-}
diff --git a/core/java/android/hardware/camera2/CameraAccessException.java b/core/java/android/hardware/camera2/CameraAccessException.java
index 933ce0d..f9b659c 100644
--- a/core/java/android/hardware/camera2/CameraAccessException.java
+++ b/core/java/android/hardware/camera2/CameraAccessException.java
@@ -114,12 +114,12 @@
}
public CameraAccessException(@AccessError int problem, String message) {
- super(message);
+ super(getCombinedMessage(problem, message));
mReason = problem;
}
public CameraAccessException(@AccessError int problem, String message, Throwable cause) {
- super(message, cause);
+ super(getCombinedMessage(problem, message), cause);
mReason = problem;
}
@@ -151,4 +151,37 @@
}
return null;
}
+
+ private static String getCombinedMessage(@AccessError int problem, String message) {
+ String problemString = getProblemString(problem);
+ return String.format("%s (%d): %s", problemString, problem, message);
+ }
+
+ private static String getProblemString(int problem) {
+ String problemString;
+ switch (problem) {
+ case CAMERA_IN_USE:
+ problemString = "CAMERA_IN_USE";
+ break;
+ case MAX_CAMERAS_IN_USE:
+ problemString = "MAX_CAMERAS_IN_USE";
+ break;
+ case CAMERA_DISCONNECTED:
+ problemString = "CAMERA_DISCONNECTED";
+ break;
+ case CAMERA_DISABLED:
+ problemString = "CAMERA_DISABLED";
+ break;
+ case CAMERA_ERROR:
+ problemString = "CAMERA_ERROR";
+ break;
+ case CAMERA_DEPRECATED_HAL:
+ problemString = "CAMERA_DEPRECATED_HAL";
+ break;
+ default:
+ problemString = "<UNKNOWN ERROR>";
+ }
+ return problemString;
+ }
+
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 51796eb..b3c8e3b 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -26,15 +26,14 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.legacy.CameraDeviceUserShim;
import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.hardware.camera2.utils.CameraServiceBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.BinderHolder;
import android.os.IBinder;
import android.os.Binder;
+import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.ArrayMap;
@@ -240,25 +239,19 @@
if (!supportsCamera2ApiLocked(cameraId)) {
// Legacy backwards compatibility path; build static info from the camera
// parameters
- String[] outParameters = new String[1];
+ String parameters = cameraService.getLegacyParameters(id);
- cameraService.getLegacyParameters(id, /*out*/outParameters);
- String parameters = outParameters[0];
-
- CameraInfo info = new CameraInfo();
- cameraService.getCameraInfo(id, /*out*/info);
+ CameraInfo info = cameraService.getCameraInfo(id);
characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info);
} else {
// Normal path: Get the camera characteristics directly from the camera service
- CameraMetadataNative info = new CameraMetadataNative();
-
- cameraService.getCameraCharacteristics(id, info);
+ CameraMetadataNative info = cameraService.getCameraCharacteristics(id);
characteristics = new CameraCharacteristics(info);
}
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
+ } catch (ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
// Camera service died - act as if the camera was disconnected
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -292,85 +285,83 @@
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
- try {
- synchronized (mLock) {
+ synchronized (mLock) {
- ICameraDeviceUser cameraUser = null;
+ ICameraDeviceUser cameraUser = null;
- android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
- new android.hardware.camera2.impl.CameraDeviceImpl(
- cameraId,
- callback,
- handler,
- characteristics);
+ android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
+ new android.hardware.camera2.impl.CameraDeviceImpl(
+ cameraId,
+ callback,
+ handler,
+ characteristics);
- BinderHolder holder = new BinderHolder();
+ ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
- ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
- int id = Integer.parseInt(cameraId);
- try {
- if (supportsCamera2ApiLocked(cameraId)) {
- // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
- ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
- if (cameraService == null) {
- throw new CameraRuntimeException(
- CameraAccessException.CAMERA_DISCONNECTED,
- "Camera service is currently unavailable");
- }
- cameraService.connectDevice(callbacks, id,
- mContext.getOpPackageName(), USE_CALLING_UID, holder);
- cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
- } else {
- // Use legacy camera implementation for HAL1 devices
- Log.i(TAG, "Using legacy camera HAL.");
- cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
- }
- } catch (CameraRuntimeException e) {
- if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
- throw new AssertionError("Should've gone down the shim path");
- } else if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
- e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE ||
- e.getReason() == CameraAccessException.CAMERA_DISABLED ||
- e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
- e.getReason() == CameraAccessException.CAMERA_ERROR) {
- // Received one of the known connection errors
- // The remote camera device cannot be connected to, so
- // set the local camera to the startup error state
- deviceImpl.setRemoteFailure(e);
-
- if (e.getReason() == CameraAccessException.CAMERA_DISABLED ||
- e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
- e.getReason() == CameraAccessException.CAMERA_IN_USE) {
- // Per API docs, these failures call onError and throw
- throw e.asChecked();
- }
- } else {
- // Unexpected failure - rethrow
- throw e;
- }
- } catch (RemoteException e) {
- // Camera service died - act as if it's a CAMERA_DISCONNECTED case
- CameraRuntimeException ce = new CameraRuntimeException(
- CameraAccessException.CAMERA_DISCONNECTED,
- "Camera service is currently unavailable", e);
- deviceImpl.setRemoteFailure(ce);
- throw ce.asChecked();
- }
-
- // TODO: factor out callback to be non-nested, then move setter to constructor
- // For now, calling setRemoteDevice will fire initial
- // onOpened/onUnconfigured callbacks.
- deviceImpl.setRemoteDevice(cameraUser);
- device = deviceImpl;
+ int id;
+ try {
+ id = Integer.parseInt(cameraId);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
+ + cameraId);
}
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
- + cameraId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
+ try {
+ if (supportsCamera2ApiLocked(cameraId)) {
+ // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
+ ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
+ if (cameraService == null) {
+ throw new ServiceSpecificException(
+ ICameraService.ERROR_DISCONNECTED,
+ "Camera service is currently unavailable");
+ }
+ cameraUser = cameraService.connectDevice(callbacks, id,
+ mContext.getOpPackageName(), USE_CALLING_UID);
+ } else {
+ // Use legacy camera implementation for HAL1 devices
+ Log.i(TAG, "Using legacy camera HAL.");
+ cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
+ }
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
+ throw new AssertionError("Should've gone down the shim path");
+ } else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE ||
+ e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE ||
+ e.errorCode == ICameraService.ERROR_DISABLED ||
+ e.errorCode == ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode == ICameraService.ERROR_INVALID_OPERATION) {
+ // Received one of the known connection errors
+ // The remote camera device cannot be connected to, so
+ // set the local camera to the startup error state
+ deviceImpl.setRemoteFailure(e);
+
+ if (e.errorCode == ICameraService.ERROR_DISABLED ||
+ e.errorCode == ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {
+ // Per API docs, these failures call onError and throw
+ throwAsPublicException(e);
+ }
+ } else {
+ // Unexpected failure - rethrow
+ throwAsPublicException(e);
+ }
+ } catch (RemoteException e) {
+ // Camera service died - act as if it's a CAMERA_DISCONNECTED case
+ ServiceSpecificException sse = new ServiceSpecificException(
+ ICameraService.ERROR_DISCONNECTED,
+ "Camera service is currently unavailable");
+ deviceImpl.setRemoteFailure(sse);
+ throwAsPublicException(sse);
+ }
+
+ // TODO: factor out callback to be non-nested, then move setter to constructor
+ // For now, calling setRemoteDevice will fire initial
+ // onOpened/onUnconfigured callbacks.
+ deviceImpl.setRemoteDevice(cameraUser);
+ device = deviceImpl;
}
+
return device;
}
@@ -602,6 +593,56 @@
}
/**
+ * Convert ServiceSpecificExceptions and Binder RemoteExceptions from camera binder interfaces
+ * into the correct public exceptions.
+ *
+ * @hide
+ */
+ public static void throwAsPublicException(Throwable t) throws CameraAccessException {
+ if (t instanceof ServiceSpecificException) {
+ ServiceSpecificException e = (ServiceSpecificException) t;
+ int reason = CameraAccessException.CAMERA_ERROR;
+ switch(e.errorCode) {
+ case ICameraService.ERROR_DISCONNECTED:
+ reason = CameraAccessException.CAMERA_DISCONNECTED;
+ break;
+ case ICameraService.ERROR_DISABLED:
+ reason = CameraAccessException.CAMERA_DISABLED;
+ break;
+ case ICameraService.ERROR_CAMERA_IN_USE:
+ reason = CameraAccessException.CAMERA_IN_USE;
+ break;
+ case ICameraService.ERROR_MAX_CAMERAS_IN_USE:
+ reason = CameraAccessException.MAX_CAMERAS_IN_USE;
+ break;
+ case ICameraService.ERROR_DEPRECATED_HAL:
+ reason = CameraAccessException.CAMERA_DEPRECATED_HAL;
+ break;
+ case ICameraService.ERROR_ILLEGAL_ARGUMENT:
+ case ICameraService.ERROR_ALREADY_EXISTS:
+ throw new IllegalArgumentException(e.getMessage(), e);
+ case ICameraService.ERROR_PERMISSION_DENIED:
+ throw new SecurityException(e.getMessage(), e);
+ case ICameraService.ERROR_TIMED_OUT:
+ case ICameraService.ERROR_INVALID_OPERATION:
+ default:
+ reason = CameraAccessException.CAMERA_ERROR;
+ }
+ throw new CameraAccessException(reason, e.getMessage(), e);
+ } else if (t instanceof DeadObjectException) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+ "Camera service has died unexpectedly",
+ t);
+ } else if (t instanceof RemoteException) {
+ throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
+ " which should never happen.", t);
+ } else if (t instanceof RuntimeException) {
+ RuntimeException e = (RuntimeException) t;
+ throw e;
+ }
+ }
+
+ /**
* Return or create the list of currently connected camera devices.
*
* <p>In case of errors connecting to the camera service, will return an empty list.</p>
@@ -619,34 +660,32 @@
try {
numCameras = cameraService.getNumberOfCameras(CAMERA_TYPE_ALL);
- } catch(CameraRuntimeException e) {
- throw e.asChecked();
+ } catch(ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
// camera service just died - if no camera service, then no devices
return deviceIdList;
}
- CameraMetadataNative info = new CameraMetadataNative();
for (int i = 0; i < numCameras; ++i) {
// Non-removable cameras use integers starting at 0 for their
// identifiers
boolean isDeviceSupported = false;
try {
- cameraService.getCameraCharacteristics(i, info);
+ CameraMetadataNative info = cameraService.getCameraCharacteristics(i);
if (!info.isEmpty()) {
isDeviceSupported = true;
} else {
throw new AssertionError("Expected to get non-empty characteristics");
}
- } catch(IllegalArgumentException e) {
- // Got a BAD_VALUE from service, meaning that this
- // device is not supported.
- } catch(CameraRuntimeException e) {
+ } catch(ServiceSpecificException e) {
// DISCONNECTED means that the HAL reported an low-level error getting the
- // device info; skip listing the device. Other errors,
+ // device info; ILLEGAL_ARGUMENT means that this devices is not supported.
+ // Skip listing the device. Other errors,
// propagate exception onward
- if (e.getReason() != CameraAccessException.CAMERA_DISCONNECTED) {
- throw e.asChecked();
+ if (e.errorCode != ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode != ICameraService.ERROR_ILLEGAL_ARGUMENT) {
+ throwAsPublicException(e);
}
} catch(RemoteException e) {
// Camera service died - no devices to list
@@ -699,17 +738,7 @@
// If no camera service, no support
if (cameraService == null) return false;
- int res = cameraService.supportsCameraApi(id, apiVersion);
-
- if (res != CameraServiceBinderDecorator.NO_ERROR) {
- throw new AssertionError("Unexpected value " + res);
- }
- return true;
- } catch (CameraRuntimeException e) {
- if (e.getReason() != CameraAccessException.CAMERA_DEPRECATED_HAL) {
- throw e;
- }
- // API level is not supported
+ return cameraService.supportsCameraApi(id, apiVersion);
} catch (RemoteException e) {
// Camera service is now down, no support for any API level
}
@@ -737,21 +766,6 @@
*/
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
- // Keep up-to-date with ICameraServiceListener.h
-
- // Device physically unplugged
- public static final int STATUS_NOT_PRESENT = 0;
- // Device physically has been plugged in
- // and the camera can be used exclusively
- public static final int STATUS_PRESENT = 1;
- // Device physically has been plugged in
- // but it will not be connect-able until enumeration is complete
- public static final int STATUS_ENUMERATING = 2;
- // Camera is in use by another app and cannot be used exclusively
- public static final int STATUS_NOT_AVAILABLE = 0x80000000;
-
- // End enums shared with ICameraServiceListener.h
-
// Camera ID -> Status map
private final ArrayMap<String, Integer> mDeviceStatus = new ArrayMap<String, Integer>();
@@ -759,17 +773,6 @@
private final ArrayMap<AvailabilityCallback, Handler> mCallbackMap =
new ArrayMap<AvailabilityCallback, Handler>();
- // Keep up-to-date with ICameraServiceListener.h
-
- // torch mode has become not available to set via setTorchMode().
- public static final int TORCH_STATUS_NOT_AVAILABLE = 0;
- // torch mode is off and available to be turned on via setTorchMode().
- public static final int TORCH_STATUS_AVAILABLE_OFF = 1;
- // torch mode is on and available to be turned off via setTorchMode().
- public static final int TORCH_STATUS_AVAILABLE_ON = 2;
-
- // End enums shared with ICameraServiceListener.h
-
// torch client binder to set the torch mode with.
private Binder mTorchClientBinder = new Binder();
@@ -839,29 +842,20 @@
return;
}
- ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
-
- /**
- * Wrap the camera service in a decorator which automatically translates return codes
- * into exceptions.
- */
- ICameraService cameraService =
- CameraServiceBinderDecorator.newInstance(cameraServiceRaw);
+ ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
try {
- CameraServiceBinderDecorator.throwOnError(
- CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor());
- } catch (CameraRuntimeException e) {
- handleRecoverableSetupErrors(e, "Failed to set up vendor tags");
+ CameraMetadataNative.setupGlobalVendorTagDescriptor();
+ } catch (ServiceSpecificException e) {
+ handleRecoverableSetupErrors(e);
}
try {
cameraService.addListener(this);
mCameraService = cameraService;
- } catch(CameraRuntimeException e) {
+ } catch(ServiceSpecificException e) {
// Unexpected failure
- throw new IllegalStateException("Failed to register a camera service listener",
- e.asChecked());
+ throw new IllegalStateException("Failed to register a camera service listener", e);
} catch (RemoteException e) {
// Camera service is now down, leave mCameraService as null
}
@@ -881,16 +875,9 @@
}
try {
- int status = cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder);
- } catch(CameraRuntimeException e) {
- int problem = e.getReason();
- switch (problem) {
- case CameraAccessException.CAMERA_ERROR:
- throw new IllegalArgumentException(
- "the camera device doesn't have a flash unit.");
- default:
- throw e.asChecked();
- }
+ cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder);
+ } catch(ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable");
@@ -898,21 +885,19 @@
}
}
- private void handleRecoverableSetupErrors(CameraRuntimeException e, String msg) {
- int problem = e.getReason();
- switch (problem) {
- case CameraAccessException.CAMERA_DISCONNECTED:
- String errorMsg = CameraAccessException.getDefaultMessage(problem);
- Log.w(TAG, msg + ": " + errorMsg);
+ private void handleRecoverableSetupErrors(ServiceSpecificException e) {
+ switch (e.errorCode) {
+ case ICameraService.ERROR_DISCONNECTED:
+ Log.w(TAG, e.getMessage());
break;
default:
- throw new IllegalStateException(msg, e.asChecked());
+ throw new IllegalStateException(e);
}
}
private boolean isAvailable(int status) {
switch (status) {
- case STATUS_PRESENT:
+ case ICameraServiceListener.STATUS_PRESENT:
return true;
default:
return false;
@@ -921,10 +906,10 @@
private boolean validStatus(int status) {
switch (status) {
- case STATUS_NOT_PRESENT:
- case STATUS_PRESENT:
- case STATUS_ENUMERATING:
- case STATUS_NOT_AVAILABLE:
+ case ICameraServiceListener.STATUS_NOT_PRESENT:
+ case ICameraServiceListener.STATUS_PRESENT:
+ case ICameraServiceListener.STATUS_ENUMERATING:
+ case ICameraServiceListener.STATUS_NOT_AVAILABLE:
return true;
default:
return false;
@@ -933,9 +918,9 @@
private boolean validTorchStatus(int status) {
switch (status) {
- case TORCH_STATUS_NOT_AVAILABLE:
- case TORCH_STATUS_AVAILABLE_ON:
- case TORCH_STATUS_AVAILABLE_OFF:
+ case ICameraServiceListener.TORCH_STATUS_NOT_AVAILABLE:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_OFF:
return true;
default:
return false;
@@ -966,14 +951,14 @@
private void postSingleTorchUpdate(final TorchCallback callback, final Handler handler,
final String id, final int status) {
switch(status) {
- case TORCH_STATUS_AVAILABLE_ON:
- case TORCH_STATUS_AVAILABLE_OFF:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_OFF:
handler.post(
new Runnable() {
@Override
public void run() {
callback.onTorchModeChanged(id, status ==
- TORCH_STATUS_AVAILABLE_ON);
+ ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON);
}
});
break;
@@ -1220,11 +1205,12 @@
// and torch statuses will be updated.
for (int i = 0; i < mDeviceStatus.size(); i++) {
String cameraId = mDeviceStatus.keyAt(i);
- onStatusChangedLocked(STATUS_NOT_PRESENT, cameraId);
+ onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, cameraId);
}
for (int i = 0; i < mTorchStatus.size(); i++) {
String cameraId = mTorchStatus.keyAt(i);
- onTorchStatusChangedLocked(TORCH_STATUS_NOT_AVAILABLE, cameraId);
+ onTorchStatusChangedLocked(ICameraServiceListener.TORCH_STATUS_NOT_AVAILABLE,
+ cameraId);
}
scheduleCameraServiceReconnectionLocked();
diff --git a/core/java/android/hardware/camera2/CaptureRequest.aidl b/core/java/android/hardware/camera2/CaptureRequest.aidl
deleted file mode 100644
index 0b7d5ba..0000000
--- a/core/java/android/hardware/camera2/CaptureRequest.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/** @hide */
-parcelable CaptureRequest;
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
deleted file mode 100644
index 151c918..0000000
--- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.impl.CaptureResultExtras;
-
-/** @hide */
-interface ICameraDeviceCallbacks
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
- */
-
- oneway void onDeviceError(int errorCode, in CaptureResultExtras resultExtras);
- oneway void onDeviceIdle();
- oneway void onCaptureStarted(in CaptureResultExtras resultExtras, long timestamp);
- oneway void onResultReceived(in CameraMetadataNative result,
- in CaptureResultExtras resultExtras);
- oneway void onPrepared(int streamId);
-}
diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
deleted file mode 100644
index c9c9abc..0000000
--- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.LongParcelable;
-import android.view.Surface;
-
-/** @hide */
-interface ICameraDeviceUser
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceUser.h and
- * frameworks/base/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
- */
- void disconnect();
-
- // ints here are status_t
-
- // non-negative value is the requestId. negative value is status_t
- int submitRequest(in CaptureRequest request, boolean streaming,
- out LongParcelable lastFrameNumber);
-
- int submitRequestList(in List<CaptureRequest> requestList, boolean streaming,
- out LongParcelable lastFrameNumber);
-
- int cancelRequest(int requestId, out LongParcelable lastFrameNumber);
-
- /**
- * Begin the device configuration.
- *
- * <p>
- * beginConfigure must be called before any call to deleteStream, createStream,
- * or endConfigure. It is not valid to call this when the device is not idle.
- * <p>
- */
- int beginConfigure();
-
- /**
- * End the device configuration.
- *
- * <p>
- * endConfigure must be called after stream configuration is complete (i.e. after
- * a call to beginConfigure and subsequent createStream/deleteStream calls). This
- * must be called before any requests can be submitted.
- * <p>
- */
- int endConfigure(boolean isConstrainedHighSpeed);
-
- int deleteStream(int streamId);
-
- // non-negative value is the stream ID. negative value is status_t
- int createStream(in OutputConfiguration outputConfiguration);
-
- /**
- * Create an input stream
- *
- * <p>Create an input stream of width, height, and format</p>
- *
- * @param width Width of the input buffers
- * @param height Height of the input buffers
- * @param format Format of the input buffers. One of HAL_PIXEL_FORMAT_*.
- *
- * @return stream ID if it's a non-negative value. status_t if it's a negative value.
- */
- int createInputStream(int width, int height, int format);
-
- /**
- * Get the surface of the input stream.
- *
- * <p>It's valid to call this method only after a stream configuration is completed
- * successfully and the stream configuration includes a input stream.</p>
- *
- * @param surface An output argument for the surface of the input stream buffer queue.
- */
- int getInputSurface(out Surface surface);
-
- int createDefaultRequest(int templateId, out CameraMetadataNative request);
-
- int getCameraInfo(out CameraMetadataNative info);
-
- int waitUntilIdle();
-
- int flush(out LongParcelable lastFrameNumber);
-
- int prepare(int streamId);
-
- int tearDown(int streamId);
-
- int prepare2(int maxCount, int streamId);
-}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 3aba0d1..00dd780 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -33,14 +33,14 @@
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.ReprocessFormatsMap;
import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.utils.SurfaceUtils;
+import android.hardware.ICameraService;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Range;
import android.util.Size;
@@ -70,7 +70,7 @@
private static final int REQUEST_ID_NONE = -1;
// TODO: guard every function with if (!mRemoteDevice) check (if it was closed)
- private ICameraDeviceUser mRemoteDevice;
+ private ICameraDeviceUserWrapper mRemoteDevice;
// Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock = new Object(); // access from this class and Session only!
@@ -267,7 +267,7 @@
// If setRemoteFailure already called, do nothing
if (mInError) return;
- mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice);
+ mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
mDeviceHandler.post(mCallOnOpened);
mDeviceHandler.post(mCallOnUnconfigured);
@@ -280,28 +280,29 @@
* <p>This places the camera device in the error state and informs the callback.
* Use in place of setRemoteDevice() when startup fails.</p>
*/
- public void setRemoteFailure(final CameraRuntimeException failure) {
+ public void setRemoteFailure(final ServiceSpecificException failure) {
int failureCode = StateCallback.ERROR_CAMERA_DEVICE;
boolean failureIsError = true;
- switch (failure.getReason()) {
- case CameraAccessException.CAMERA_IN_USE:
+ switch (failure.errorCode) {
+ case ICameraService.ERROR_CAMERA_IN_USE:
failureCode = StateCallback.ERROR_CAMERA_IN_USE;
break;
- case CameraAccessException.MAX_CAMERAS_IN_USE:
+ case ICameraService.ERROR_MAX_CAMERAS_IN_USE:
failureCode = StateCallback.ERROR_MAX_CAMERAS_IN_USE;
break;
- case CameraAccessException.CAMERA_DISABLED:
+ case ICameraService.ERROR_DISABLED:
failureCode = StateCallback.ERROR_CAMERA_DISABLED;
break;
- case CameraAccessException.CAMERA_DISCONNECTED:
+ case ICameraService.ERROR_DISCONNECTED:
failureIsError = false;
break;
- case CameraAccessException.CAMERA_ERROR:
+ case ICameraService.ERROR_INVALID_OPERATION:
failureCode = StateCallback.ERROR_CAMERA_DEVICE;
break;
default:
- Log.wtf(TAG, "Unknown failure in opening camera device: " + failure.getReason());
+ Log.e(TAG, "Unexpected failure in opening camera device: " + failure.errorCode +
+ failure.getMessage());
break;
}
final int code = failureCode;
@@ -430,27 +431,20 @@
}
}
- try {
- mRemoteDevice.endConfigure(isConstrainedHighSpeed);
- }
- catch (IllegalArgumentException e) {
- // OK. camera service can reject stream config if it's not supported by HAL
- // This is only the result of a programmer misusing the camera2 api.
- Log.w(TAG, "Stream configuration failed");
- return false;
- }
+ mRemoteDevice.endConfigure(isConstrainedHighSpeed);
success = true;
- } catch (CameraRuntimeException e) {
- if (e.getReason() == CAMERA_IN_USE) {
- throw new IllegalStateException("The camera is currently busy." +
- " You must wait until the previous operation completes.");
- }
-
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
+ } catch (IllegalArgumentException e) {
+ // OK. camera service can reject stream config if it's not supported by HAL
+ // This is only the result of a programmer misusing the camera2 api.
+ Log.w(TAG, "Stream configuration failed due to: " + e.getMessage());
return false;
+ } catch (CameraAccessException e) {
+ if (e.getReason() == CameraAccessException.CAMERA_IN_USE) {
+ throw new IllegalStateException("The camera is currently busy." +
+ " You must wait until the previous operation completes.", e);
+ }
+ throw e;
} finally {
if (success && outputs.size() > 0) {
mDeviceHandler.post(mCallOnIdle);
@@ -594,12 +588,7 @@
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
isConstrainedHighSpeed);
if (configureSuccess == true && inputConfig != null) {
- input = new Surface();
- try {
- mRemoteDevice.getInputSurface(/*out*/input);
- } catch (CameraRuntimeException e) {
- e.asChecked();
- }
+ input = mRemoteDevice.getInputSurface();
}
} catch (CameraAccessException e) {
configureSuccess = false;
@@ -608,9 +597,6 @@
if (DEBUG) {
Log.v(TAG, "createCaptureSession - failed with exception ", e);
}
- } catch (RemoteException e) {
- // impossible
- return;
}
List<Surface> outSurfaces = new ArrayList<>(outputConfigurations.size());
@@ -655,16 +641,9 @@
synchronized(mInterfaceLock) {
checkIfCameraClosedOrInError();
- CameraMetadataNative templatedRequest = new CameraMetadataNative();
+ CameraMetadataNative templatedRequest = null;
- try {
- mRemoteDevice.createDefaultRequest(templateType, /*out*/templatedRequest);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return null;
- }
+ templatedRequest = mRemoteDevice.createDefaultRequest(templateType);
CaptureRequest.Builder builder = new CaptureRequest.Builder(
templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
@@ -701,14 +680,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.prepare(streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.prepare(streamId);
}
}
@@ -728,14 +701,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.prepare2(maxCount, streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.prepare2(maxCount, streamId);
}
}
@@ -753,14 +720,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.tearDown(streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.tearDown(streamId);
}
}
@@ -875,45 +836,37 @@
synchronized(mInterfaceLock) {
checkIfCameraClosedOrInError();
- int requestId;
-
if (repeating) {
stopRepeating();
}
- LongParcelable lastFrameNumberRef = new LongParcelable();
- try {
- requestId = mRemoteDevice.submitRequestList(requestList, repeating,
- /*out*/lastFrameNumberRef);
- if (DEBUG) {
- Log.v(TAG, "last frame number " + lastFrameNumberRef.getNumber());
- }
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return -1;
+ SubmitInfo requestInfo;
+
+ CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]);
+ requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating);
+ if (DEBUG) {
+ Log.v(TAG, "last frame number " + requestInfo.getLastFrameNumber());
}
if (callback != null) {
- mCaptureCallbackMap.put(requestId, new CaptureCallbackHolder(callback,
- requestList, handler, repeating, mNextSessionId - 1));
+ mCaptureCallbackMap.put(requestInfo.getRequestId(),
+ new CaptureCallbackHolder(
+ callback, requestList, handler, repeating, mNextSessionId - 1));
} else {
if (DEBUG) {
- Log.d(TAG, "Listen for request " + requestId + " is null");
+ Log.d(TAG, "Listen for request " + requestInfo.getRequestId() + " is null");
}
}
- long lastFrameNumber = lastFrameNumberRef.getNumber();
-
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
+ checkEarlyTriggerSequenceComplete(mRepeatingRequestId,
+ requestInfo.getLastFrameNumber());
}
- mRepeatingRequestId = requestId;
+ mRepeatingRequestId = requestInfo.getRequestId();
} else {
- mRequestLastFrameNumbersList.add(new RequestLastFrameNumbersHolder(requestList,
- requestId, lastFrameNumber));
+ mRequestLastFrameNumbersList.add(
+ new RequestLastFrameNumbersHolder(requestList, requestInfo));
}
if (mIdle) {
@@ -921,7 +874,7 @@
}
mIdle = false;
- return requestId;
+ return requestInfo.getRequestId();
}
}
@@ -949,19 +902,9 @@
int requestId = mRepeatingRequestId;
mRepeatingRequestId = REQUEST_ID_NONE;
- try {
- LongParcelable lastFrameNumberRef = new LongParcelable();
- mRemoteDevice.cancelRequest(requestId, /*out*/lastFrameNumberRef);
- long lastFrameNumber = lastFrameNumberRef.getNumber();
+ long lastFrameNumber = mRemoteDevice.cancelRequest(requestId);
- checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber);
-
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+ checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber);
}
}
}
@@ -974,14 +917,8 @@
if (mRepeatingRequestId != REQUEST_ID_NONE) {
throw new IllegalStateException("Active repeating request ongoing");
}
- try {
- mRemoteDevice.waitUntilIdle();
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.waitUntilIdle();
}
}
@@ -997,19 +934,11 @@
mDeviceHandler.post(mCallOnIdle);
return;
}
- try {
- LongParcelable lastFrameNumberRef = new LongParcelable();
- mRemoteDevice.flush(/*out*/lastFrameNumberRef);
- if (mRepeatingRequestId != REQUEST_ID_NONE) {
- long lastFrameNumber = lastFrameNumberRef.getNumber();
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
- mRepeatingRequestId = REQUEST_ID_NONE;
- }
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
+
+ long lastFrameNumber = mRemoteDevice.flush();
+ if (mRepeatingRequestId != REQUEST_ID_NONE) {
+ checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
+ mRepeatingRequestId = REQUEST_ID_NONE;
}
}
}
@@ -1021,14 +950,8 @@
return;
}
- try {
- if (mRemoteDevice != null) {
- mRemoteDevice.disconnect();
- }
- } catch (CameraRuntimeException e) {
- Log.e(TAG, "Exception while closing: ", e.asChecked());
- } catch (RemoteException e) {
- // impossible
+ if (mRemoteDevice != null) {
+ mRemoteDevice.disconnect();
}
// Only want to fire the onClosed callback once;
@@ -1297,14 +1220,14 @@
* Create a request-last-frame-numbers holder with a list of requests, request ID, and
* the last frame number returned by camera service.
*/
- public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, int requestId,
- long lastFrameNumber) {
+ public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo) {
long lastRegularFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
long lastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long frameNumber = lastFrameNumber;
+ long frameNumber = requestInfo.getLastFrameNumber();
- if (lastFrameNumber < requestList.size() - 1) {
- throw new IllegalArgumentException("lastFrameNumber: " + lastFrameNumber +
+ if (requestInfo.getLastFrameNumber() < requestList.size() - 1) {
+ throw new IllegalArgumentException(
+ "lastFrameNumber: " + requestInfo.getLastFrameNumber() +
" should be at least " + (requestList.size() - 1) + " for the number of " +
" requests in the list: " + requestList.size());
}
@@ -1330,7 +1253,7 @@
mLastRegularFrameNumber = lastRegularFrameNumber;
mLastReprocessFrameNumber = lastReprocessFrameNumber;
- mRequestId = requestId;
+ mRequestId = requestInfo.getRequestId();
}
/**
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl b/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
deleted file mode 100644
index 4a89129..0000000
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 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.impl;
-
-/** @hide */
-parcelable CameraMetadataNative;
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 12a2910..79eac26 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -58,6 +58,7 @@
import android.location.LocationManager;
import android.os.Parcelable;
import android.os.Parcel;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Size;
@@ -363,13 +364,24 @@
* Set the global client-side vendor tag descriptor to allow use of vendor
* tags in camera applications.
*
- * @return int A native status_t value corresponding to one of the
- * {@link CameraBinderDecorator} integer constants.
- * @see CameraBinderDecorator#throwOnError
- *
+ * @throws ServiceSpecificException
* @hide
*/
- public static native int nativeSetupGlobalVendorTagDescriptor();
+ public static void setupGlobalVendorTagDescriptor() throws ServiceSpecificException {
+ int err = nativeSetupGlobalVendorTagDescriptor();
+ if (err != 0) {
+ throw new ServiceSpecificException(err, "Failure to set up global vendor tags");
+ }
+ }
+
+ /**
+ * Set the global client-side vendor tag descriptor to allow use of vendor
+ * tags in camera applications.
+ *
+ * @return int An error code corresponding to one of the
+ * {@link ICameraService} error constants, or 0 on success.
+ */
+ private static native int nativeSetupGlobalVendorTagDescriptor();
/**
* Set a camera metadata field to a value. The field definitions can be
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl b/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
deleted file mode 100644
index ebc812a..0000000
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.impl;
-
-/** @hide */
-parcelable CaptureResultExtras;
diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
new file mode 100644
index 0000000..ddc3fd1
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 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.impl;
+
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
+import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
+
+import android.hardware.ICameraService;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.params.OutputConfiguration;
+import android.hardware.camera2.utils.SubmitInfo;
+import android.os.RemoteException;
+import android.view.Surface;
+
+/**
+ * A wrapper around ICameraDeviceUser.
+ *
+ * Mainly used to convert ServiceSpecificExceptions to the correct
+ * checked / unchecked exception.
+ *
+ * @hide
+ */
+public class ICameraDeviceUserWrapper {
+
+ private final ICameraDeviceUser mRemoteDevice;
+
+ public ICameraDeviceUserWrapper(ICameraDeviceUser remoteDevice) {
+ if (remoteDevice == null) {
+ throw new NullPointerException("Remote device may not be null");
+ }
+ mRemoteDevice = remoteDevice;
+ }
+
+ public void disconnect() {
+ try {
+ mRemoteDevice.disconnect();
+ } catch (RemoteException t) {
+ // ignore binder errors for disconnect
+ }
+ }
+
+ public SubmitInfo submitRequest(CaptureRequest request, boolean streaming)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.submitRequest(request, streaming);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean streaming)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.submitRequestList(requestList, streaming);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public long cancelRequest(int requestId) throws CameraAccessException {
+ try {
+ return mRemoteDevice.cancelRequest(requestId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void beginConfigure() throws CameraAccessException {
+ try {
+ mRemoteDevice.beginConfigure();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void endConfigure(boolean isConstrainedHighSpeed) throws CameraAccessException {
+ try {
+ mRemoteDevice.endConfigure(isConstrainedHighSpeed);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void deleteStream(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.deleteStream(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public int createStream(OutputConfiguration outputConfiguration)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.createStream(outputConfiguration);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public int createInputStream(int width, int height, int format) throws CameraAccessException {
+ try {
+ return mRemoteDevice.createInputStream(width, height, format);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public Surface getInputSurface() throws CameraAccessException {
+ try {
+ return mRemoteDevice.getInputSurface();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public CameraMetadataNative createDefaultRequest(int templateId) throws CameraAccessException {
+ try {
+ return mRemoteDevice.createDefaultRequest(templateId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public CameraMetadataNative getCameraInfo() throws CameraAccessException {
+ try {
+ return mRemoteDevice.getCameraInfo();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void waitUntilIdle() throws CameraAccessException {
+ try {
+ mRemoteDevice.waitUntilIdle();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public long flush() throws CameraAccessException {
+ try {
+ return mRemoteDevice.flush();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void prepare(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.prepare(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void tearDown(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.tearDown(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void prepare2(int maxCount, int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.prepare2(maxCount, streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+
+}
diff --git a/core/java/android/hardware/camera2/legacy/BurstHolder.java b/core/java/android/hardware/camera2/legacy/BurstHolder.java
index e7b3682..23efe15 100644
--- a/core/java/android/hardware/camera2/legacy/BurstHolder.java
+++ b/core/java/android/hardware/camera2/legacy/BurstHolder.java
@@ -35,10 +35,10 @@
*
* @param requestId id of the burst request.
* @param repeating true if this burst is repeating.
- * @param requests a {@link List} of {@link CaptureRequest}s in this burst.
+ * @param requests the array of {@link CaptureRequest}s for this burst.
* @param jpegSurfaceIds a {@link Collection} of IDs for the surfaces that have jpeg outputs.
*/
- public BurstHolder(int requestId, boolean repeating, List<CaptureRequest> requests,
+ public BurstHolder(int requestId, boolean repeating, CaptureRequest[] requests,
Collection<Long> jpegSurfaceIds) {
mRequestBuilders = new ArrayList<>();
int i = 0;
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 798c941..d01c275 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -16,6 +16,7 @@
package android.hardware.camera2.legacy;
+import android.hardware.ICameraService;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.camera2.CameraAccessException;
@@ -23,12 +24,10 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
-import android.hardware.camera2.utils.LongParcelable;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
+import android.hardware.camera2.utils.SubmitInfo;
import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Looper;
@@ -36,6 +35,7 @@
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;
@@ -93,7 +93,7 @@
private static int translateErrorsFromCamera1(int errorCode) {
if (errorCode == -EACCES) {
- return CameraBinderDecorator.PERMISSION_DENIED;
+ return ICameraService.ERROR_PERMISSION_DENIED;
}
return errorCode;
@@ -173,7 +173,7 @@
*
* @return int error code
*
- * @throws CameraRuntimeException if the camera open times out with ({@code CAMERA_ERROR})
+ * @throws ServiceSpecificException if the camera open times out with ({@code CAMERA_ERROR})
*/
public int waitForOpen(int timeoutMs) {
// Block until the camera is open asynchronously
@@ -186,7 +186,7 @@
Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e);
}
- throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION);
}
return mInitErrors;
@@ -344,7 +344,7 @@
Camera legacyCamera = init.getCamera();
// Check errors old HAL initialization
- CameraBinderDecorator.throwOnError(initErrors);
+ LegacyExceptionUtils.throwOnServiceError(initErrors);
// Disable shutter sounds (this will work unconditionally) for api2 clients
legacyCamera.disableShutterSound();
@@ -356,8 +356,8 @@
try {
legacyParameters = legacyCamera.getParameters();
} catch (RuntimeException e) {
- throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR,
- "Unable to get initial parameters", e);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION,
+ "Unable to get initial parameters: " + e.getMessage());
}
CameraCharacteristics characteristics =
@@ -386,101 +386,106 @@
}
@Override
- public int submitRequest(CaptureRequest request, boolean streaming,
- /*out*/LongParcelable lastFrameNumber) {
+ public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) {
if (DEBUG) {
Log.d(TAG, "submitRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot submit request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot submit request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot submit request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot submit request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- return mLegacyDevice.submitRequest(request, streaming, lastFrameNumber);
+ return mLegacyDevice.submitRequest(request, streaming);
}
@Override
- public int submitRequestList(List<CaptureRequest> request, boolean streaming,
- /*out*/LongParcelable lastFrameNumber) {
+ public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) {
if (DEBUG) {
Log.d(TAG, "submitRequestList called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot submit request list, device has been closed.");
- return -ENODEV;
+ String err = "Cannot submit request list, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot submit request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot submit request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- return mLegacyDevice.submitRequestList(request, streaming, lastFrameNumber);
+ return mLegacyDevice.submitRequestList(request, streaming);
}
@Override
- public int cancelRequest(int requestId, /*out*/LongParcelable lastFrameNumber) {
+ public long cancelRequest(int requestId) {
if (DEBUG) {
Log.d(TAG, "cancelRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot cancel request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot cancel request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot cancel request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot cancel request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- long lastFrame = mLegacyDevice.cancelRequest(requestId);
- lastFrameNumber.setNumber(lastFrame);
- return CameraBinderDecorator.NO_ERROR;
+ return mLegacyDevice.cancelRequest(requestId);
}
@Override
- public int beginConfigure() {
+ public void beginConfigure() {
if (DEBUG) {
Log.d(TAG, "beginConfigure called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot begin configure, device has been closed.");
- return -ENODEV;
+ String err = "Cannot begin configure, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot begin configure, configuration change already in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot begin configure, configuration change already in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
mConfiguring = true;
}
- return CameraBinderDecorator.NO_ERROR;
}
@Override
- public int endConfigure(boolean isConstrainedHighSpeed) {
+ public void endConfigure(boolean isConstrainedHighSpeed) {
if (DEBUG) {
Log.d(TAG, "endConfigure called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot end configure, device has been closed.");
- return -ENODEV;
+ String err = "Cannot end configure, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
ArrayList<Surface> surfaces = null;
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot end configure, no configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot end configure, no configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
int numSurfaces = mSurfaces.size();
if (numSurfaces > 0) {
@@ -491,32 +496,34 @@
}
mConfiguring = false;
}
- return mLegacyDevice.configureOutputs(surfaces);
+ mLegacyDevice.configureOutputs(surfaces);
}
@Override
- public int deleteStream(int streamId) {
+ public void deleteStream(int streamId) {
if (DEBUG) {
Log.d(TAG, "deleteStream called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot delete stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot delete stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot delete stream, no configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
int index = mSurfaces.indexOfKey(streamId);
if (index < 0) {
- Log.e(TAG, "Cannot delete stream, stream id " + streamId + " doesn't exist.");
- return CameraBinderDecorator.BAD_VALUE;
+ String err = "Cannot delete stream, stream id " + streamId + " doesn't exist.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
mSurfaces.removeAt(index);
}
- return CameraBinderDecorator.NO_ERROR;
}
@Override
@@ -525,18 +532,21 @@
Log.d(TAG, "createStream called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot create stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot create stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot create stream, beginConfigure hasn't been called yet.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) {
- Log.e(TAG, "Cannot create stream, stream rotation is not supported.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot create stream, stream rotation is not supported.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
int id = ++mSurfaceIdCounter;
mSurfaces.put(id, outputConfiguration.getSurface());
@@ -546,24 +556,27 @@
@Override
public int createInputStream(int width, int height, int format) {
- Log.e(TAG, "creating input stream is not supported on legacy devices");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Creating input stream is not supported on legacy devices";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
@Override
- public int getInputSurface(/*out*/ Surface surface) {
- Log.e(TAG, "getting input surface is not supported on legacy devices");
- return CameraBinderDecorator.INVALID_OPERATION;
+ public Surface getInputSurface() {
+ String err = "Getting input surface is not supported on legacy devices";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
@Override
- public int createDefaultRequest(int templateId, /*out*/CameraMetadataNative request) {
+ public CameraMetadataNative createDefaultRequest(int templateId) {
if (DEBUG) {
Log.d(TAG, "createDefaultRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot create default request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot create default request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
CameraMetadataNative template;
@@ -571,99 +584,96 @@
template =
LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "createDefaultRequest - invalid templateId specified");
- return CameraBinderDecorator.BAD_VALUE;
+ String err = "createDefaultRequest - invalid templateId specified";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
- request.swap(template);
- return CameraBinderDecorator.NO_ERROR;
+ return template;
}
@Override
- public int getCameraInfo(/*out*/CameraMetadataNative info) {
+ public CameraMetadataNative getCameraInfo() {
if (DEBUG) {
Log.d(TAG, "getCameraInfo called.");
}
// TODO: implement getCameraInfo.
Log.e(TAG, "getCameraInfo unimplemented.");
- return CameraBinderDecorator.NO_ERROR;
+ return null;
}
@Override
- public int waitUntilIdle() throws RemoteException {
+ public void waitUntilIdle() throws RemoteException {
if (DEBUG) {
Log.d(TAG, "waitUntilIdle called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot wait until idle, device has been closed.");
- return -ENODEV;
+ String err = "Cannot wait until idle, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot wait until idle, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot wait until idle, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
mLegacyDevice.waitUntilIdle();
- return CameraBinderDecorator.NO_ERROR;
}
@Override
- public int flush(/*out*/LongParcelable lastFrameNumber) {
+ public long flush() {
if (DEBUG) {
Log.d(TAG, "flush called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot flush, device has been closed.");
- return -ENODEV;
+ String err = "Cannot flush, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot flush, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot flush, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- long lastFrame = mLegacyDevice.flush();
- if (lastFrameNumber != null) {
- lastFrameNumber.setNumber(lastFrame);
- }
- return CameraBinderDecorator.NO_ERROR;
+ return mLegacyDevice.flush();
}
- public int prepare(int streamId) {
+ public void prepare(int streamId) {
if (DEBUG) {
Log.d(TAG, "prepare called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot prepare stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot prepare stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
// LEGACY doesn't support actual prepare, just signal success right away
mCameraCallbacks.onPrepared(streamId);
-
- return CameraBinderDecorator.NO_ERROR;
}
- public int prepare2(int maxCount, int streamId) {
+ public void prepare2(int maxCount, int streamId) {
// We don't support this in LEGACY mode.
- return prepare(streamId);
+ prepare(streamId);
}
- public int tearDown(int streamId) {
+ public void tearDown(int streamId) {
if (DEBUG) {
Log.d(TAG, "tearDown called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot tear down stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot tear down stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
// LEGACY doesn't support actual teardown, so just a no-op
-
- return CameraBinderDecorator.NO_ERROR;
}
@Override
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index fddfbde..e62df3c 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -26,14 +26,13 @@
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.camera2.utils.ArrayUtils;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.utils.CameraRuntimeException;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
@@ -45,7 +44,6 @@
import java.util.List;
import static android.hardware.camera2.legacy.LegacyExceptionUtils.*;
-import static android.hardware.camera2.utils.CameraBinderDecorator.*;
import static com.android.internal.util.Preconditions.*;
/**
@@ -357,9 +355,9 @@
if (success) {
mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null;
} else {
- return CameraBinderDecorator.INVALID_OPERATION;
+ return LegacyExceptionUtils.INVALID_OPERATION;
}
- return CameraBinderDecorator.NO_ERROR;
+ return LegacyExceptionUtils.NO_ERROR;
}
/**
@@ -367,17 +365,16 @@
*
* @param requestList a list of capture requests to execute.
* @param repeating {@code true} if this burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitRequestList(List<CaptureRequest> requestList, boolean repeating,
- /*out*/LongParcelable frameNumber) {
- if (requestList == null || requestList.isEmpty()) {
+ public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean repeating) {
+ if (requestList == null || requestList.length == 0) {
Log.e(TAG, "submitRequestList - Empty/null requests are not allowed");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - Empty/null requests are not allowed");
}
List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
@@ -388,28 +385,33 @@
if (request.getTargets().isEmpty()) {
Log.e(TAG, "submitRequestList - "
+ "Each request must have at least one Surface target");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - "
+ + "Each request must have at least one Surface target");
}
for (Surface surface : request.getTargets()) {
if (surface == null) {
Log.e(TAG, "submitRequestList - Null Surface targets are not allowed");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - Null Surface targets are not allowed");
} else if (mConfiguredSurfaces == null) {
Log.e(TAG, "submitRequestList - must configure " +
" device with valid surfaces before submitting requests");
- return INVALID_OPERATION;
+ throw new ServiceSpecificException(INVALID_OPERATION,
+ "submitRequestList - must configure " +
+ " device with valid surfaces before submitting requests");
} else if (!containsSurfaceId(surface, surfaceIds)) {
Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - cannot use a surface that wasn't configured");
}
}
}
// TODO: further validation of request here
mIdle.close();
- return mRequestThreadManager.submitCaptureRequests(requestList, repeating,
- frameNumber);
+ return mRequestThreadManager.submitCaptureRequests(requestList, repeating);
}
/**
@@ -417,17 +419,14 @@
*
* @param request the capture request to execute.
* @param repeating {@code true} if this request is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * request is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitRequest(CaptureRequest request, boolean repeating,
- /*out*/LongParcelable frameNumber) {
- ArrayList<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
- requestList.add(request);
- return submitRequestList(requestList, repeating, frameNumber);
+ public SubmitInfo submitRequest(CaptureRequest request, boolean repeating) {
+ CaptureRequest[] requestList = { request };
+ return submitRequestList(requestList, repeating);
}
/**
@@ -493,7 +492,7 @@
protected void finalize() throws Throwable {
try {
close();
- } catch (CameraRuntimeException e) {
+ } catch (ServiceSpecificException e) {
Log.e(TAG, "Got error while trying to finalize, ignoring: " + e.getMessage());
} finally {
super.finalize();
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
index 4501e81..93d6001 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
@@ -16,10 +16,11 @@
package android.hardware.camera2.legacy;
-import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.hardware.ICameraService;
+import android.os.ServiceSpecificException;
import android.util.AndroidException;
-import static android.system.OsConstants.ENODEV;
+import static android.system.OsConstants.*;
/**
* Utility class containing exception handling used solely by the compatibility mode shim.
@@ -27,6 +28,14 @@
public class LegacyExceptionUtils {
private static final String TAG = "LegacyExceptionUtils";
+ public static final int NO_ERROR = 0;
+ public static final int PERMISSION_DENIED = -EPERM;
+ public static final int ALREADY_EXISTS = -EEXIST;
+ public static final int BAD_VALUE = -EINVAL;
+ public static final int DEAD_OBJECT = -ENOSYS;
+ public static final int INVALID_OPERATION = -EPIPE;
+ public static final int TIMED_OUT = -ETIMEDOUT;
+
/**
* Checked exception thrown when a BufferQueue has been abandoned by its consumer.
*/
@@ -58,8 +67,8 @@
* @return {@code errorFlag} if the value was non-negative, throws otherwise.
*/
public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
- if (errorFlag == CameraBinderDecorator.NO_ERROR) {
- return CameraBinderDecorator.NO_ERROR;
+ if (errorFlag == NO_ERROR) {
+ return NO_ERROR;
} else if (errorFlag == -ENODEV) {
throw new BufferQueueAbandonedException();
}
@@ -70,6 +79,59 @@
return errorFlag;
}
+ /**
+ * Throw error codes returned by the camera service as exceptions.
+ *
+ * @param errorFlag error to throw as an exception.
+ */
+ public static void throwOnServiceError(int errorFlag) {
+ int errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ String errorMsg;
+
+ if (errorFlag >= NO_ERROR) {
+ return;
+ } else if (errorFlag == PERMISSION_DENIED) {
+ errorCode = ICameraService.ERROR_PERMISSION_DENIED;
+ errorMsg = "Lacking privileges to access camera service";
+ } else if (errorFlag == ALREADY_EXISTS) {
+ // This should be handled at the call site. Typically this isn't bad,
+ // just means we tried to do an operation that already completed.
+ return;
+ } else if (errorFlag == BAD_VALUE) {
+ errorCode = ICameraService.ERROR_ILLEGAL_ARGUMENT;
+ errorMsg = "Bad argument passed to camera service";
+ } else if (errorFlag == DEAD_OBJECT) {
+ errorCode = ICameraService.ERROR_DISCONNECTED;
+ errorMsg = "Camera service not available";
+ } else if (errorFlag == TIMED_OUT) {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Operation timed out in camera service";
+ } else if (errorFlag == -EACCES) {
+ errorCode = ICameraService.ERROR_DISABLED;
+ errorMsg = "Camera disabled by policy";
+ } else if (errorFlag == -EBUSY) {
+ errorCode = ICameraService.ERROR_CAMERA_IN_USE;
+ errorMsg = "Camera already in use";
+ } else if (errorFlag == -EUSERS) {
+ errorCode = ICameraService.ERROR_MAX_CAMERAS_IN_USE;
+ errorMsg = "Maximum number of cameras in use";
+ } else if (errorFlag == -ENODEV) {
+ errorCode = ICameraService.ERROR_DISCONNECTED;
+ errorMsg = "Camera device not available";
+ } else if (errorFlag == -EOPNOTSUPP) {
+ errorCode = ICameraService.ERROR_DEPRECATED_HAL;
+ errorMsg = "Deprecated camera HAL does not support this";
+ } else if (errorFlag == INVALID_OPERATION) {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Illegal state encountered in camera service.";
+ } else {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Unknown camera device error " + errorFlag;
+ }
+
+ throw new ServiceSpecificException(errorCode, errorMsg);
+ }
+
private LegacyExceptionUtils() {
throw new AssertionError();
}
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
index c995029..8f252a1 100644
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ b/core/java/android/hardware/camera2/legacy/RequestQueue.java
@@ -16,7 +16,7 @@
package android.hardware.camera2.legacy;
import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.util.Log;
import android.util.Pair;
@@ -111,31 +111,29 @@
*
* @param requests the burst of requests to add to the queue.
* @param repeating true if the burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public synchronized int submit(List<CaptureRequest> requests, boolean repeating,
- /*out*/LongParcelable frameNumber) {
+ public synchronized SubmitInfo submit(CaptureRequest[] requests, boolean repeating) {
int requestId = mCurrentRequestId++;
BurstHolder burst = new BurstHolder(requestId, repeating, requests, mJpegSurfaceIds);
- long ret = INVALID_FRAME;
+ long lastFrame = INVALID_FRAME;
if (burst.isRepeating()) {
Log.i(TAG, "Repeating capture request set.");
if (mRepeatingRequest != null) {
- ret = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
+ lastFrame = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
mCurrentRepeatingFrameNumber - 1;
}
mCurrentRepeatingFrameNumber = INVALID_FRAME;
mRepeatingRequest = burst;
} else {
mRequestQueue.offer(burst);
- ret = calculateLastFrame(burst.getRequestId());
+ lastFrame = calculateLastFrame(burst.getRequestId());
}
- frameNumber.setNumber(ret);
- return requestId;
+ SubmitInfo info = new SubmitInfo(requestId, lastFrame);
+ return info;
}
private long calculateLastFrame(int requestId) {
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 4866598..1ca7ddf 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -21,7 +21,7 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.utils.SizeAreaComparator;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.os.ConditionVariable;
@@ -1008,21 +1008,19 @@
*
* @param requests the burst of requests to add to the queue.
* @param repeating true if the burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitCaptureRequests(List<CaptureRequest> requests, boolean repeating,
- /*out*/LongParcelable frameNumber) {
+ public SubmitInfo submitCaptureRequests(CaptureRequest[] requests, boolean repeating) {
Handler handler = mRequestThread.waitAndGetHandler();
- int ret;
+ SubmitInfo info;
synchronized (mIdleLock) {
- ret = mRequestQueue.submit(requests, repeating, frameNumber);
+ info = mRequestQueue.submit(requests, repeating);
handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST);
}
- return ret;
+ return info;
}
/**
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.aidl b/core/java/android/hardware/camera2/params/OutputConfiguration.aidl
deleted file mode 100644
index 0921cd8..0000000
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.params;
-
-/** @hide */
-parcelable OutputConfiguration;
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 4407e55..cd0c474 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -21,11 +21,11 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.utils.HashCodeHelpers;
import android.hardware.camera2.utils.SurfaceUtils;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
-import android.os.Parcel;
-import android.os.Parcelable;
import static com.android.internal.util.Preconditions.*;
diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
new file mode 100644
index 0000000..ea424e5
--- /dev/null
+++ b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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.params;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * A class for describing the vendor tags declared by a camera HAL module.
+ * Generally only used by the native side of
+ * android.hardware.camera2.impl.CameraMetadataNative
+ *
+ * @hide
+ */
+public final class VendorTagDescriptor implements Parcelable {
+
+ private VendorTagDescriptor(Parcel source) {
+ }
+
+ public static final Parcelable.Creator<VendorTagDescriptor> CREATOR =
+ new Parcelable.Creator<VendorTagDescriptor>() {
+ @Override
+ public VendorTagDescriptor createFromParcel(Parcel source) {
+ try {
+ VendorTagDescriptor vendorDescriptor = new VendorTagDescriptor(source);
+ return vendorDescriptor;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating VendorTagDescriptor from parcel", e);
+ return null;
+ }
+ }
+
+ @Override
+ public VendorTagDescriptor[] newArray(int size) {
+ return new VendorTagDescriptor[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (dest == null) {
+ throw new IllegalArgumentException("dest must not be null");
+ }
+ }
+
+ private static final String TAG = "VendorTagDescriptor";
+}
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.aidl b/core/java/android/hardware/camera2/utils/BinderHolder.aidl
deleted file mode 100644
index f39d645..0000000
--- a/core/java/android/hardware/camera2/utils/BinderHolder.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 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.utils;
-
-/** @hide */
-parcelable BinderHolder;
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.java b/core/java/android/hardware/camera2/utils/BinderHolder.java
deleted file mode 100644
index 9eea390..0000000
--- a/core/java/android/hardware/camera2/utils/BinderHolder.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 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.utils;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.IBinder;
-
-/**
- * @hide
- */
-public class BinderHolder implements Parcelable {
- private IBinder mBinder = null;
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongBinder(mBinder);
- }
-
- public void readFromParcel(Parcel src) {
- mBinder = src.readStrongBinder();
- }
-
- public static final Parcelable.Creator<BinderHolder> CREATOR =
- new Parcelable.Creator<BinderHolder>() {
- @Override
- public BinderHolder createFromParcel(Parcel in) {
- return new BinderHolder(in);
- }
-
- @Override
- public BinderHolder[] newArray(int size) {
- return new BinderHolder[size];
- }
- };
-
- public IBinder getBinder() {
- return mBinder;
- }
-
- public void setBinder(IBinder binder) {
- mBinder = binder;
- }
-
- public BinderHolder() {}
-
- public BinderHolder(IBinder binder) {
- mBinder = binder;
- }
-
- private BinderHolder(Parcel in) {
- mBinder = in.readStrongBinder();
- }
-}
-
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
deleted file mode 100644
index 162edc9..0000000
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2013 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.utils;
-
-import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
-import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
-import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
-import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
-import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
-import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
-import static android.system.OsConstants.*;
-
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-
-import java.lang.reflect.Method;
-
-/**
- * Translate camera device status_t return values into exceptions.
- *
- * @see android.hardware.camera2.utils.CameraBinderDecorator#newInstance
- * @hide
- */
-public class CameraBinderDecorator {
-
- public static final int NO_ERROR = 0;
- public static final int PERMISSION_DENIED = -EPERM;
- public static final int ALREADY_EXISTS = -EEXIST;
- public static final int BAD_VALUE = -EINVAL;
- public static final int DEAD_OBJECT = -ENOSYS;
- public static final int INVALID_OPERATION = -EPIPE;
- public static final int TIMED_OUT = -ETIMEDOUT;
-
- /**
- * TODO: add as error codes in Errors.h
- * - POLICY_PROHIBITS
- * - RESOURCE_BUSY
- * - NO_SUCH_DEVICE
- * - NOT_SUPPORTED
- * - TOO_MANY_USERS
- */
-
- static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
-
- @Override
- public void onBeforeInvocation(Method m, Object[] args) {
- }
-
- @Override
- public void onAfterInvocation(Method m, Object[] args, Object result) {
- // int return type => status_t => convert to exception
- if (m.getReturnType() == Integer.TYPE) {
- int returnValue = (Integer) result;
- throwOnError(returnValue);
- }
- }
-
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
-
- if (t instanceof DeadObjectException) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED,
- "Process hosting the camera service has died unexpectedly",
- t);
- } else if (t instanceof RemoteException) {
- throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
- " which should never happen.", t);
- }
-
- return false;
- }
-
- @Override
- public void onFinally(Method m, Object[] args) {
- }
-
- }
-
- /**
- * Throw error codes returned by the camera service as exceptions.
- *
- * @param errorFlag error to throw as an exception.
- */
- public static void throwOnError(int errorFlag) {
- if (errorFlag == NO_ERROR) {
- return;
- } else if (errorFlag == PERMISSION_DENIED) {
- throw new SecurityException("Lacking privileges to access camera service");
- } else if (errorFlag == ALREADY_EXISTS) {
- // This should be handled at the call site. Typically this isn't bad,
- // just means we tried to do an operation that already completed.
- return;
- } else if (errorFlag == BAD_VALUE) {
- throw new IllegalArgumentException("Bad argument passed to camera service");
- } else if (errorFlag == DEAD_OBJECT) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED);
- } else if (errorFlag == TIMED_OUT) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- "Operation timed out in camera service");
- } else if (errorFlag == -EACCES) {
- throw new CameraRuntimeException(CAMERA_DISABLED);
- } else if (errorFlag == -EBUSY) {
- throw new CameraRuntimeException(CAMERA_IN_USE);
- } else if (errorFlag == -EUSERS) {
- throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
- } else if (errorFlag == -ENODEV) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED);
- } else if (errorFlag == -EOPNOTSUPP) {
- throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
- } else if (errorFlag == INVALID_OPERATION) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- "Illegal state encountered in camera service.");
- }
-
- /**
- * Trap the rest of the negative return values. If we have known
- * error codes i.e. ALREADY_EXISTS that aren't really runtime
- * errors, then add them to the top switch statement
- */
- if (errorFlag < 0) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- String.format("Unknown camera device error %d", errorFlag));
- }
- }
-
- /**
- * <p>
- * Wraps the type T with a proxy that will check 'status_t' return codes
- * from the native side of the camera service, and throw Java exceptions
- * automatically based on the code.
- * </p>
- * <p>
- * In addition it also rewrites binder's RemoteException into either a
- * CameraAccessException or an UnsupportedOperationException.
- * </p>
- * <p>
- * As a result of calling any method on the proxy, RemoteException is
- * guaranteed never to be thrown.
- * </p>
- *
- * @param obj object that will serve as the target for all method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a proxy that will intercept all invocations to obj
- */
- public static <T> T newInstance(T obj) {
- return Decorator.<T> newInstance(obj, new CameraBinderDecoratorListener());
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/CameraRuntimeException.java b/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
deleted file mode 100644
index 9ed88a9..0000000
--- a/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package android.hardware.camera2.utils;
-
-import android.hardware.camera2.CameraAccessException;
-
-/**
- * @hide
- */
-public class CameraRuntimeException extends RuntimeException {
-
- private final int mReason;
- private String mMessage;
- private Throwable mCause;
-
- public final int getReason() {
- return mReason;
- }
-
- public CameraRuntimeException(int problem) {
- super();
- mReason = problem;
- }
-
- public CameraRuntimeException(int problem, String message) {
- super(message);
- mReason = problem;
- mMessage = message;
- }
-
- public CameraRuntimeException(int problem, String message, Throwable cause) {
- super(message, cause);
- mReason = problem;
- mMessage = message;
- mCause = cause;
- }
-
- public CameraRuntimeException(int problem, Throwable cause) {
- super(cause);
- mReason = problem;
- mCause = cause;
- }
-
- /**
- * Recreate this exception as the CameraAccessException equivalent.
- * @return CameraAccessException
- */
- public CameraAccessException asChecked() {
- CameraAccessException e;
-
- if (mMessage != null && mCause != null) {
- e = new CameraAccessException(mReason, mMessage, mCause);
- } else if (mMessage != null) {
- e = new CameraAccessException(mReason, mMessage);
- } else if (mCause != null) {
- e = new CameraAccessException(mReason, mCause);
- } else {
- e = new CameraAccessException(mReason);
- }
- // throw and catch, so java has a chance to fill out the stack trace
- e.setStackTrace(this.getStackTrace());
-
- return e;
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java
deleted file mode 100644
index c1fb6b1..0000000
--- a/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.utils;
-
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.reflect.Method;
-
-/**
- * Translate camera service status_t return values into exceptions.
- *
- * @see android.hardware.camera2.utils.CameraBinderDecorator#newInstance
- * @hide
- */
-public class CameraServiceBinderDecorator extends CameraBinderDecorator {
-
- private static final String TAG = "CameraServiceBinderDecorator";
-
- static class CameraServiceBinderDecoratorListener
- extends CameraBinderDecorator.CameraBinderDecoratorListener {
-
- // Pass through remote exceptions, unlike CameraBinderDecorator
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
-
- if (t instanceof DeadObjectException) {
- // Can sometimes happen (camera service died)
- // Pass on silently
- } else if (t instanceof RemoteException) {
- // Some other kind of remote exception - this is not normal, so let's at least
- // note it before moving on
- Log.e(TAG, "Unexpected RemoteException from camera service call.", t);
- }
- // All other exceptions also get sent onward
- return false;
- }
-
- }
-
- /**
- * <p>
- * Wraps the type T with a proxy that will check 'status_t' return codes
- * from the native side of the camera service, and throw Java exceptions
- * automatically based on the code.
- * </p>
- *
- * @param obj object that will serve as the target for all method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a proxy that will intercept all invocations to obj
- */
- public static <T> T newInstance(T obj) {
- return Decorator.<T> newInstance(obj, new CameraServiceBinderDecoratorListener());
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/Decorator.java b/core/java/android/hardware/camera2/utils/Decorator.java
deleted file mode 100644
index 5826497..0000000
--- a/core/java/android/hardware/camera2/utils/Decorator.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-package android.hardware.camera2.utils;
-
-import java.lang.reflect.*;
-
-/**
- * This is an implementation of the 'decorator' design pattern using Java's proxy mechanism.
- *
- * @see android.hardware.camera2.utils.Decorator#newInstance
- *
- * @hide
- */
-public class Decorator<T> implements InvocationHandler {
-
- public interface DecoratorListener {
- /**
- * This method is called before the target method is invoked
- * @param args arguments to target method
- * @param m Method being called
- */
- void onBeforeInvocation(Method m, Object[] args);
- /**
- * This function is called after the target method is invoked
- * if there were no uncaught exceptions
- * @param args arguments to target method
- * @param m Method being called
- * @param result return value of target method
- */
- void onAfterInvocation(Method m, Object[] args, Object result);
- /**
- * This method is called only if there was an exception thrown by the target method
- * during its invocation.
- *
- * @param args arguments to target method
- * @param m Method being called
- * @param t Throwable that was thrown
- * @return false to rethrow exception, true if the exception was handled
- */
- boolean onCatchException(Method m, Object[] args, Throwable t);
- /**
- * This is called after the target method is invoked, regardless of whether or not
- * there were any exceptions.
- * @param args arguments to target method
- * @param m Method being called
- */
- void onFinally(Method m, Object[] args);
- }
-
- private final T mObject;
- private final DecoratorListener mListener;
-
- /**
- * Create a decorator wrapping the specified object's method calls.
- *
- * @param obj the object whose method calls you want to intercept
- * @param listener the decorator handler for intercepted method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a wrapped interface-compatible T
- */
- @SuppressWarnings("unchecked")
- public static<T> T newInstance(T obj, DecoratorListener listener) {
- return (T)java.lang.reflect.Proxy.newProxyInstance(
- obj.getClass().getClassLoader(),
- obj.getClass().getInterfaces(),
- new Decorator<T>(obj, listener));
- }
-
- private Decorator(T obj, DecoratorListener listener) {
- this.mObject = obj;
- this.mListener = listener;
- }
-
- @Override
- public Object invoke(Object proxy, Method m, Object[] args)
- throws Throwable
- {
- Object result = null;
- try {
- mListener.onBeforeInvocation(m, args);
- result = m.invoke(mObject, args);
- mListener.onAfterInvocation(m, args, result);
- } catch (InvocationTargetException e) {
- Throwable t = e.getTargetException();
- if (!mListener.onCatchException(m, args, t)) {
- throw t;
- }
- } finally {
- mListener.onFinally(m, args);
- }
- return result;
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/LongParcelable.aidl b/core/java/android/hardware/camera2/utils/LongParcelable.aidl
deleted file mode 100644
index 98ad1b2..0000000
--- a/core/java/android/hardware/camera2/utils/LongParcelable.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.utils;
-
-/** @hide */
-parcelable LongParcelable;
diff --git a/core/java/android/hardware/camera2/utils/SubmitInfo.java b/core/java/android/hardware/camera2/utils/SubmitInfo.java
new file mode 100644
index 0000000..d1692b5
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/SubmitInfo.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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.utils;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.hardware.camera2.ICameraDeviceUser;
+
+/**
+ * The status information returned for a successful capture request submission.
+ *
+ * Includes the request ID for the newly submitted capture request, and the
+ * last frame number of either the previous repeating request (for repeating
+ * requests), or of the request(s) just submitted (for single-shot capture).
+ *
+ * @hide
+ */
+public class SubmitInfo implements Parcelable {
+
+ private int mRequestId;
+ private long mLastFrameNumber;
+
+ public SubmitInfo() {
+ mRequestId = -1;
+ mLastFrameNumber = ICameraDeviceUser.NO_IN_FLIGHT_REPEATING_FRAMES;
+ }
+
+ public SubmitInfo(int requestId, long lastFrameNumber) {
+ mRequestId = requestId;
+ mLastFrameNumber = lastFrameNumber;
+ }
+
+ public static final Parcelable.Creator<SubmitInfo> CREATOR =
+ new Parcelable.Creator<SubmitInfo>() {
+ @Override
+ public SubmitInfo createFromParcel(Parcel in) {
+ return new SubmitInfo(in);
+ }
+
+ @Override
+ public SubmitInfo[] newArray(int size) {
+ return new SubmitInfo[size];
+ }
+ };
+
+ private SubmitInfo(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRequestId);
+ dest.writeLong(mLastFrameNumber);
+ }
+
+ public void readFromParcel(Parcel in) {
+ mRequestId = in.readInt();
+ mLastFrameNumber = in.readLong();
+ }
+
+ /**
+ * Return the request ID for the submitted capture request/burst.
+ *
+ * This is used to track the completion status of the requested captures,
+ * and to cancel repeating requests.
+ */
+ public int getRequestId() {
+ return mRequestId;
+ }
+
+ /**
+ * Return the last frame number for the submitted capture request/burst.
+ *
+ * For a repeating request, this is the last frame number of the _prior_
+ * repeating request, to indicate when to fire the sequence completion callback
+ * for the prior repeating request.
+ *
+ * For a single-shot capture, this is the last frame number of _this_
+ * burst, to indicate when to fire the sequence completion callback for the request itself.
+ *
+ * For a repeating request, may be NO_IN_FLIGHT_REPEATING_FRAMES, if no
+ * instances of a prior repeating request were actually issued to the camera device.
+ */
+ public long getLastFrameNumber() {
+ return mLastFrameNumber;
+ }
+
+}
diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java
index 20f237a5..04fca19 100644
--- a/core/java/android/os/ServiceSpecificException.java
+++ b/core/java/android/os/ServiceSpecificException.java
@@ -20,20 +20,23 @@
*
* <p>This exception includes an error code specific to the throwing
* service. This is mostly used by system services to indicate
- * domain specific error conditions.
+ * domain specific error conditions.</p>
+ *
+ * <p>Since these exceptions are designed to be passed through Binder
+ * interfaces, and to be generated by native-code Binder services,
+ * they do not support exception chaining.</p>
*
* @hide
*/
public class ServiceSpecificException extends RuntimeException {
public final int errorCode;
- ServiceSpecificException(int errorCode, String message) {
+ public ServiceSpecificException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
- ServiceSpecificException(int errorCode) {
+ public ServiceSpecificException(int errorCode) {
this.errorCode = errorCode;
}
}
-
diff --git a/core/java/android/view/Surface.aidl b/core/java/android/view/Surface.aidl
deleted file mode 100644
index 90bf37a..0000000
--- a/core/java/android/view/Surface.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/Surface.aidl
-**
-** Copyright 2007, 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.view;
-
-parcelable Surface;
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index ed3fe42..816a2c4 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -190,7 +190,6 @@
$(call include-path-for, bluedroid) \
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
- $(TOP)/frameworks/av/include \
$(TOP)/frameworks/base/media/jni \
$(TOP)/system/core/base/include \
$(TOP)/system/core/include \
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 7930027..afccfcf 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -33,9 +33,9 @@
#include "core_jni_helpers.h"
#include "android_runtime/android_hardware_camera2_CameraMetadata.h"
+#include <android/hardware/ICameraService.h>
#include <binder/IServiceManager.h>
#include <camera/CameraMetadata.h>
-#include <camera/ICameraService.h>
#include <camera/VendorTagDescriptor.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -906,32 +906,36 @@
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
const String16 NAME("media.camera");
- sp<ICameraService> cameraService;
+ sp<hardware::ICameraService> cameraService;
status_t err = getService(NAME, /*out*/&cameraService);
if (err != OK) {
ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
strerror(-err), err);
- return err;
+ return hardware::ICameraService::ERROR_DISCONNECTED;
}
- sp<VendorTagDescriptor> desc;
- err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
+ sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+ binder::Status res = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
- if (err == -EOPNOTSUPP) {
+ if (res.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_DEPRECATED_HAL) {
ALOGW("%s: Camera HAL too old; does not support vendor tags", __FUNCTION__);
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
return OK;
- } else if (err != OK) {
- ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)",
- __FUNCTION__, strerror(-err), err);
- return err;
+ } else if (!res.isOk()) {
+ ALOGE("%s: Failed to setup vendor tag descriptors: %s: %s",
+ __FUNCTION__, res.serviceSpecificErrorCode(),
+ res.toString8().string());
+ return res.serviceSpecificErrorCode();
}
err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
- return err;
+ if (err != OK) {
+ return hardware::ICameraService::ERROR_INVALID_OPERATION;
+ }
+ return OK;
}
} // extern "C"
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index cf68449..b7701d6 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -411,22 +411,27 @@
return 0;
}
+ android::view::Surface surfaceShim;
+
+ // Calling code in Surface.java has already read the name of the Surface
+ // from the Parcel
+ surfaceShim.readFromParcel(parcel, /*nameAlreadyRead*/true);
+
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
- sp<IBinder> binder(parcel->readStrongBinder());
// update the Surface only if the underlying IGraphicBufferProducer
// has changed.
- if (self != NULL
- && (IInterface::asBinder(self->getIGraphicBufferProducer()) == binder)) {
+ if (self != nullptr
+ && (IInterface::asBinder(self->getIGraphicBufferProducer()) ==
+ IInterface::asBinder(surfaceShim.graphicBufferProducer))) {
// same IGraphicBufferProducer, return ourselves
return jlong(self.get());
}
sp<Surface> sur;
- sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
- if (gbp != NULL) {
+ if (surfaceShim.graphicBufferProducer != nullptr) {
// we have a new IGraphicBufferProducer, create a new Surface for it
- sur = new Surface(gbp, true);
+ sur = new Surface(surfaceShim.graphicBufferProducer, true);
// and keep a reference before passing to java
sur->incStrong(&sRefBaseOwner);
}
@@ -447,7 +452,13 @@
return;
}
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
- parcel->writeStrongBinder( self != 0 ? IInterface::asBinder(self->getIGraphicBufferProducer()) : NULL);
+ android::view::Surface surfaceShim;
+ if (self != nullptr) {
+ surfaceShim.graphicBufferProducer = self->getIGraphicBufferProducer();
+ }
+ // Calling code in Surface.java has already written the name of the Surface
+ // to the Parcel
+ surfaceShim.writeToParcel(parcel, /*nameAlreadyWritten*/true);
}
static jint nativeGetWidth(JNIEnv* env, jclass clazz, jlong nativeObject) {
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index fa9c48c..29739ca 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -64,7 +64,6 @@
frameworks/av/media/mtp \
frameworks/native/include/media/openmax \
$(call include-path-for, libhardware)/hardware \
- system/media/camera/include \
$(PV_INCLUDES) \
$(JNI_H_INCLUDE)
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 701f7ac..922ad79 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -26,7 +26,6 @@
#include <utils/Log.h>
#include <gui/Surface.h>
-#include <camera/ICameraService.h>
#include <camera/Camera.h>
#include <media/mediarecorder.h>
#include <media/stagefright/PersistentSurface.h>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
index 61dede3..9be7004 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
@@ -60,10 +60,7 @@
}
private void addCameraUnitTests(TestSuite suite) {
- suite.addTestSuite(CameraUtilsDecoratorTest.class);
- suite.addTestSuite(CameraUtilsRuntimeExceptionTest.class);
suite.addTestSuite(CameraUtilsUncheckedThrowTest.class);
- suite.addTestSuite(CameraUtilsBinderDecoratorTest.class);
suite.addTestSuite(CameraUtilsTypeReferenceTest.class);
suite.addTestSuite(CameraMetadataTest.class);
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 6f74203..9a0946e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -19,16 +19,16 @@
import android.hardware.CameraInfo;
import android.hardware.ICamera;
import android.hardware.ICameraClient;
+import android.hardware.ICameraService;
import android.hardware.ICameraServiceListener;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
-import android.hardware.camera2.utils.BinderHolder;
-import android.hardware.camera2.utils.CameraBinderDecorator;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -84,14 +84,7 @@
public void testCameraInfo() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- CameraInfo info = new CameraInfo();
- info.info.facing = -1;
- info.info.orientation = -1;
-
- assertTrue(
- "Camera service returned info for camera " + cameraId,
- mUtils.getCameraService().getCameraInfo(cameraId, info) ==
- CameraBinderTestUtils.NO_ERROR);
+ CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId);
assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
assertTrue("Orientation was not set for camera " + cameraId,
info.info.orientation != -1);
@@ -105,20 +98,17 @@
public void testGetLegacyParameters() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- String[] parameters = new String[1];
- assertEquals("Camera service returned parameters for camera " + cameraId,
- CameraBinderTestUtils.NO_ERROR,
- mUtils.getCameraService().getLegacyParameters(cameraId, /*out*/parameters));
- assertNotNull(parameters[0]);
+ String parameters = mUtils.getCameraService().getLegacyParameters(cameraId);
+ assertNotNull(parameters);
assertTrue("Parameters should have at least one character in it",
- parameters[0].length() > 0);
+ parameters.length() > 0);
- int end = parameters[0].length();
+ int end = parameters.length();
if (end > MAX_PARAMETERS_LENGTH) {
end = MAX_PARAMETERS_LENGTH;
}
- Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters[0].substring(0, end));
+ Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end));
}
}
@@ -127,14 +117,8 @@
public void testSupportsCamera2Api() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
+ boolean supports = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
- if (res != CameraBinderTestUtils.NO_ERROR && res != -android.system.OsConstants.EOPNOTSUPP) {
- fail("Camera service returned bad value when queried if it supports camera2 api: "
- + res + " for camera ID " + cameraId);
- }
-
- boolean supports = res == CameraBinderTestUtils.NO_ERROR;
Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports);
}
}
@@ -144,10 +128,10 @@
public void testSupportsCamera1Api() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_1);
- assertEquals(
- "Camera service returned bad value when queried if it supports camera1 api: "
- + res + " for camera ID " + cameraId, CameraBinderTestUtils.NO_ERROR, res);
+ boolean supports = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_1);
+ assertTrue(
+ "Camera service returned false when queried if it supports camera1 api " +
+ " for camera ID " + cameraId, supports);
}
}
@@ -169,11 +153,10 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
+ ICamera cameraUser = mUtils.getCameraService()
.connect(dummyCallbacks, cameraId, clientPackageName,
- CameraBinderTestUtils.USE_CALLING_UID, holder);
- ICamera cameraUser = ICamera.Stub.asInterface(holder.getBinder());
+ ICameraService.USE_CALLING_UID,
+ ICameraService.USE_CALLING_PID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -191,14 +174,11 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
-
try {
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
+ cameraUser = mUtils.getCameraService()
.connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
- clientPackageName,
- CameraBinderTestUtils.USE_CALLING_UID, holder);
- cameraUser = ICamera.Stub.asInterface(holder.getBinder());
+ clientPackageName,
+ ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
@@ -284,11 +264,11 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
- .connectDevice(dummyCallbacks, cameraId,
- clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
- ICameraDeviceUser cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+ ICameraDeviceUser cameraUser =
+ mUtils.getCameraService().connectDevice(
+ dummyCallbacks, cameraId,
+ clientPackageName,
+ ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -323,27 +303,33 @@
ICameraServiceListener listener = new DummyCameraServiceListener();
- assertTrue(
- "Listener was removed before added",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.BAD_VALUE);
+ try {
+ mUtils.getCameraService().removeListener(listener);
+ fail("Listener was removed before added");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was removed before added",
+ e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
- assertTrue("Listener was not added",
- mUtils.getCameraService().addListener(listener) ==
- CameraBinderTestUtils.NO_ERROR);
- assertTrue(
- "Listener was wrongly added again",
- mUtils.getCameraService().addListener(listener) ==
- CameraBinderTestUtils.ALREADY_EXISTS);
+ mUtils.getCameraService().addListener(listener);
- assertTrue(
- "Listener was not removed",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.NO_ERROR);
- assertTrue(
- "Listener was wrongly removed again",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.BAD_VALUE);
+ try {
+ mUtils.getCameraService().addListener(listener);
+ fail("Listener was wrongly added again");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was wrongly added again",
+ e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
+ }
+
+ mUtils.getCameraService().removeListener(listener);
+
+ try {
+ mUtils.getCameraService().removeListener(listener);
+ fail("Listener was wrongly removed twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was wrongly removed twice",
+ e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
}
}
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
index 5c4b23b..38fc49f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
@@ -18,10 +18,6 @@
static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
- protected static final int USE_CALLING_UID = -1;
- protected static final int BAD_VALUE = -EINVAL;
- protected static final int INVALID_OPERATION = -ENOSYS;
- protected static final int ALREADY_EXISTS = -EEXIST;
public static final int NO_ERROR = 0;
private final Context mContext;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index d71b44b..5c1d8a7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -18,6 +18,7 @@
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
+import android.hardware.ICameraService;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -27,12 +28,13 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.BinderHolder;
+import android.hardware.camera2.utils.SubmitInfo;
import android.media.Image;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -164,11 +166,10 @@
}
private CaptureRequest.Builder createDefaultBuilder(boolean needStream) throws Exception {
- CameraMetadataNative metadata = new CameraMetadataNative();
+ CameraMetadataNative metadata = null;
assertTrue(metadata.isEmpty());
- int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
assertFalse(metadata.isEmpty());
CaptureRequest.Builder request = new CaptureRequest.Builder(metadata, /*reprocess*/false,
@@ -183,12 +184,13 @@
return request;
}
- private int submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
- int requestId = mCameraUser.submitRequest(request, streaming, null);
+ private SubmitInfo submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request, streaming);
assertTrue(
- "Request IDs should be non-negative (expected: >= 0, actual: " + requestId + ")",
- requestId >= 0);
- return requestId;
+ "Request IDs should be non-negative (expected: >= 0, actual: " +
+ requestInfo.getRequestId() + ")",
+ requestInfo.getRequestId() >= 0);
+ return requestInfo;
}
@Override
@@ -214,10 +216,8 @@
mMockCb = spy(dummyCallbacks);
- BinderHolder holder = new BinderHolder();
- mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
- clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
- mCameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+ mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
+ clientPackageName, ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
@@ -238,11 +238,10 @@
@SmallTest
public void testCreateDefaultRequest() throws Exception {
- CameraMetadataNative metadata = new CameraMetadataNative();
+ CameraMetadataNative metadata = null;
assertTrue(metadata.isEmpty());
- int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
assertFalse(metadata.isEmpty());
}
@@ -252,18 +251,28 @@
int streamId = mCameraUser.createStream(mOutputConfiguration);
assertEquals(0, streamId);
- assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
- mCameraUser.createStream(mOutputConfiguration));
+ try {
+ mCameraUser.createStream(mOutputConfiguration);
+ fail("Creating same stream twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Creating same stream twice",
+ e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
+ }
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
+ mCameraUser.deleteStream(streamId);
}
@SmallTest
public void testDeleteInvalidStream() throws Exception {
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(-1));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(1));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0xC0FFEE));
+ int[] badStreams = { -1, 0, 1, 0xC0FFEE };
+ for (int badStream : badStreams) {
+ try {
+ mCameraUser.deleteStream(badStream);
+ fail("Allowed bad stream delete");
+ } catch (ServiceSpecificException e) {
+ assertEquals(e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
+ }
}
@SmallTest
@@ -273,8 +282,13 @@
int streamId = mCameraUser.createStream(mOutputConfiguration);
assertEquals(0, streamId);
- assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
- mCameraUser.createStream(mOutputConfiguration));
+ try {
+ mCameraUser.createStream(mOutputConfiguration);
+ fail("Created same stream twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Created same stream twice",
+ ICameraService.ERROR_ALREADY_EXISTS, e.errorCode);
+ }
// Create second stream with a different surface.
SurfaceTexture surfaceTexture = new SurfaceTexture(/* ignored */0);
@@ -286,8 +300,8 @@
assertEquals(1, streamId2);
// Clean up streams
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId2));
+ mCameraUser.deleteStream(streamId);
+ mCameraUser.deleteStream(streamId2);
}
@SmallTest
@@ -295,16 +309,25 @@
CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */false);
CaptureRequest request1 = builder.build();
- int status = mCameraUser.submitRequest(request1, /* streaming */false, null);
- assertEquals("Expected submitRequest to return BAD_VALUE " +
- "since we had 0 surface targets set.", CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request1, /* streaming */false);
+ fail("Exception expected");
+ } catch(ServiceSpecificException e) {
+ assertEquals("Expected submitRequest to throw ServiceSpecificException with BAD_VALUE " +
+ "since we had 0 surface targets set.", ICameraService.ERROR_ILLEGAL_ARGUMENT,
+ e.errorCode);
+ }
builder.addTarget(mSurface);
CaptureRequest request2 = builder.build();
- status = mCameraUser.submitRequest(request2, /* streaming */false, null);
- assertEquals("Expected submitRequest to return BAD_VALUE since " +
- "the target surface wasn't registered with createStream.",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request2, /* streaming */false);
+ fail("Exception expected");
+ } catch(ServiceSpecificException e) {
+ assertEquals("Expected submitRequest to throw ILLEGAL_ARGUMENT " +
+ "ServiceSpecificException since the target wasn't registered with createStream.",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
}
@SmallTest
@@ -314,9 +337,10 @@
CaptureRequest request = builder.build();
// Submit valid request twice.
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- assertNotSame("Request IDs should be unique for multiple requests", requestId1, requestId2);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ assertNotSame("Request IDs should be unique for multiple requests",
+ requestInfo1.getRequestId(), requestInfo2.getRequestId());
}
@@ -329,32 +353,35 @@
// Submit valid request once (non-streaming), and another time
// (streaming)
- int requestId1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
- int requestIdStreaming = submitCameraRequest(request, /* streaming */true);
- assertNotSame("Request IDs should be unique for multiple requests", requestId1,
- requestIdStreaming);
+ SubmitInfo requestInfoStreaming = submitCameraRequest(request, /* streaming */true);
+ assertNotSame("Request IDs should be unique for multiple requests",
+ requestInfo1.getRequestId(),
+ requestInfoStreaming.getRequestId());
- int status = mCameraUser.cancelRequest(-1, null);
- assertEquals("Invalid request IDs should not be cancellable",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ long lastFrameNumber = mCameraUser.cancelRequest(-1);
+ fail("Expected exception");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Invalid request IDs should not be cancellable",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
- status = mCameraUser.cancelRequest(requestId1, null);
- assertEquals("Non-streaming request IDs should not be cancellable",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfo1.getRequestId());
+ fail("Expected exception");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Non-streaming request IDs should not be cancellable",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
- status = mCameraUser.cancelRequest(requestIdStreaming, null);
- assertEquals("Streaming request IDs should be cancellable", CameraBinderTestUtils.NO_ERROR,
- status);
-
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
}
@SmallTest
public void testCameraInfo() throws RemoteException {
- CameraMetadataNative info = new CameraMetadataNative();
-
- int status = mCameraUser.getCameraInfo(/*out*/info);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ CameraMetadataNative info = mCameraUser.getCameraInfo();
assertFalse(info.isEmpty());
assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
@@ -362,10 +389,7 @@
@SmallTest
public void testCameraCharacteristics() throws RemoteException {
- CameraMetadataNative info = new CameraMetadataNative();
-
- int status = mUtils.getCameraService().getCameraCharacteristics(mCameraId, /*out*/info);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId);
assertFalse(info.isEmpty());
assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
@@ -374,18 +398,19 @@
@SmallTest
public void testWaitUntilIdle() throws Exception {
CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
- int requestIdStreaming = submitCameraRequest(builder.build(), /* streaming */true);
+ SubmitInfo requestInfoStreaming = submitCameraRequest(builder.build(), /* streaming */true);
// Test Bad case first: waitUntilIdle when there is active repeating request
- int status = mCameraUser.waitUntilIdle();
- assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
- CameraBinderTestUtils.INVALID_OPERATION, status);
+ try {
+ mCameraUser.waitUntilIdle();
+ } catch (ServiceSpecificException e) {
+ assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
+ ICameraService.ERROR_INVALID_OPERATION, e.errorCode);
+ }
// Test good case, waitUntilIdle when there is no active repeating request
- status = mCameraUser.cancelRequest(requestIdStreaming, null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
- status = mCameraUser.waitUntilIdle();
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
+ mCameraUser.waitUntilIdle();
}
@SmallTest
@@ -411,12 +436,12 @@
ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
// Test both single request and streaming request.
- int requestId1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onCaptureStarted(
any(CaptureResultExtras.class),
anyLong());
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
.onCaptureStarted(
any(CaptureResultExtras.class),
@@ -436,22 +461,22 @@
CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
// Try streaming
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
// Wait a bit to fill up the queue
SystemClock.sleep(WAIT_FOR_WORK_MS);
// Cancel and make sure we eventually quiesce
- status = mCameraUser.cancelRequest(streamingId, null);
+ long lastFrameNumber = mCameraUser.cancelRequest(streamingInfo.getRequestId());
verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onDeviceIdle();
// Submit a few capture requests
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- int requestId3 = submitCameraRequest(request, /* streaming */false);
- int requestId4 = submitCameraRequest(request, /* streaming */false);
- int requestId5 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
// And wait for more idle
verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onDeviceIdle();
@@ -463,38 +488,34 @@
int status;
// Initial flush should work
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ long lastFrameNumber = mCameraUser.flush();
// Then set up a stream
CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
// Flush should still be a no-op, really
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
// Submit a few capture requests
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- int requestId3 = submitCameraRequest(request, /* streaming */false);
- int requestId4 = submitCameraRequest(request, /* streaming */false);
- int requestId5 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
// Then flush and wait for idle
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onDeviceIdle();
// Now a streaming request
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
// Wait a bit to fill up the queue
SystemClock.sleep(WAIT_FOR_WORK_MS);
// Then flush and wait for the idle callback
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onDeviceIdle();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
deleted file mode 100644
index 33c6388..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.mediaframeworktest.unit;
-
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-import android.os.TransactionTooLargeException;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import static org.mockito.Mockito.*;
-import static android.hardware.camera2.utils.CameraBinderDecorator.*;
-import static android.hardware.camera2.CameraAccessException.*;
-import static android.system.OsConstants.*;
-
-import junit.framework.Assert;
-
-public class CameraUtilsBinderDecoratorTest extends junit.framework.TestCase {
-
- private interface ICameraBinderStereotype {
-
- double doNothing();
-
- // int is a 'status_t'
- int doSomethingPositive();
-
- int doSomethingNoError();
-
- int doSomethingPermissionDenied();
-
- int doSomethingAlreadyExists();
-
- int doSomethingBadValue();
-
- int doSomethingDeadObject() throws CameraRuntimeException;
-
- int doSomethingBadPolicy() throws CameraRuntimeException;
-
- int doSomethingDeviceBusy() throws CameraRuntimeException;
-
- int doSomethingNoSuchDevice() throws CameraRuntimeException;
-
- int doSomethingUnknownErrorCode();
-
- int doSomethingThrowDeadObjectException() throws RemoteException;
-
- int doSomethingThrowTransactionTooLargeException() throws RemoteException;
- }
-
- private static final double SOME_ARBITRARY_DOUBLE = 1.0;
- private static final int SOME_ARBITRARY_POSITIVE_INT = 5;
- private static final int SOME_ARBITRARY_NEGATIVE_INT = -0xC0FFEE;
-
- @SmallTest
- public void testStereotypes() {
-
- ICameraBinderStereotype mock = mock(ICameraBinderStereotype.class);
- try {
- when(mock.doNothing()).thenReturn(SOME_ARBITRARY_DOUBLE);
- when(mock.doSomethingPositive()).thenReturn(SOME_ARBITRARY_POSITIVE_INT);
- when(mock.doSomethingNoError()).thenReturn(NO_ERROR);
- when(mock.doSomethingPermissionDenied()).thenReturn(PERMISSION_DENIED);
- when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
- when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
- when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
- when(mock.doSomethingBadPolicy()).thenReturn(-EACCES);
- when(mock.doSomethingDeviceBusy()).thenReturn(-EBUSY);
- when(mock.doSomethingNoSuchDevice()).thenReturn(-ENODEV);
- when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
- when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
- when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
- new TransactionTooLargeException());
- } catch (RemoteException e) {
- Assert.fail("Unreachable");
- }
-
- ICameraBinderStereotype decoratedMock = CameraBinderDecorator.newInstance(mock);
-
- // ignored by decorator because return type is double, not int
- assertEquals(SOME_ARBITRARY_DOUBLE, decoratedMock.doNothing());
-
- // pass through for positive values
- assertEquals(SOME_ARBITRARY_POSITIVE_INT, decoratedMock.doSomethingPositive());
-
- // pass through NO_ERROR
- assertEquals(NO_ERROR, decoratedMock.doSomethingNoError());
-
- try {
- decoratedMock.doSomethingPermissionDenied();
- Assert.fail("Should've thrown SecurityException");
- } catch (SecurityException e) {
- }
-
- assertEquals(ALREADY_EXISTS, decoratedMock.doSomethingAlreadyExists());
-
- try {
- decoratedMock.doSomethingBadValue();
- Assert.fail("Should've thrown IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- decoratedMock.doSomethingDeadObject();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingBadPolicy();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISABLED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingDeviceBusy();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_IN_USE, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingNoSuchDevice();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingUnknownErrorCode();
- Assert.fail("Should've thrown UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertEquals(String.format("Unknown error %d",
- SOME_ARBITRARY_NEGATIVE_INT), e.getMessage());
- }
-
- try {
- decoratedMock.doSomethingThrowDeadObjectException();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- } catch (RemoteException e) {
- Assert.fail("Should not throw a DeadObjectException directly, but rethrow");
- }
-
- try {
- decoratedMock.doSomethingThrowTransactionTooLargeException();
- Assert.fail("Should've thrown UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertTrue(e.getCause() instanceof TransactionTooLargeException);
- } catch (RemoteException e) {
- Assert.fail("Should not throw a TransactionTooLargeException directly, but rethrow");
- }
- }
-
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
deleted file mode 100644
index c3b6006..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.mediaframeworktest.unit;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.hardware.camera2.utils.*;
-import android.hardware.camera2.utils.Decorator.DecoratorListener;
-
-import junit.framework.Assert;
-
-import java.lang.reflect.Method;
-
-/**
- * adb shell am instrument -e class 'com.android.mediaframeworktest.unit.CameraUtilsDecoratorTest' \
- * -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
- */
-public class CameraUtilsDecoratorTest extends junit.framework.TestCase {
- private DummyListener mDummyListener;
- private DummyInterface mIface;
-
- @Override
- public void setUp() {
- mDummyListener = new DummyListener();
- mIface = Decorator.newInstance(new DummyImpl(), mDummyListener);
- }
-
- interface DummyInterface {
- int addValues(int x, int y, int z);
-
- void raiseException() throws Exception;
-
- void raiseUnsupportedOperationException() throws UnsupportedOperationException;
- }
-
- class DummyImpl implements DummyInterface {
- @Override
- public int addValues(int x, int y, int z) {
- return x + y + z;
- }
-
- @Override
- public void raiseException() throws Exception {
- throw new Exception("Test exception");
- }
-
- @Override
- public void raiseUnsupportedOperationException() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Test exception");
- }
- }
-
- class DummyListener implements DecoratorListener {
-
- public boolean beforeCalled = false;
- public boolean afterCalled = false;
- public boolean catchCalled = false;
- public boolean finallyCalled = false;
- public Object resultValue = null;
-
- public boolean raiseException = false;
-
- @Override
- public void onBeforeInvocation(Method m, Object[] args) {
- beforeCalled = true;
- }
-
- @Override
- public void onAfterInvocation(Method m, Object[] args, Object result) {
- afterCalled = true;
- resultValue = result;
-
- if (raiseException) {
- throw new UnsupportedOperationException("Test exception");
- }
- }
-
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
- catchCalled = true;
- return false;
- }
-
- @Override
- public void onFinally(Method m, Object[] args) {
- finallyCalled = true;
- }
-
- };
-
- @SmallTest
- public void testDecorator() {
-
- // TODO rewrite this using mocks
-
- assertTrue(mIface.addValues(1, 2, 3) == 6);
- assertTrue(mDummyListener.beforeCalled);
- assertTrue(mDummyListener.afterCalled);
-
- int resultValue = (Integer)mDummyListener.resultValue;
- assertTrue(resultValue == 6);
- assertTrue(mDummyListener.finallyCalled);
- assertFalse(mDummyListener.catchCalled);
- }
-
- @SmallTest
- public void testDecoratorExceptions() {
-
- boolean gotExceptions = false;
- try {
- mIface.raiseException();
- } catch (Exception e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertFalse(mDummyListener.afterCalled);
- assertTrue(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-
- @SmallTest
- public void testDecoratorUnsupportedOperationException() {
-
- boolean gotExceptions = false;
- try {
- mIface.raiseUnsupportedOperationException();
- } catch (UnsupportedOperationException e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertFalse(mDummyListener.afterCalled);
- assertTrue(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-
- @SmallTest
- public void testDecoratorRaisesException() {
-
- boolean gotExceptions = false;
- try {
- mDummyListener.raiseException = true;
- mIface.addValues(1, 2, 3);
- Assert.fail("unreachable");
- } catch (UnsupportedOperationException e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertTrue(mDummyListener.afterCalled);
- assertFalse(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
deleted file mode 100644
index 02c9f2a..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.mediaframeworktest.unit;
-
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.UncheckedThrow;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.Assert;
-
-public class CameraUtilsRuntimeExceptionTest extends junit.framework.TestCase {
-
- @SmallTest
- public void testCameraRuntimeException1() {
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertNull(e.getMessage());
- assertNull(e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException2() {
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello");
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertEquals("Hello", e.getMessage());
- assertNull(e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException3() {
- Throwable cause = new IllegalStateException("For great justice");
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, cause);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertNull(e.getMessage());
- assertEquals(cause, e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException4() {
- Throwable cause = new IllegalStateException("For great justice");
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello", cause);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertEquals("Hello", e.getMessage());
- assertEquals(cause, e.getCause());
- }
- }
-}
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index f82454a..cd8eb4e 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -60,10 +60,6 @@
public static final String CAMERA_SERVICE_PROXY_BINDER_NAME = "media.camera.proxy";
- // Event arguments to use with the camera service notifySystemEvent call:
- public static final int NO_EVENT = 0; // NOOP
- public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
-
// State arguments to use with the notifyCameraState call from camera service:
public static final int CAMERA_STATE_OPEN = 0;
public static final int CAMERA_STATE_ACTIVE = 1;
@@ -224,7 +220,7 @@
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
mEnabledCameraUsers = currentUserHandles;
- notifyMediaserverLocked(USER_SWITCHED, currentUserHandles);
+ notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, currentUserHandles);
}
}
@@ -244,7 +240,7 @@
if (mEnabledCameraUsers == null) {
return;
}
- if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
+ if (notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, mEnabledCameraUsers)) {
retries = 0;
}
}