Loading core/java/android/hardware/camera2/CameraCaptureSession.java +28 −16 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.List; public abstract class CameraCaptureSession implements AutoCloseable { /** * Get the camera device that this session is created for * Get the camera device that this session is created for. */ public abstract CameraDevice getDevice(); Loading Loading @@ -90,8 +90,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException if the request targets Surfaces that are not configured as * outputs for this session. Or if the handler is null, the * listener is not null, and the calling thread has no looper. Loading @@ -99,6 +100,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #captureBurst * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #abortCaptures */ public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -132,8 +134,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests target Surfaces not currently configured as * outputs. Or if the handler is null, the listener is not * null, and the calling thread has no looper. Loading @@ -141,6 +144,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #capture * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #abortCaptures */ public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -188,11 +192,13 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces that are not currently * configured as outputs. Or if the handler is null, the * listener is not null, and the calling thread has no looper. * Or if no requests were passed in. * * @see #capture * @see #captureBurst Loading Loading @@ -246,11 +252,13 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces not currently configured * as outputs. Or if the handler is null, the listener is not * null, and the calling thread has no looper. * null, and the calling thread has no looper. Or if no * requests were passed in. * * @see #capture * @see #captureBurst Loading @@ -274,8 +282,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * * @see #setRepeatingRequest * @see #setRepeatingBurst Loading Loading @@ -308,8 +317,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * * @see #setRepeatingRequest * @see #setRepeatingBurst Loading @@ -320,8 +330,8 @@ public abstract class CameraCaptureSession implements AutoCloseable { /** * Close this capture session asynchronously. * * <p>Closing a session frees up the target output Surfaces of the session for reuse with either a * new session, or to other APIs that can draw to Surfaces.</p> * <p>Closing a session frees up the target output Surfaces of the session for reuse with either * a new session, or to other APIs that can draw to Surfaces.</p> * * <p>Note that creating a new capture session with {@link CameraDevice#createCaptureSession} * will close any existing capture session automatically, and call the older session listener's Loading @@ -334,6 +344,8 @@ public abstract class CameraCaptureSession implements AutoCloseable { * However, any in-progress capture requests submitted to the session will be completed as * normal; once all captures have completed and the session has been torn down, * {@link StateListener#onClosed} will be called.</p> * * <p>Closing a session is idempotent; closing more than once has no effect.</p> */ @Override public abstract void close(); Loading core/java/android/hardware/camera2/CameraDevice.java +16 −2 Original line number Diff line number Diff line Loading @@ -244,6 +244,7 @@ public interface CameraDevice extends AutoCloseable { * @see StreamConfigurationMap#getOutputSizes(Class) * @deprecated Use {@link #createCaptureSession} instead */ @Deprecated public void configureOutputs(List<Surface> outputs) throws CameraAccessException; /** Loading Loading @@ -432,6 +433,7 @@ public interface CameraDevice extends AutoCloseable { * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int capture(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -470,13 +472,15 @@ public interface CameraDevice extends AutoCloseable { * or the camera device has been closed. * @throws IllegalArgumentException If the requests target Surfaces not * currently configured as outputs. Or if the handler is null, the listener * is not null, and the calling thread has no looper. * is not null, and the calling thread has no looper. Or if no requests were * passed in. * * @see #capture * @see #setRepeatingRequest * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int captureBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -536,6 +540,7 @@ public interface CameraDevice extends AutoCloseable { * @see #flush * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int setRepeatingRequest(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -586,7 +591,8 @@ public interface CameraDevice extends AutoCloseable { * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces not * currently configured as outputs. Or if the handler is null, the listener * is not null, and the calling thread has no looper. * is not null, and the calling thread has no looper. Or if no requests were * passed in. * * @see #capture * @see #captureBurst Loading @@ -595,6 +601,7 @@ public interface CameraDevice extends AutoCloseable { * @see #flush * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading @@ -620,6 +627,7 @@ public interface CameraDevice extends AutoCloseable { * @see StateListener#onIdle * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public void stopRepeating() throws CameraAccessException; /** Loading Loading @@ -657,6 +665,7 @@ public interface CameraDevice extends AutoCloseable { * @see #configureOutputs * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public void flush() throws CameraAccessException; /** Loading Loading @@ -691,6 +700,7 @@ public interface CameraDevice extends AutoCloseable { * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public static abstract class CaptureListener { /** Loading Loading @@ -1042,6 +1052,7 @@ public interface CameraDevice extends AutoCloseable { * @param camera the camera device has that become unconfigured * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onUnconfigured(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1072,6 +1083,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#setRepeatingRequest * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onActive(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1106,6 +1118,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#flush * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onBusy(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1154,6 +1167,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#flush * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onIdle(CameraDevice camera) { // Default empty implementation } Loading core/java/android/hardware/camera2/dispatch/BroadcastDispatcher.java 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import static com.android.internal.util.Preconditions.*; /** * Broadcast a single dispatch into multiple other dispatchables. * * <p>Every time {@link #dispatch} is invoked, all the broadcast targets will * see the same dispatch as well. The first target's return value is returned.</p> * * <p>This enables a single listener to be converted into a multi-listener.</p> */ public class BroadcastDispatcher<T> implements Dispatchable<T> { private final List<Dispatchable<T>> mDispatchTargets; /** * Create a broadcast dispatcher from the supplied dispatch targets. * * @param dispatchTargets one or more targets to dispatch to */ @SafeVarargs public BroadcastDispatcher(Dispatchable<T>... dispatchTargets) { mDispatchTargets = Arrays.asList( checkNotNull(dispatchTargets, "dispatchTargets must not be null")); } @Override public Object dispatch(Method method, Object[] args) throws Throwable { Object result = null; boolean gotResult = false; for (Dispatchable<T> dispatchTarget : mDispatchTargets) { Object localResult = dispatchTarget.dispatch(method, args); if (!gotResult) { gotResult = true; result = localResult; } } return result; } } core/java/android/hardware/camera2/dispatch/Dispatchable.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; /** * Dynamically dispatch a method and its argument to some object. * * <p>This can be used to intercept method calls and do work around them, redirect work, * or block calls entirely.</p> */ public interface Dispatchable<T> { /** * Dispatch the method and arguments to this object. * @param method a method defined in class {@code T} * @param args arguments corresponding to said {@code method} * @return the object returned when invoking {@code method} * @throws Throwable any exception that might have been raised while invoking the method */ public Object dispatch(Method method, Object[] args) throws Throwable; } core/java/android/hardware/camera2/dispatch/DuckTypingDispatcher.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; import static com.android.internal.util.Preconditions.*; /** * Duck typing dispatcher; converts dispatch methods calls from one class to another by * looking up equivalently methods at runtime by name. * * <p>For example, if two types have identical method names and arguments, but * are not subclasses/subinterfaces of each other, this dispatcher will allow calls to be * made from one type to the other.</p> * * @param <TFrom> source dispatch type, whose methods with {@link #dispatch} will be called * @param <T> destination dispatch type, methods will be converted to the class of {@code T} */ public class DuckTypingDispatcher<TFrom, T> implements Dispatchable<TFrom> { private final MethodNameInvoker<T> mDuck; /** * Create a new duck typing dispatcher. * * @param target destination dispatch type, methods will be redirected to this dispatcher * @param targetClass destination dispatch class, methods will be converted to this class's */ public DuckTypingDispatcher(Dispatchable<T> target, Class<T> targetClass) { checkNotNull(targetClass, "targetClass must not be null"); checkNotNull(target, "target must not be null"); mDuck = new MethodNameInvoker<T>(target, targetClass); } @Override public Object dispatch(Method method, Object[] args) { return mDuck.invoke(method.getName(), args); } } Loading
core/java/android/hardware/camera2/CameraCaptureSession.java +28 −16 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.List; public abstract class CameraCaptureSession implements AutoCloseable { /** * Get the camera device that this session is created for * Get the camera device that this session is created for. */ public abstract CameraDevice getDevice(); Loading Loading @@ -90,8 +90,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException if the request targets Surfaces that are not configured as * outputs for this session. Or if the handler is null, the * listener is not null, and the calling thread has no looper. Loading @@ -99,6 +100,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #captureBurst * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #abortCaptures */ public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -132,8 +134,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests target Surfaces not currently configured as * outputs. Or if the handler is null, the listener is not * null, and the calling thread has no looper. Loading @@ -141,6 +144,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #capture * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #abortCaptures */ public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -188,11 +192,13 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces that are not currently * configured as outputs. Or if the handler is null, the * listener is not null, and the calling thread has no looper. * Or if no requests were passed in. * * @see #capture * @see #captureBurst Loading Loading @@ -246,11 +252,13 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces not currently configured * as outputs. Or if the handler is null, the listener is not * null, and the calling thread has no looper. * null, and the calling thread has no looper. Or if no * requests were passed in. * * @see #capture * @see #captureBurst Loading @@ -274,8 +282,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * * @see #setRepeatingRequest * @see #setRepeatingBurst Loading Loading @@ -308,8 +317,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * @throws CameraAccessException if the camera device is no longer connected or has * encountered a fatal error * @throws IllegalStateException if this session is no longer active, either because a new * session has been created or the camera device has been closed. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created * or the camera device has been closed. * * @see #setRepeatingRequest * @see #setRepeatingBurst Loading @@ -320,8 +330,8 @@ public abstract class CameraCaptureSession implements AutoCloseable { /** * Close this capture session asynchronously. * * <p>Closing a session frees up the target output Surfaces of the session for reuse with either a * new session, or to other APIs that can draw to Surfaces.</p> * <p>Closing a session frees up the target output Surfaces of the session for reuse with either * a new session, or to other APIs that can draw to Surfaces.</p> * * <p>Note that creating a new capture session with {@link CameraDevice#createCaptureSession} * will close any existing capture session automatically, and call the older session listener's Loading @@ -334,6 +344,8 @@ public abstract class CameraCaptureSession implements AutoCloseable { * However, any in-progress capture requests submitted to the session will be completed as * normal; once all captures have completed and the session has been torn down, * {@link StateListener#onClosed} will be called.</p> * * <p>Closing a session is idempotent; closing more than once has no effect.</p> */ @Override public abstract void close(); Loading
core/java/android/hardware/camera2/CameraDevice.java +16 −2 Original line number Diff line number Diff line Loading @@ -244,6 +244,7 @@ public interface CameraDevice extends AutoCloseable { * @see StreamConfigurationMap#getOutputSizes(Class) * @deprecated Use {@link #createCaptureSession} instead */ @Deprecated public void configureOutputs(List<Surface> outputs) throws CameraAccessException; /** Loading Loading @@ -432,6 +433,7 @@ public interface CameraDevice extends AutoCloseable { * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int capture(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -470,13 +472,15 @@ public interface CameraDevice extends AutoCloseable { * or the camera device has been closed. * @throws IllegalArgumentException If the requests target Surfaces not * currently configured as outputs. Or if the handler is null, the listener * is not null, and the calling thread has no looper. * is not null, and the calling thread has no looper. Or if no requests were * passed in. * * @see #capture * @see #setRepeatingRequest * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int captureBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -536,6 +540,7 @@ public interface CameraDevice extends AutoCloseable { * @see #flush * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int setRepeatingRequest(CaptureRequest request, CaptureListener listener, Handler handler) throws CameraAccessException; Loading Loading @@ -586,7 +591,8 @@ public interface CameraDevice extends AutoCloseable { * or the camera device has been closed. * @throws IllegalArgumentException If the requests reference Surfaces not * currently configured as outputs. Or if the handler is null, the listener * is not null, and the calling thread has no looper. * is not null, and the calling thread has no looper. Or if no requests were * passed in. * * @see #capture * @see #captureBurst Loading @@ -595,6 +601,7 @@ public interface CameraDevice extends AutoCloseable { * @see #flush * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener, Handler handler) throws CameraAccessException; Loading @@ -620,6 +627,7 @@ public interface CameraDevice extends AutoCloseable { * @see StateListener#onIdle * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public void stopRepeating() throws CameraAccessException; /** Loading Loading @@ -657,6 +665,7 @@ public interface CameraDevice extends AutoCloseable { * @see #configureOutputs * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public void flush() throws CameraAccessException; /** Loading Loading @@ -691,6 +700,7 @@ public interface CameraDevice extends AutoCloseable { * @see #setRepeatingBurst * @deprecated Use {@link CameraCaptureSession} instead */ @Deprecated public static abstract class CaptureListener { /** Loading Loading @@ -1042,6 +1052,7 @@ public interface CameraDevice extends AutoCloseable { * @param camera the camera device has that become unconfigured * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onUnconfigured(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1072,6 +1083,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#setRepeatingRequest * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onActive(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1106,6 +1118,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#flush * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onBusy(CameraDevice camera) { // Default empty implementation } Loading Loading @@ -1154,6 +1167,7 @@ public interface CameraDevice extends AutoCloseable { * @see CameraDevice#flush * @deprecated Use {@link CameraCaptureSession.StateListener} instead. */ @Deprecated public void onIdle(CameraDevice camera) { // Default empty implementation } Loading
core/java/android/hardware/camera2/dispatch/BroadcastDispatcher.java 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import static com.android.internal.util.Preconditions.*; /** * Broadcast a single dispatch into multiple other dispatchables. * * <p>Every time {@link #dispatch} is invoked, all the broadcast targets will * see the same dispatch as well. The first target's return value is returned.</p> * * <p>This enables a single listener to be converted into a multi-listener.</p> */ public class BroadcastDispatcher<T> implements Dispatchable<T> { private final List<Dispatchable<T>> mDispatchTargets; /** * Create a broadcast dispatcher from the supplied dispatch targets. * * @param dispatchTargets one or more targets to dispatch to */ @SafeVarargs public BroadcastDispatcher(Dispatchable<T>... dispatchTargets) { mDispatchTargets = Arrays.asList( checkNotNull(dispatchTargets, "dispatchTargets must not be null")); } @Override public Object dispatch(Method method, Object[] args) throws Throwable { Object result = null; boolean gotResult = false; for (Dispatchable<T> dispatchTarget : mDispatchTargets) { Object localResult = dispatchTarget.dispatch(method, args); if (!gotResult) { gotResult = true; result = localResult; } } return result; } }
core/java/android/hardware/camera2/dispatch/Dispatchable.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; /** * Dynamically dispatch a method and its argument to some object. * * <p>This can be used to intercept method calls and do work around them, redirect work, * or block calls entirely.</p> */ public interface Dispatchable<T> { /** * Dispatch the method and arguments to this object. * @param method a method defined in class {@code T} * @param args arguments corresponding to said {@code method} * @return the object returned when invoking {@code method} * @throws Throwable any exception that might have been raised while invoking the method */ public Object dispatch(Method method, Object[] args) throws Throwable; }
core/java/android/hardware/camera2/dispatch/DuckTypingDispatcher.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.dispatch; import java.lang.reflect.Method; import static com.android.internal.util.Preconditions.*; /** * Duck typing dispatcher; converts dispatch methods calls from one class to another by * looking up equivalently methods at runtime by name. * * <p>For example, if two types have identical method names and arguments, but * are not subclasses/subinterfaces of each other, this dispatcher will allow calls to be * made from one type to the other.</p> * * @param <TFrom> source dispatch type, whose methods with {@link #dispatch} will be called * @param <T> destination dispatch type, methods will be converted to the class of {@code T} */ public class DuckTypingDispatcher<TFrom, T> implements Dispatchable<TFrom> { private final MethodNameInvoker<T> mDuck; /** * Create a new duck typing dispatcher. * * @param target destination dispatch type, methods will be redirected to this dispatcher * @param targetClass destination dispatch class, methods will be converted to this class's */ public DuckTypingDispatcher(Dispatchable<T> target, Class<T> targetClass) { checkNotNull(targetClass, "targetClass must not be null"); checkNotNull(target, "target must not be null"); mDuck = new MethodNameInvoker<T>(target, targetClass); } @Override public Object dispatch(Method method, Object[] args) { return mDuck.invoke(method.getName(), args); } }