diff options
author | Igor Murashkin <iam@google.com> | 2013-06-25 05:15:02 +0000 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2013-06-25 05:15:02 +0000 |
commit | a858308ed2c950fe800abeefcb845b9c3197a2f3 (patch) | |
tree | 4147ceb253ea4474df716db3ae51ddbaf4afe646 /core/java/android/hardware | |
parent | e473f7d8f96b5682141522378b761913192d8114 (diff) | |
download | frameworks_base-a858308ed2c950fe800abeefcb845b9c3197a2f3.zip frameworks_base-a858308ed2c950fe800abeefcb845b9c3197a2f3.tar.gz frameworks_base-a858308ed2c950fe800abeefcb845b9c3197a2f3.tar.bz2 |
Revert "Partial CameraManager implementation"
This reverts commit e473f7d8f96b5682141522378b761913192d8114.
Change-Id: I23e92ca2def0ebf507f6c782442a4698745bc926
Diffstat (limited to 'core/java/android/hardware')
7 files changed, 10 insertions, 614 deletions
diff --git a/core/java/android/hardware/photography/CameraAccessException.java b/core/java/android/hardware/photography/CameraAccessException.java index fac5086..01114df 100644 --- a/core/java/android/hardware/photography/CameraAccessException.java +++ b/core/java/android/hardware/photography/CameraAccessException.java @@ -16,8 +16,6 @@ package android.hardware.photography; -import android.util.AndroidException; - /** * <p><code>CameraAccessException</code> is thrown if a camera device could not * be queried or opened by the {@link CameraManager}, or if the connection to an @@ -26,7 +24,7 @@ import android.util.AndroidException; * @see CameraManager * @see CameraDevice */ -public class CameraAccessException extends AndroidException { +public class CameraAccessException extends Exception { /** * The camera device is in use already */ @@ -53,10 +51,7 @@ public class CameraAccessException extends AndroidException { */ public static final int CAMERA_DISCONNECTED = 4; - // Make the eclipse warning about serializable exceptions go away - private static final long serialVersionUID = 5630338637471475675L; // randomly generated - - private final int mReason; + private int mReason; /** * The reason for the failure to access the camera. @@ -71,7 +66,6 @@ public class CameraAccessException extends AndroidException { } public CameraAccessException(int problem) { - super(getDefaultMessage(problem)); mReason = problem; } @@ -86,25 +80,7 @@ public class CameraAccessException extends AndroidException { } public CameraAccessException(int problem, Throwable cause) { - super(getDefaultMessage(problem), cause); + super(cause); mReason = problem; } - - private static String getDefaultMessage(int problem) { - switch (problem) { - case CAMERA_IN_USE: - return "The camera device is in use already"; - case MAX_CAMERAS_IN_USE: - return "The system-wide limit for number of open cameras has been reached, " + - "and more camera devices cannot be opened until previous instances " + - "are closed."; - case CAMERA_DISABLED: - return "The camera is disabled due to a device policy, and cannot be opened."; - case CAMERA_DISCONNECTED: - return "The camera device is removable and has been disconnected from the Android" + - " device, or the camera service has shut down the connection due to a " + - "higher-priority access request for the camera device."; - } - return null; - } } diff --git a/core/java/android/hardware/photography/CameraDevice.java b/core/java/android/hardware/photography/CameraDevice.java index e94e3a1..2062db2 100644 --- a/core/java/android/hardware/photography/CameraDevice.java +++ b/core/java/android/hardware/photography/CameraDevice.java @@ -17,10 +17,8 @@ package android.hardware.photography; import android.graphics.ImageFormat; -import android.os.IBinder; import android.renderscript.Allocation; import android.renderscript.RenderScript; -import android.util.Log; import android.view.Surface; import java.lang.AutoCloseable; @@ -103,8 +101,6 @@ public final class CameraDevice implements AutoCloseable { */ public static final int TEMPLATE_MANUAL = 5; - private static final String TAG = "CameraDevice"; - /** * Get the static properties for this camera. These are identical to the * properties returned by {@link CameraManager#getCameraProperties}. @@ -455,7 +451,6 @@ public final class CameraDevice implements AutoCloseable { * the camera device interface will throw a {@link IllegalStateException}, * except for calls to close(). */ - @Override public void close() { } @@ -557,11 +552,4 @@ public final class CameraDevice implements AutoCloseable { public void onCameraDeviceError(CameraDevice camera, int error); } - /** - * @hide - */ - public CameraDevice(IBinder binder) { - Log.e(TAG, "CameraDevice constructor not implemented yet"); - } - } diff --git a/core/java/android/hardware/photography/CameraManager.java b/core/java/android/hardware/photography/CameraManager.java index 115f151..328ba4b 100644 --- a/core/java/android/hardware/photography/CameraManager.java +++ b/core/java/android/hardware/photography/CameraManager.java @@ -16,22 +16,6 @@ package android.hardware.photography; -import android.content.Context; -import android.hardware.ICameraService; -import android.hardware.ICameraServiceListener; -import android.hardware.IProCameraUser; -import android.hardware.photography.utils.CameraBinderDecorator; -import android.hardware.photography.utils.CameraRuntimeException; -import android.os.Binder; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.util.Log; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; - /** * <p>An interface for iterating, listing, and connecting to * {@link CameraDevice CameraDevices}.</p> @@ -48,40 +32,9 @@ import java.util.HashSet; public final class CameraManager { /** - * This should match the ICameraService definition - */ - private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera"; - private static final int USE_CALLING_UID = -1; - - private final ICameraService mCameraService; - private ArrayList<String> mDeviceIdList; - private HashSet<CameraListener> mListenerSet; - private final Context mContext; - private final Object mLock = new Object(); - - /** * @hide */ - public CameraManager(Context context) { - mContext = context; - - IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME); - ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); - - /** - * Wrap the camera service in a decorator which automatically translates return codes - * into exceptions, and RemoteExceptions into other exceptions. - */ - mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw); - - try { - mCameraService.addListener(new CameraServiceListener()); - } catch(CameraRuntimeException e) { - throw new IllegalStateException("Failed to register a camera service listener", - e.asChecked()); - } catch (RemoteException e) { - // impossible - } + public CameraManager() { } /** @@ -92,37 +45,25 @@ public final class CameraManager { * * @return The list of currently connected camera devices. */ - public String[] getDeviceIdList() throws CameraAccessException { - synchronized (mLock) { - return (String[]) getOrCreateDeviceIdListLocked().toArray(); - } + public String[] getDeviceIdList() { + return null; } /** * Register a listener to be notified about camera device availability. * - * Registering a listener more than once has no effect. - * - * @param listener the new listener to send camera availability notices to. + * @param listener the new listener to send camera availablity notices to. */ public void registerCameraListener(CameraListener listener) { - synchronized (mLock) { - mListenerSet.add(listener); - } } /** * Remove a previously-added listener; the listener will no longer receive * connection and disconnection callbacks. * - * Removing a listener that isn't registered has no effect. - * * @param listener the listener to remove from the notification list */ public void unregisterCameraListener(CameraListener listener) { - synchronized (mLock) { - mListenerSet.remove(listener); - } } /** @@ -143,18 +84,7 @@ public final class CameraManager { */ public CameraProperties getCameraProperties(String cameraId) throws CameraAccessException { - - synchronized (mLock) { - if (!getOrCreateDeviceIdListLocked().contains(cameraId)) { - throw new IllegalArgumentException(String.format("Camera id %s does not match any" + - " currently connected camera device", cameraId)); - } - } - - // TODO: implement and call a service function to get the capabilities on C++ side - - // TODO: get properties from service - return new CameraProperties(); + throw new IllegalArgumentException(); } /** @@ -177,33 +107,7 @@ public final class CameraManager { * @see android.app.admin.DevicePolicyManager#setCameraDisabled */ public CameraDevice openCamera(String cameraId) throws CameraAccessException { - - try { - IProCameraUser cameraUser; - - synchronized (mLock) { - // TODO: Use ICameraDevice or some such instead of this... - cameraUser = mCameraService.connectPro(null, - Integer.parseInt(cameraId), - mContext.getPackageName(), USE_CALLING_UID); - - } - - return new CameraDevice(cameraUser.asBinder()); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: " - + cameraId); - } catch (CameraRuntimeException e) { - if (e.getReason() == CameraAccessException.CAMERA_DISCONNECTED) { - throw new IllegalArgumentException("Invalid camera ID specified -- " + - "perhaps the camera was physically disconnected", e); - } else { - throw e.asChecked(); - } - } catch (RemoteException e) { - // impossible - return null; - } + throw new IllegalArgumentException(); } /** @@ -231,135 +135,4 @@ public final class CameraManager { */ public void onCameraUnavailable(String cameraId); } - - private ArrayList<String> getOrCreateDeviceIdListLocked() throws CameraAccessException { - if (mDeviceIdList == null) { - int numCameras = 0; - - try { - numCameras = mCameraService.getNumberOfCameras(); - } catch(CameraRuntimeException e) { - throw e.asChecked(); - } catch (RemoteException e) { - // impossible - return null; - } - - mDeviceIdList = new ArrayList<String>(); - for (int i = 0; i < numCameras; ++i) { - // Non-removable cameras use integers starting at 0 for their - // identifiers - mDeviceIdList.add(String.valueOf(i)); - } - - } - return mDeviceIdList; - } - - // TODO: this class needs unit tests - // TODO: extract class into top level - private class CameraServiceListener extends Binder implements ICameraServiceListener { - - // 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; - - // Camera ID -> Status map - private final HashMap<String, Integer> mDeviceStatus = new HashMap<String, Integer>(); - - private static final String TAG = "CameraServiceListener"; - - @Override - public IBinder asBinder() { - return this; - } - - private boolean isAvailable(int status) { - switch (status) { - case STATUS_PRESENT: - return true; - default: - return false; - } - } - - private boolean validStatus(int status) { - switch (status) { - case STATUS_NOT_PRESENT: - case STATUS_PRESENT: - case STATUS_ENUMERATING: - case STATUS_NOT_AVAILABLE: - return true; - default: - return false; - } - } - - @Override - public void onStatusChanged(int status, int cameraId) throws RemoteException { - synchronized(CameraManager.this) { - - Log.v(TAG, - String.format("Camera id %d has status changed to 0x%x", cameraId, status)); - - String id = String.valueOf(cameraId); - - if (!validStatus(status)) { - Log.e(TAG, String.format("Ignoring invalid device %d status 0x%x", cameraId, - status)); - return; - } - - Integer oldStatus = mDeviceStatus.put(id, status); - - if (oldStatus == status) { - Log.v(TAG, String.format( - "Device status changed to 0x%x, which is what it already was", - status)); - return; - } - - // TODO: consider abstracting out this state minimization + transition - // into a separate - // more easily testable class - // i.e. (new State()).addState(STATE_AVAILABLE) - // .addState(STATE_NOT_AVAILABLE) - // .addTransition(STATUS_PRESENT, STATE_AVAILABLE), - // .addTransition(STATUS_NOT_PRESENT, STATE_NOT_AVAILABLE) - // .addTransition(STATUS_ENUMERATING, STATE_NOT_AVAILABLE); - // .addTransition(STATUS_NOT_AVAILABLE, STATE_NOT_AVAILABLE); - - // Translate all the statuses to either 'available' or 'not available' - // available -> available => no new update - // not available -> not available => no new update - if (oldStatus != null && isAvailable(status) == isAvailable(oldStatus)) { - - Log.v(TAG, - String.format( - "Device status was previously available (%d), " + - " and is now again available (%d)" + - "so no new client visible update will be sent", - isAvailable(status), isAvailable(status))); - return; - } - - for (CameraListener listener : mListenerSet) { - if (isAvailable(status)) { - listener.onCameraAvailable(id); - } else { - listener.onCameraUnavailable(id); - } - } // for - } // synchronized - } // onStatusChanged - } // CameraServiceListener -} // CameraManager +} diff --git a/core/java/android/hardware/photography/utils/CameraBinderDecorator.java b/core/java/android/hardware/photography/utils/CameraBinderDecorator.java deleted file mode 100644 index 99e7c78..0000000 --- a/core/java/android/hardware/photography/utils/CameraBinderDecorator.java +++ /dev/null @@ -1,146 +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.photography.utils; - -import static android.hardware.photography.CameraAccessException.CAMERA_DISABLED; -import static android.hardware.photography.CameraAccessException.CAMERA_DISCONNECTED; -import static android.hardware.photography.CameraAccessException.CAMERA_IN_USE; - -import android.os.DeadObjectException; -import android.os.RemoteException; - -import java.lang.reflect.Method; - -/** - * Translate camera service status_t return values into exceptions. - * - * @see android.hardware.photography.utils.CameraBinderDecorator#newInstance - * @hide - */ -public class CameraBinderDecorator { - - public static final int NO_ERROR = 0; - public static final int PERMISSION_DENIED = -1; - public static final int ALREADY_EXISTS = -17; - public static final int BAD_VALUE = -22; - public static final int DEAD_OBJECT = -32; - - /** - * TODO: add as error codes in Errors.h - * - POLICY_PROHIBITS - * - RESOURCE_BUSY - * - NO_SUCH_DEVICE - */ - public static final int EACCES = -13; - public static final int EBUSY = -16; - public static final int ENODEV = -19; - - private 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; - - switch (returnValue) { - case NO_ERROR: - return; - case PERMISSION_DENIED: - throw new SecurityException("Lacking privileges to access camera service"); - case ALREADY_EXISTS: - return; - case BAD_VALUE: - throw new IllegalArgumentException("Bad argument passed to camera service"); - case DEAD_OBJECT: - UncheckedThrow.throwAnyException(new CameraRuntimeException( - CAMERA_DISCONNECTED)); - // TODO: Camera service (native side) should return - // EACCES error - // when there's a policy manager disabled causing this - case EACCES: - UncheckedThrow.throwAnyException(new CameraRuntimeException( - CAMERA_DISABLED)); - case EBUSY: - UncheckedThrow.throwAnyException(new CameraRuntimeException( - CAMERA_IN_USE)); - case ENODEV: - UncheckedThrow.throwAnyException(new CameraRuntimeException( - CAMERA_DISCONNECTED)); - } - - /** - * 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 (returnValue < 0) { - throw new UnsupportedOperationException(String.format("Unknown error %d", - returnValue)); - } - } - } - - @Override - public boolean onCatchException(Method m, Object[] args, Throwable t) { - - if (t instanceof DeadObjectException) { - UncheckedThrow.throwAnyException(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) { - } - - } - - /** - * <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/photography/utils/CameraRuntimeException.java b/core/java/android/hardware/photography/utils/CameraRuntimeException.java deleted file mode 100644 index 25dfc62..0000000 --- a/core/java/android/hardware/photography/utils/CameraRuntimeException.java +++ /dev/null @@ -1,63 +0,0 @@ -package android.hardware.photography.utils; - -import android.hardware.photography.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/photography/utils/Decorator.java b/core/java/android/hardware/photography/utils/Decorator.java deleted file mode 100644 index ed05dd2..0000000 --- a/core/java/android/hardware/photography/utils/Decorator.java +++ /dev/null @@ -1,92 +0,0 @@ - -package android.hardware.photography.utils; - -import java.lang.reflect.*; - -/** - * This is an implementation of the 'decorator' design pattern using Java's proxy mechanism. - * - * @see android.hardware.photography.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/photography/utils/UncheckedThrow.java b/core/java/android/hardware/photography/utils/UncheckedThrow.java deleted file mode 100644 index 8eed6b1..0000000 --- a/core/java/android/hardware/photography/utils/UncheckedThrow.java +++ /dev/null @@ -1,40 +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.photography.utils; - -/** - * @hide - */ -public class UncheckedThrow { - - /** - * Throw any kind of exception without needing it to be checked - * @param e any instance of a Exception - */ - public static void throwAnyException(Exception e) { - /** - * Abuse type erasure by making the compiler think we are throwing RuntimeException, - * which is unchecked, but then inserting any exception in there. - */ - UncheckedThrow.<RuntimeException>throwAnyImpl(e); - } - - @SuppressWarnings("unchecked") - private static<T extends Exception> void throwAnyImpl(Exception e) throws T { - throw (T) e; - } -} |