camera2: Change CaptureListener callbacks to include the session (api)

* Also makes CameraDevice an abstract class (API)

Bug: 15428219
Bug: 14964443
Change-Id: I0e8c8309186aad59570aac7e0f998bb615405f0a
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index d62958f..5fd0f9b 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -370,6 +370,7 @@
          * <p>If the camera device configuration fails, then {@link #onConfigureFailed} will
          * be invoked instead of this callback.</p>
          *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public abstract void onConfigured(CameraCaptureSession session);
 
@@ -383,6 +384,8 @@
          * callback is invoked will throw an IllegalStateException. Any capture requests submitted
          * to the session prior to this callback will be discarded and will not produce any
          * callbacks on their listeners.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public abstract void onConfigureFailed(CameraCaptureSession session);
 
@@ -396,6 +399,8 @@
          * <p>Otherwise, this callback will be invoked any time the session finishes processing
          * all of its active capture requests, and no repeating request or burst is set up.</p>
          *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
+         *
          */
         public void onReady(CameraCaptureSession session) {
             // default empty implementation
@@ -410,6 +415,8 @@
          *
          * <p>If the session runs out of capture requests to process and calls {@link #onReady},
          * then this callback will be invoked again once new requests are submitted for capture.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public void onActive(CameraCaptureSession session) {
             // default empty implementation
@@ -426,6 +433,8 @@
          * any repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called).
          * However, any in-progress capture requests submitted to the session will be completed
          * as normal.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
         public void onClosed(CameraCaptureSession session) {
             // default empty implementation
@@ -478,13 +487,13 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera the CameraDevice sending the callback
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request the request for the capture that just begun
          * @param timestamp the timestamp at start of capture, in nanoseconds.
          *
          * @see android.media.MediaActionSound
          */
-        public void onCaptureStarted(CameraDevice camera,
+        public void onCaptureStarted(CameraCaptureSession session,
                 CaptureRequest request, long timestamp) {
             // default empty implementation
         }
@@ -502,7 +511,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param result The partial output metadata from the capture, which
          * includes a subset of the CaptureResult fields.
@@ -514,7 +523,7 @@
          *
          * @hide
          */
-        public void onCapturePartial(CameraDevice camera,
+        public void onCapturePartial(CameraCaptureSession session,
                 CaptureRequest request, CaptureResult result) {
             // default empty implementation
         }
@@ -545,7 +554,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param partialResult The partial output metadata from the capture, which
          * includes a subset of the {@link TotalCaptureResult} fields.
@@ -555,7 +564,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureProgressed(CameraDevice camera,
+        public void onCaptureProgressed(CameraCaptureSession session,
                 CaptureRequest request, CaptureResult partialResult) {
             // default empty implementation
         }
@@ -573,7 +582,7 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera The CameraDevice sending the callback.
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request The request that was given to the CameraDevice
          * @param result The total output metadata from the capture, including the
          * final capture parameters and the state of the camera system during
@@ -584,7 +593,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureCompleted(CameraDevice camera,
+        public void onCaptureCompleted(CameraCaptureSession session,
                 CaptureRequest request, TotalCaptureResult result) {
             // default empty implementation
         }
@@ -600,8 +609,8 @@
          *
          * <p>The default implementation of this method does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param request
          *            The request that was given to the CameraDevice
          * @param failure
@@ -613,7 +622,7 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureFailed(CameraDevice camera,
+        public void onCaptureFailed(CameraCaptureSession session,
                 CaptureRequest request, CaptureFailure failure) {
             // default empty implementation
         }
@@ -629,8 +638,8 @@
          *
          * <p>The default implementation does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param sequenceId
          *            A sequence ID returned by the {@link #capture} family of functions.
          * @param frameNumber
@@ -643,7 +652,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceAborted
          */
-        public void onCaptureSequenceCompleted(CameraDevice camera,
+        public void onCaptureSequenceCompleted(CameraCaptureSession session,
                 int sequenceId, long frameNumber) {
             // default empty implementation
         }
@@ -661,8 +670,8 @@
          *
          * <p>The default implementation does nothing.</p>
          *
-         * @param camera
-         *            The CameraDevice sending the callback.
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
          * @param sequenceId
          *            A sequence ID returned by the {@link #capture} family of functions.
          *
@@ -672,7 +681,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceCompleted
          */
-        public void onCaptureSequenceAborted(CameraDevice camera,
+        public void onCaptureSequenceAborted(CameraCaptureSession session,
                 int sequenceId) {
             // default empty implementation
         }
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index f9f617a..e9213c5 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -24,7 +24,7 @@
 import java.util.List;
 
 /**
- * <p>The CameraDevice class is an interface to a single camera connected to an
+ * <p>The CameraDevice class is a representation of a single camera connected to an
  * Android device, allowing for fine-grain control of image capture and
  * post-processing at high frame rates.</p>
  *
@@ -46,7 +46,7 @@
  * @see CameraManager#openCamera
  * @see android.Manifest.permission#CAMERA
  */
-public interface CameraDevice extends AutoCloseable {
+public abstract class CameraDevice implements AutoCloseable {
 
     /**
      * Create a request suitable for a camera preview window. Specifically, this
@@ -127,7 +127,7 @@
      * @see CameraManager#getCameraCharacteristics
      * @see CameraManager#getCameraIdList
      */
-    public String getId();
+    public abstract String getId();
 
     /**
      * <p>Set up a new output set of Surfaces for the camera device.</p>
@@ -245,7 +245,7 @@
      * @deprecated Use {@link #createCaptureSession} instead
      */
     @Deprecated
-    public void configureOutputs(List<Surface> outputs) throws CameraAccessException;
+    public abstract void configureOutputs(List<Surface> outputs) throws CameraAccessException;
 
     /**
      * <p>Create a new camera capture session by providing the target output set of Surfaces to the
@@ -358,7 +358,7 @@
      * @see StreamConfigurationMap#getOutputSizes(int)
      * @see StreamConfigurationMap#getOutputSizes(Class)
      */
-    public void createCaptureSession(List<Surface> outputs,
+    public abstract void createCaptureSession(List<Surface> outputs,
             CameraCaptureSession.StateListener listener, Handler handler)
             throws CameraAccessException;
 
@@ -387,7 +387,7 @@
      * @see #TEMPLATE_VIDEO_SNAPSHOT
      * @see #TEMPLATE_MANUAL
      */
-    public CaptureRequest.Builder createCaptureRequest(int templateType)
+    public abstract CaptureRequest.Builder createCaptureRequest(int templateType)
             throws CameraAccessException;
 
     /**
@@ -434,7 +434,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public int capture(CaptureRequest request, CaptureListener listener, Handler handler)
+    public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler)
             throws CameraAccessException;
 
     /**
@@ -481,7 +481,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+    public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -541,7 +541,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+    public abstract int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -602,7 +602,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
+    public abstract int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
             Handler handler) throws CameraAccessException;
 
     /**
@@ -628,7 +628,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public void stopRepeating() throws CameraAccessException;
+    public abstract void stopRepeating() throws CameraAccessException;
 
     /**
      * Flush all captures currently pending and in-progress as fast as
@@ -666,7 +666,7 @@
      * @deprecated Use {@link CameraCaptureSession} instead
      */
     @Deprecated
-    public void flush() throws CameraAccessException;
+    public abstract void flush() throws CameraAccessException;
 
     /**
      * Close the connection to this camera device as quickly as possible.
@@ -684,7 +684,7 @@
      *
      */
     @Override
-    public void close();
+    public abstract void close();
 
     /**
      * <p>A listener for tracking the progress of a {@link CaptureRequest}
@@ -1230,4 +1230,10 @@
          */
         public abstract void onError(CameraDevice camera, int error); // Must implement
     }
+
+    /**
+     * To be inherited by android.hardware.camera2.* code only.
+     * @hide
+     */
+    public CameraDevice() {}
 }
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 83db056..e21fb1f 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -228,8 +228,8 @@
 
                 ICameraDeviceUser cameraUser;
 
-                android.hardware.camera2.impl.CameraDevice deviceImpl =
-                        new android.hardware.camera2.impl.CameraDevice(
+                android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
+                        new android.hardware.camera2.impl.CameraDeviceImpl(
                                 cameraId,
                                 listener,
                                 handler,
diff --git a/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java b/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java
new file mode 100644
index 0000000..866f370
--- /dev/null
+++ b/core/java/android/hardware/camera2/dispatch/ArgumentReplacingDispatcher.java
@@ -0,0 +1,85 @@
+/*
+ * 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.*;
+
+/**
+ * A dispatcher that replaces one argument with another; replaces any argument at an index
+ * with another argument.
+ *
+ * <p>For example, we can override an {@code void onSomething(int x)} calls to have {@code x} always
+ * equal to 1. Or, if using this with a duck typing dispatcher, we could even overwrite {@code x} to
+ * be something
+ * that's not an {@code int}.</p>
+ *
+ * @param <T>
+ *          source dispatch type, whose methods with {@link #dispatch} will be called
+ * @param <TArg>
+ *          argument replacement type, args in {@link #dispatch} matching {@code argumentIndex}
+ *          will be overriden to objects of this type
+ */
+public class ArgumentReplacingDispatcher<T, TArg> implements Dispatchable<T> {
+
+    private final Dispatchable<T> mTarget;
+    private final int mArgumentIndex;
+    private final TArg mReplaceWith;
+
+    /**
+     * Create a new argument replacing dispatcher; dispatches are forwarded to {@code target}
+     * after the argument is replaced.
+     *
+     * <p>For example, if a method {@code onAction(T1 a, Integer b, T2 c)} is invoked, and we wanted
+     * to replace all occurrences of {@code b} with {@code 0xDEADBEEF}, we would set
+     * {@code argumentIndex = 1} and {@code replaceWith = 0xDEADBEEF}.</p>
+     *
+     * <p>If a method dispatched has less arguments than {@code argumentIndex}, it is
+     * passed through with the arguments unchanged.</p>
+     *
+     * @param target destination dispatch type, methods will be redirected to this dispatcher
+     * @param argumentIndex the numeric index of the argument {@code >= 0}
+     * @param replaceWith arguments matching {@code argumentIndex} will be replaced with this object
+     */
+    public ArgumentReplacingDispatcher(Dispatchable<T> target, int argumentIndex,
+            TArg replaceWith) {
+        mTarget = checkNotNull(target, "target must not be null");
+        mArgumentIndex = checkArgumentNonnegative(argumentIndex,
+                "argumentIndex must not be negative");
+        mReplaceWith = checkNotNull(replaceWith, "replaceWith must not be null");
+    }
+
+    @Override
+    public Object dispatch(Method method, Object[] args) throws Throwable {
+
+        if (args.length > mArgumentIndex) {
+            args = arrayCopy(args); // don't change in-place since it can affect upstream dispatches
+            args[mArgumentIndex] = mReplaceWith;
+        }
+
+        return mTarget.dispatch(method, args);
+    }
+
+    private static Object[] arrayCopy(Object[] array) {
+        int length = array.length;
+        Object[] newArray = new Object[length];
+        for (int i = 0; i < length; ++i) {
+            newArray[i] = array[i];
+        }
+        return newArray;
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index e129783..f74fbaa 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -19,6 +19,7 @@
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.dispatch.ArgumentReplacingDispatcher;
 import android.hardware.camera2.dispatch.BroadcastDispatcher;
 import android.hardware.camera2.dispatch.Dispatchable;
 import android.hardware.camera2.dispatch.DuckTypingDispatcher;
@@ -34,7 +35,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-import static android.hardware.camera2.impl.CameraDevice.checkHandler;
+import static android.hardware.camera2.impl.CameraDeviceImpl.checkHandler;
 import static com.android.internal.util.Preconditions.*;
 
 public class CameraCaptureSessionImpl extends CameraCaptureSession {
@@ -52,7 +53,7 @@
     private final Handler mStateHandler;
 
     /** Internal camera device; used to translate calls into existing deprecated API */
-    private final android.hardware.camera2.impl.CameraDevice mDeviceImpl;
+    private final android.hardware.camera2.impl.CameraDeviceImpl mDeviceImpl;
     /** Internal handler; used for all incoming events to preserve total order */
     private final Handler mDeviceHandler;
 
@@ -82,7 +83,7 @@
      */
     CameraCaptureSessionImpl(List<Surface> outputs,
             CameraCaptureSession.StateListener listener, Handler stateHandler,
-            android.hardware.camera2.impl.CameraDevice deviceImpl,
+            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl,
             Handler deviceStateHandler, boolean configureSuccess) {
         if (outputs == null || outputs.isEmpty()) {
             throw new IllegalArgumentException("outputs must be a non-null, non-empty list");
@@ -325,6 +326,7 @@
 
         /*
          * Split the calls from the device listener into local listener and the following chain:
+         * - replace the first CameraDevice arg with a CameraCaptureSession
          * - duck type from device listener to session listener
          * - then forward the call to a handler
          * - then finally invoke the destination method on the session listener object
@@ -340,12 +342,15 @@
                 new InvokeDispatcher<>(localListener);
         HandlerDispatcher<CaptureListener> handlerPassthrough =
                 new HandlerDispatcher<>(userListenerSink, handler);
-        DuckTypingDispatcher<CameraDevice.CaptureListener, CaptureListener> duckToSessionCaptureListener
+        DuckTypingDispatcher<CameraDevice.CaptureListener, CaptureListener> duckToSession
                 = new DuckTypingDispatcher<>(handlerPassthrough, CaptureListener.class);
+        ArgumentReplacingDispatcher<CameraDevice.CaptureListener, CameraCaptureSessionImpl>
+            replaceDeviceWithSession = new ArgumentReplacingDispatcher<>(duckToSession,
+                    /*argumentIndex*/0, this);
 
         BroadcastDispatcher<CameraDevice.CaptureListener> broadcaster =
                 new BroadcastDispatcher<CameraDevice.CaptureListener>(
-                        duckToSessionCaptureListener,
+                        replaceDeviceWithSession,
                         localSink);
 
         return new ListenerProxies.DeviceCaptureListenerProxy(broadcaster);
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
similarity index 92%
rename from core/java/android/hardware/camera2/impl/CameraDevice.java
rename to core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index e9d4b0f..81bd2fd 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -21,7 +21,6 @@
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.ICameraDeviceCallbacks;
@@ -48,7 +47,7 @@
 /**
  * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
  */
-public class CameraDevice implements android.hardware.camera2.CameraDevice {
+public class CameraDeviceImpl extends android.hardware.camera2.CameraDevice {
 
     private final String TAG;
     private final boolean DEBUG;
@@ -67,6 +66,7 @@
 
     private boolean mIdle = true;
 
+    /** map request IDs to listener/request data */
     private final SparseArray<CaptureListenerHolder> mCaptureListenerMap =
             new SparseArray<CaptureListenerHolder>();
 
@@ -99,11 +99,11 @@
     private final Runnable mCallOnOpened = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onOpened(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onOpened(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onOpened(CameraDevice.this);
+                    sessionListener.onOpened(CameraDeviceImpl.this);
                 }
             }
         }
@@ -112,11 +112,11 @@
     private final Runnable mCallOnUnconfigured = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onUnconfigured(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onUnconfigured(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onUnconfigured(CameraDevice.this);
+                    sessionListener.onUnconfigured(CameraDeviceImpl.this);
                 }
             }
         }
@@ -125,11 +125,11 @@
     private final Runnable mCallOnActive = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onActive(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onActive(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onActive(CameraDevice.this);
+                    sessionListener.onActive(CameraDeviceImpl.this);
                 }
             }
         }
@@ -138,11 +138,11 @@
     private final Runnable mCallOnBusy = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onBusy(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onBusy(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onBusy(CameraDevice.this);
+                    sessionListener.onBusy(CameraDeviceImpl.this);
                 }
             }
         }
@@ -151,10 +151,10 @@
     private final Runnable mCallOnClosed = new Runnable() {
         @Override
         public void run() {
-            mDeviceListener.onClosed(CameraDevice.this);
+            mDeviceListener.onClosed(CameraDeviceImpl.this);
             StateListener sessionListener = mSessionStateListener;
             if (sessionListener != null) {
-                sessionListener.onClosed(CameraDevice.this);
+                sessionListener.onClosed(CameraDeviceImpl.this);
             }
         }
     };
@@ -162,11 +162,11 @@
     private final Runnable mCallOnIdle = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onIdle(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onIdle(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onIdle(CameraDevice.this);
+                    sessionListener.onIdle(CameraDeviceImpl.this);
                 }
             }
         }
@@ -175,17 +175,17 @@
     private final Runnable mCallOnDisconnected = new Runnable() {
         @Override
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onDisconnected(CameraDevice.this);
+            if (!CameraDeviceImpl.this.isClosed()) {
+                mDeviceListener.onDisconnected(CameraDeviceImpl.this);
                 StateListener sessionListener = mSessionStateListener;
                 if (sessionListener != null) {
-                    sessionListener.onDisconnected(CameraDevice.this);
+                    sessionListener.onDisconnected(CameraDeviceImpl.this);
                 }
             }
         }
     };
 
-    public CameraDevice(String cameraId, StateListener listener, Handler handler,
+    public CameraDeviceImpl(String cameraId, StateListener listener, Handler handler,
                         CameraCharacteristics characteristics) {
         if (cameraId == null || listener == null || handler == null) {
             throw new IllegalArgumentException("Null argument given");
@@ -416,7 +416,7 @@
                 Runnable resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()) {
+                        if (!CameraDeviceImpl.this.isClosed()) {
                             if (DEBUG) {
                                 Log.d(TAG, String.format(
                                         "early trigger sequence complete for request %d",
@@ -427,7 +427,7 @@
                                 throw new AssertionError(lastFrameNumber + " cannot be cast to int");
                             }
                             holder.getListener().onCaptureSequenceCompleted(
-                                    CameraDevice.this,
+                                    CameraDeviceImpl.this,
                                     requestId,
                                     lastFrameNumber);
                         }
@@ -769,7 +769,7 @@
                     Runnable resultDispatch = new Runnable() {
                         @Override
                         public void run() {
-                            if (!CameraDevice.this.isClosed()){
+                            if (!CameraDeviceImpl.this.isClosed()){
                                 if (DEBUG) {
                                     Log.d(TAG, String.format(
                                             "fire sequence complete for request %d",
@@ -783,7 +783,7 @@
                                             + " cannot be cast to int");
                                 }
                                 holder.getListener().onCaptureSequenceCompleted(
-                                    CameraDevice.this,
+                                    CameraDeviceImpl.this,
                                     requestId,
                                     lastFrameNumber);
                             }
@@ -847,14 +847,14 @@
                         r = new Runnable() {
                             @Override
                             public void run() {
-                                if (!CameraDevice.this.isClosed()) {
-                                    mDeviceListener.onError(CameraDevice.this, errorCode);
+                                if (!CameraDeviceImpl.this.isClosed()) {
+                                    mDeviceListener.onError(CameraDeviceImpl.this, errorCode);
                                 }
                             }
                         };
                         break;
                 }
-                CameraDevice.this.mDeviceHandler.post(r);
+                CameraDeviceImpl.this.mDeviceHandler.post(r);
             }
 
             // Fire onCaptureSequenceCompleted
@@ -874,10 +874,10 @@
                 Log.d(TAG, "Camera now idle");
             }
             synchronized (mLock) {
-                if (!CameraDevice.this.mIdle) {
-                    CameraDevice.this.mDeviceHandler.post(mCallOnIdle);
+                if (!CameraDeviceImpl.this.mIdle) {
+                    CameraDeviceImpl.this.mDeviceHandler.post(mCallOnIdle);
                 }
-                CameraDevice.this.mIdle = true;
+                CameraDeviceImpl.this.mIdle = true;
             }
         }
 
@@ -891,7 +891,7 @@
 
             // Get the listener for this frame ID, if there is one
             synchronized (mLock) {
-                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+                holder = CameraDeviceImpl.this.mCaptureListenerMap.get(requestId);
             }
 
             if (holder == null) {
@@ -905,9 +905,9 @@
                 new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()) {
+                        if (!CameraDeviceImpl.this.isClosed()) {
                             holder.getListener().onCaptureStarted(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 holder.getRequest(resultExtras.getSubsequenceId()),
                                 timestamp);
                         }
@@ -932,7 +932,7 @@
 
             final CaptureListenerHolder holder;
             synchronized (mLock) {
-                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+                holder = CameraDeviceImpl.this.mCaptureListenerMap.get(requestId);
             }
 
             Boolean quirkPartial = result.get(CaptureResult.QUIRKS_PARTIAL_RESULT);
@@ -976,9 +976,9 @@
                 resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()){
+                        if (!CameraDeviceImpl.this.isClosed()){
                             holder.getListener().onCapturePartial(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 request,
                                 resultAsCapture);
                         }
@@ -992,9 +992,9 @@
                 resultDispatch = new Runnable() {
                     @Override
                     public void run() {
-                        if (!CameraDevice.this.isClosed()){
+                        if (!CameraDeviceImpl.this.isClosed()){
                             holder.getListener().onCaptureCompleted(
-                                CameraDevice.this,
+                                CameraDeviceImpl.this,
                                 request,
                                 resultAsCapture);
                         }