Camera2: Add SDK annotations

- Annotate everything with @NonNull, @Nullable
- Annotate a few @IntRange
- Annotate a few @IntDef
  - Most metadata enums probably canont be annotated usefully,
    since get/set() are generic and the annotation system
    can't yet manage that.
  - Plus metadata annotations need to be auto-generated anyway
- Also add explicit null check to prepare's surface argument
- Also update docs of getCameraCharacteristics to match reality

Bug: 21029463
Change-Id: Ifd81b2a782e29ad069fe25c7db4a1fda73dabcd7
diff --git a/core/java/android/hardware/camera2/CameraAccessException.java b/core/java/android/hardware/camera2/CameraAccessException.java
index 84e9912..933ce0d 100644
--- a/core/java/android/hardware/camera2/CameraAccessException.java
+++ b/core/java/android/hardware/camera2/CameraAccessException.java
@@ -16,8 +16,13 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.IntDef;
 import android.util.AndroidException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * <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
@@ -76,6 +81,16 @@
      */
     public static final int CAMERA_DEPRECATED_HAL = 1000;
 
+     /** @hide */
+     @Retention(RetentionPolicy.SOURCE)
+     @IntDef(
+         {CAMERA_IN_USE,
+          MAX_CAMERAS_IN_USE,
+          CAMERA_DISABLED,
+          CAMERA_DISCONNECTED,
+          CAMERA_ERROR})
+     public @interface AccessError {};
+
     // Make the eclipse warning about serializable exceptions go away
     private static final long serialVersionUID = 5630338637471475675L; // randomly generated
 
@@ -88,26 +103,27 @@
      * @see #CAMERA_DISCONNECTED
      * @see #CAMERA_ERROR
      */
+    @AccessError
     public final int getReason() {
         return mReason;
     }
 
-    public CameraAccessException(int problem) {
+    public CameraAccessException(@AccessError int problem) {
         super(getDefaultMessage(problem));
         mReason = problem;
     }
 
-    public CameraAccessException(int problem, String message) {
+    public CameraAccessException(@AccessError int problem, String message) {
         super(message);
         mReason = problem;
     }
 
-    public CameraAccessException(int problem, String message, Throwable cause) {
+    public CameraAccessException(@AccessError int problem, String message, Throwable cause) {
         super(message, cause);
         mReason = problem;
     }
 
-    public CameraAccessException(int problem, Throwable cause) {
+    public CameraAccessException(@AccessError int problem, Throwable cause) {
         super(getDefaultMessage(problem), cause);
         mReason = problem;
     }
@@ -115,7 +131,7 @@
     /**
      * @hide
      */
-    public static String getDefaultMessage(int problem) {
+    public static String getDefaultMessage(@AccessError int problem) {
         switch (problem) {
             case CAMERA_IN_USE:
                 return "The camera device is in use already";
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index c6f622c..b3e7cfc 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -16,6 +16,8 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Handler;
 import android.view.Surface;
 
@@ -73,6 +75,7 @@
     /**
      * Get the camera device that this session is created for.
      */
+    @NonNull
     public abstract CameraDevice getDevice();
 
     /**
@@ -133,7 +136,7 @@
      *
      * @see StateCallback#onSurfacePrepared
      */
-    public abstract void prepare(Surface surface) throws CameraAccessException;
+    public abstract void prepare(@NonNull Surface surface) throws CameraAccessException;
 
     /**
      * <p>Submit a request for an image to be captured by the camera device.</p>
@@ -194,7 +197,8 @@
      * @see #abortCaptures
      * @see CameraDevice#createReprocessableCaptureSession
      */
-    public abstract int capture(CaptureRequest request, CaptureCallback listener, Handler handler)
+    public abstract int capture(@NonNull CaptureRequest request,
+            @Nullable CaptureCallback listener, @Nullable Handler handler)
             throws CameraAccessException;
 
     /**
@@ -252,8 +256,9 @@
      * @see #setRepeatingBurst
      * @see #abortCaptures
      */
-    public abstract int captureBurst(List<CaptureRequest> requests, CaptureCallback listener,
-            Handler handler) throws CameraAccessException;
+    public abstract int captureBurst(@NonNull List<CaptureRequest> requests,
+            @Nullable CaptureCallback listener, @Nullable Handler handler)
+            throws CameraAccessException;
 
     /**
      * Request endlessly repeating capture of images by this capture session.
@@ -318,8 +323,9 @@
      * @see #stopRepeating
      * @see #abortCaptures
      */
-    public abstract int setRepeatingRequest(CaptureRequest request, CaptureCallback listener,
-            Handler handler) throws CameraAccessException;
+    public abstract int setRepeatingRequest(@NonNull CaptureRequest request,
+            @Nullable CaptureCallback listener, @Nullable Handler handler)
+            throws CameraAccessException;
 
     /**
      * <p>Request endlessly repeating capture of a sequence of images by this
@@ -389,8 +395,9 @@
      * @see #stopRepeating
      * @see #abortCaptures
      */
-    public abstract int setRepeatingBurst(List<CaptureRequest> requests, CaptureCallback listener,
-            Handler handler) throws CameraAccessException;
+    public abstract int setRepeatingBurst(@NonNull List<CaptureRequest> requests,
+            @Nullable CaptureCallback listener, @Nullable Handler handler)
+            throws CameraAccessException;
 
     /**
      * <p>Cancel any ongoing repeating capture set by either
@@ -478,6 +485,7 @@
      * @see android.media.ImageWriter
      * @see android.media.ImageReader
      */
+    @Nullable
     public abstract Surface getInputSurface();
 
     /**
@@ -525,7 +533,7 @@
          *
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
-        public abstract void onConfigured(CameraCaptureSession session);
+        public abstract void onConfigured(@NonNull CameraCaptureSession session);
 
         /**
          * This method is called if the session cannot be configured as requested.
@@ -540,7 +548,7 @@
          *
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
-        public abstract void onConfigureFailed(CameraCaptureSession session);
+        public abstract void onConfigureFailed(@NonNull CameraCaptureSession session);
 
         /**
          * This method is called every time the session has no more capture requests to process.
@@ -555,7 +563,7 @@
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          *
          */
-        public void onReady(CameraCaptureSession session) {
+        public void onReady(@NonNull CameraCaptureSession session) {
             // default empty implementation
         }
 
@@ -571,7 +579,7 @@
          *
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
-        public void onActive(CameraCaptureSession session) {
+        public void onActive(@NonNull CameraCaptureSession session) {
             // default empty implementation
         }
 
@@ -589,7 +597,7 @@
          *
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          */
-        public void onClosed(CameraCaptureSession session) {
+        public void onClosed(@NonNull CameraCaptureSession session) {
             // default empty implementation
         }
 
@@ -608,7 +616,8 @@
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param surface the Surface that was used with the {@link #prepare} call.
          */
-        public void onSurfacePrepared(CameraCaptureSession session, Surface surface) {
+        public void onSurfacePrepared(@NonNull CameraCaptureSession session,
+                @NonNull Surface surface) {
             // default empty implementation
         }
     }
@@ -675,8 +684,8 @@
          *
          * @see android.media.MediaActionSound
          */
-        public void onCaptureStarted(CameraCaptureSession session,
-                CaptureRequest request, long timestamp, long frameNumber) {
+        public void onCaptureStarted(@NonNull CameraCaptureSession session,
+                @NonNull CaptureRequest request, long timestamp, long frameNumber) {
             // Temporary trampoline for API change transition
             onCaptureStarted(session, request, timestamp);
         }
@@ -756,8 +765,8 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureProgressed(CameraCaptureSession session,
-                CaptureRequest request, CaptureResult partialResult) {
+        public void onCaptureProgressed(@NonNull CameraCaptureSession session,
+                @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
             // default empty implementation
         }
 
@@ -785,8 +794,8 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureCompleted(CameraCaptureSession session,
-                CaptureRequest request, TotalCaptureResult result) {
+        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
+                @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
             // default empty implementation
         }
 
@@ -814,8 +823,8 @@
          * @see #setRepeatingRequest
          * @see #setRepeatingBurst
          */
-        public void onCaptureFailed(CameraCaptureSession session,
-                CaptureRequest request, CaptureFailure failure) {
+        public void onCaptureFailed(@NonNull CameraCaptureSession session,
+                @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
             // default empty implementation
         }
 
@@ -844,7 +853,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceAborted
          */
-        public void onCaptureSequenceCompleted(CameraCaptureSession session,
+        public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session,
                 int sequenceId, long frameNumber) {
             // default empty implementation
         }
@@ -873,7 +882,7 @@
          * @see CaptureFailure#getSequenceId()
          * @see #onCaptureSequenceCompleted
          */
-        public void onCaptureSequenceAborted(CameraCaptureSession session,
+        public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session,
                 int sequenceId) {
             // default empty implementation
         }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index d3b63f9..c2a6a44 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -16,6 +16,8 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.PublicKey;
 import android.hardware.camera2.impl.SyntheticKey;
@@ -91,6 +93,7 @@
          *
          * @return String representation of the key name
          */
+        @NonNull
         public String getName() {
             return mKey.getName();
         }
@@ -166,6 +169,7 @@
      * @param key The characteristics field to read.
      * @return The value of that key, or {@code null} if the field is not set.
      */
+    @Nullable
     public <T> T get(Key<T> key) {
         return mProperties.get(key);
     }
@@ -194,6 +198,7 @@
     /**
      * {@inheritDoc}
      */
+    @NonNull
     @Override
     public List<Key<?>> getKeys() {
         // List of keys is immutable; cache the results after we calculate them
@@ -227,6 +232,7 @@
      * @return List of keys supported by this CameraDevice for CaptureRequests.
      */
     @SuppressWarnings({"unchecked"})
+    @NonNull
     public List<CaptureRequest.Key<?>> getAvailableCaptureRequestKeys() {
         if (mAvailableRequestKeys == null) {
             Object crKey = CaptureRequest.Key.class;
@@ -258,6 +264,7 @@
      * @return List of keys supported by this CameraDevice for CaptureResults.
      */
     @SuppressWarnings({"unchecked"})
+    @NonNull
     public List<CaptureResult.Key<?>> getAvailableCaptureResultKeys() {
         if (mAvailableResultKeys == null) {
             Object crKey = CaptureResult.Key.class;
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index dad4fb6..d02f349 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -16,6 +16,9 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.IntDef;
 import android.hardware.camera2.params.InputConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.params.OutputConfiguration;
@@ -23,6 +26,8 @@
 import android.view.Surface;
 
 import java.util.List;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * <p>The CameraDevice class is a representation of a single camera connected to an
@@ -124,6 +129,17 @@
      */
     public static final int TEMPLATE_MANUAL = 6;
 
+     /** @hide */
+     @Retention(RetentionPolicy.SOURCE)
+     @IntDef(
+         {TEMPLATE_PREVIEW,
+          TEMPLATE_STILL_CAPTURE,
+          TEMPLATE_RECORD,
+          TEMPLATE_VIDEO_SNAPSHOT,
+          TEMPLATE_ZERO_SHUTTER_LAG,
+          TEMPLATE_MANUAL })
+     public @interface RequestTemplate {};
+
     /**
      * Get the ID of this camera device.
      *
@@ -142,6 +158,7 @@
      * @see CameraManager#getCameraCharacteristics
      * @see CameraManager#getCameraIdList
      */
+    @NonNull
     public abstract String getId();
 
     /**
@@ -391,8 +408,8 @@
      * @see StreamConfigurationMap#getOutputSizes(int)
      * @see StreamConfigurationMap#getOutputSizes(Class)
      */
-    public abstract void createCaptureSession(List<Surface> outputs,
-            CameraCaptureSession.StateCallback callback, Handler handler)
+    public abstract void createCaptureSession(@NonNull List<Surface> outputs,
+            @NonNull CameraCaptureSession.StateCallback callback, @Nullable Handler handler)
             throws CameraAccessException;
 
     /**
@@ -560,8 +577,9 @@
      * @see android.media.ImageWriter
      * @see android.media.ImageReader
      */
-    public abstract void createReprocessableCaptureSession(InputConfiguration inputConfig,
-            List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
+    public abstract void createReprocessableCaptureSession(@NonNull InputConfiguration inputConfig,
+            @NonNull List<Surface> outputs, @NonNull CameraCaptureSession.StateCallback callback,
+            @Nullable Handler handler)
             throws CameraAccessException;
 
     /**
@@ -591,7 +609,8 @@
      * @see #TEMPLATE_VIDEO_SNAPSHOT
      * @see #TEMPLATE_MANUAL
      */
-    public abstract CaptureRequest.Builder createCaptureRequest(int templateType)
+    @NonNull
+    public abstract CaptureRequest.Builder createCaptureRequest(@RequestTemplate int templateType)
             throws CameraAccessException;
 
     /**
@@ -620,8 +639,9 @@
      * @see CameraDevice#createReprocessableCaptureSession
      * @see android.media.ImageWriter
      */
+    @NonNull
     public abstract CaptureRequest.Builder createReprocessCaptureRequest(
-            TotalCaptureResult inputResult) throws CameraAccessException;
+            @NonNull TotalCaptureResult inputResult) throws CameraAccessException;
 
     /**
      * Close the connection to this camera device as quickly as possible.
@@ -727,6 +747,16 @@
          */
         public static final int ERROR_CAMERA_SERVICE = 5;
 
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(
+            {ERROR_CAMERA_IN_USE,
+             ERROR_MAX_CAMERAS_IN_USE,
+             ERROR_CAMERA_DISABLED,
+             ERROR_CAMERA_DEVICE,
+             ERROR_CAMERA_SERVICE })
+        public @interface ErrorCode {};
+
         /**
          * The method called when a camera device has finished opening.
          *
@@ -736,7 +766,7 @@
          *
          * @param camera the camera device that has become opened
          */
-        public abstract void onOpened(CameraDevice camera); // Must implement
+        public abstract void onOpened(@NonNull CameraDevice camera); // Must implement
 
         /**
          * The method called when a camera device has been closed with
@@ -749,7 +779,7 @@
          *
          * @param camera the camera device that has become closed
          */
-        public void onClosed(CameraDevice camera) {
+        public void onClosed(@NonNull CameraDevice camera) {
             // Default empty implementation
         }
 
@@ -781,7 +811,7 @@
          *
          * @param camera the device that has been disconnected
          */
-        public abstract void onDisconnected(CameraDevice camera); // Must implement
+        public abstract void onDisconnected(@NonNull CameraDevice camera); // Must implement
 
         /**
          * The method called when a camera device has encountered a serious error.
@@ -805,12 +835,14 @@
          * @param error The error code, one of the
          *     {@code StateCallback.ERROR_*} values.
          *
+         * @see #ERROR_CAMERA_IN_USE
+         * @see #ERROR_MAX_CAMERAS_IN_USE
+         * @see #ERROR_CAMERA_DISABLED
          * @see #ERROR_CAMERA_DEVICE
          * @see #ERROR_CAMERA_SERVICE
-         * @see #ERROR_CAMERA_DISABLED
-         * @see #ERROR_CAMERA_IN_USE
          */
-        public abstract void onError(CameraDevice camera, int error); // Must implement
+        public abstract void onError(@NonNull CameraDevice camera,
+                @ErrorCode int error); // Must implement
     }
 
     /**
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index d99cce7..20e1610 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -16,6 +16,9 @@
 
 package android.hardware.camera2;
 
+import android.annotation.RequiresPermission;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceListener;
@@ -86,6 +89,7 @@
      *
      * @return The list of currently connected camera devices.
      */
+    @NonNull
     public String[] getCameraIdList() throws CameraAccessException {
         synchronized (mLock) {
             // ID list creation handles various known failures in device enumeration, so only
@@ -121,7 +125,8 @@
      * @throws IllegalArgumentException if the handler is {@code null} but the current thread has
      *             no looper.
      */
-    public void registerAvailabilityCallback(AvailabilityCallback callback, Handler handler) {
+    public void registerAvailabilityCallback(@NonNull AvailabilityCallback callback,
+            @Nullable Handler handler) {
         if (handler == null) {
             Looper looper = Looper.myLooper();
             if (looper == null) {
@@ -142,7 +147,7 @@
      *
      * @param callback The callback to remove from the notification list
      */
-    public void unregisterAvailabilityCallback(AvailabilityCallback callback) {
+    public void unregisterAvailabilityCallback(@NonNull AvailabilityCallback callback) {
         CameraManagerGlobal.get().unregisterAvailabilityCallback(callback);
     }
 
@@ -168,7 +173,7 @@
      * @throws IllegalArgumentException if the handler is {@code null} but the current thread has
      *             no looper.
      */
-    public void registerTorchCallback(TorchCallback callback, Handler handler) {
+    public void registerTorchCallback(@NonNull TorchCallback callback, @Nullable Handler handler) {
         if (handler == null) {
             Looper looper = Looper.myLooper();
             if (looper == null) {
@@ -188,7 +193,7 @@
      *
      * @param callback The callback to remove from the notification list
      */
-    public void unregisterTorchCallback(TorchCallback callback) {
+    public void unregisterTorchCallback(@NonNull TorchCallback callback) {
         CameraManagerGlobal.get().unregisterTorchCallback(callback);
     }
 
@@ -201,15 +206,13 @@
      *
      * @throws IllegalArgumentException if the cameraId does not match any
      *         known camera device.
-     * @throws CameraAccessException if the camera is disabled by device policy, or
-     *         the camera device has been disconnected.
-     * @throws SecurityException if the application does not have permission to
-     *         access the camera
+     * @throws CameraAccessException if the camera device has been disconnected.
      *
      * @see #getCameraIdList
      * @see android.app.admin.DevicePolicyManager#setCameraDisabled
      */
-    public CameraCharacteristics getCameraCharacteristics(String cameraId)
+    @NonNull
+    public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
             throws CameraAccessException {
         CameraCharacteristics characteristics = null;
 
@@ -431,8 +434,9 @@
      * @see #getCameraIdList
      * @see android.app.admin.DevicePolicyManager#setCameraDisabled
      */
-    public void openCamera(String cameraId, final CameraDevice.StateCallback callback,
-            Handler handler)
+    @RequiresPermission(android.Manifest.permission.CAMERA)
+    public void openCamera(@NonNull String cameraId,
+            @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
             throws CameraAccessException {
 
         if (cameraId == null) {
@@ -444,7 +448,7 @@
                 handler = new Handler();
             } else {
                 throw new IllegalArgumentException(
-                        "Looper doesn't exist in the calling thread");
+                        "Handler argument is null, but no looper exists in the calling thread");
             }
         }
 
@@ -490,7 +494,8 @@
      *             or previously available camera device, or the camera device doesn't have a
      *             flash unit.
      */
-    public void setTorchMode(String cameraId, boolean enabled) throws CameraAccessException {
+    public void setTorchMode(@NonNull String cameraId, boolean enabled)
+            throws CameraAccessException {
         CameraManagerGlobal.get().setTorchMode(cameraId, enabled);
     }
 
@@ -517,7 +522,7 @@
          *
          * @param cameraId The unique identifier of the new camera.
          */
-        public void onCameraAvailable(String cameraId) {
+        public void onCameraAvailable(@NonNull String cameraId) {
             // default empty implementation
         }
 
@@ -532,7 +537,7 @@
          *
          * @param cameraId The unique identifier of the disconnected camera.
          */
-        public void onCameraUnavailable(String cameraId) {
+        public void onCameraUnavailable(@NonNull String cameraId) {
             // default empty implementation
         }
     }
@@ -572,7 +577,7 @@
          * @param cameraId The unique identifier of the camera whose torch mode has become
          *                 unavailable.
          */
-        public void onTorchModeUnavailable(String cameraId) {
+        public void onTorchModeUnavailable(@NonNull String cameraId) {
             // default empty implementation
         }
 
@@ -589,7 +594,7 @@
          *                off. {@code false} when the torch mode has becomes off and available to
          *                be turned on.
          */
-        public void onTorchModeChanged(String cameraId, boolean enabled) {
+        public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
             // default empty implementation
         }
     }
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 6baa660..cf091a9 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -16,6 +16,7 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.PublicKey;
 import android.hardware.camera2.impl.SyntheticKey;
@@ -103,6 +104,7 @@
      * @return List of the keys contained in this map.
      */
     @SuppressWarnings("unchecked")
+    @NonNull
     public List<TKey> getKeys() {
         Class<CameraMetadata<TKey>> thisClass = (Class<CameraMetadata<TKey>>) getClass();
         return Collections.unmodifiableList(
diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java
index c168ff1..8bb33f1 100644
--- a/core/java/android/hardware/camera2/CaptureFailure.java
+++ b/core/java/android/hardware/camera2/CaptureFailure.java
@@ -15,6 +15,12 @@
  */
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A report of failed capture for a single image capture from the image sensor.
  *
@@ -43,6 +49,13 @@
      */
     public static final int REASON_FLUSHED = 1;
 
+     /** @hide */
+     @Retention(RetentionPolicy.SOURCE)
+     @IntDef(
+         {REASON_ERROR,
+          REASON_FLUSHED })
+     public @interface FailureReason {};
+
     private final CaptureRequest mRequest;
     private final int mReason;
     private final boolean mDropped;
@@ -52,8 +65,8 @@
     /**
      * @hide
      */
-    public CaptureFailure(CaptureRequest request, int reason, boolean dropped, int sequenceId,
-            long frameNumber) {
+    public CaptureFailure(CaptureRequest request, int reason,
+            boolean dropped, int sequenceId, long frameNumber) {
         mRequest = request;
         mReason = reason;
         mDropped = dropped;
@@ -81,6 +94,7 @@
      *
      * @return The request associated with this failed capture. Never {@code null}.
      */
+    @NonNull
     public CaptureRequest getRequest() {
         return mRequest;
     }
@@ -110,6 +124,7 @@
      * @see #REASON_ERROR
      * @see #REASON_FLUSHED
      */
+    @FailureReason
     public int getReason() {
         return mReason;
     }
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 5fb9abc..8f7b983 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -16,6 +16,8 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.PublicKey;
 import android.hardware.camera2.impl.SyntheticKey;
@@ -117,6 +119,7 @@
          *
          * @return String representation of the key name
          */
+        @NonNull
         public String getName() {
             return mKey.getName();
         }
@@ -239,6 +242,7 @@
      * @param key The result field to read.
      * @return The value of that key, or {@code null} if the field is not set.
      */
+    @Nullable
     public <T> T get(Key<T> key) {
         return mSettings.get(key);
     }
@@ -268,6 +272,7 @@
      * {@inheritDoc}
      */
     @Override
+    @NonNull
     public List<Key<?>> getKeys() {
         // Force the javadoc for this function to show up on the CaptureRequest page
         return super.getKeys();
@@ -286,6 +291,7 @@
      *     no tag has been set.
      * @see Builder#setTag
      */
+    @Nullable
     public Object getTag() {
         return mUserTag;
     }
@@ -476,7 +482,7 @@
          *
          * @param outputTarget Surface to use as an output target for this request
          */
-        public void addTarget(Surface outputTarget) {
+        public void addTarget(@NonNull Surface outputTarget) {
             mRequest.mSurfaceSet.add(outputTarget);
         }
 
@@ -487,7 +493,7 @@
          *
          * @param outputTarget Surface to use as an output target for this request
          */
-        public void removeTarget(Surface outputTarget) {
+        public void removeTarget(@NonNull Surface outputTarget) {
             mRequest.mSurfaceSet.remove(outputTarget);
         }
 
@@ -499,7 +505,7 @@
          * @param value The value to set the field to, which must be of a matching
          * type to the key.
          */
-        public <T> void set(Key<T> key, T value) {
+        public <T> void set(@NonNull Key<T> key, T value) {
             mRequest.mSettings.set(key, value);
         }
 
@@ -512,6 +518,7 @@
          * @param key The metadata field to read.
          * @return The value of that key, or {@code null} if the field is not set.
          */
+        @Nullable
         public <T> T get(Key<T> key) {
             return mRequest.mSettings.get(key);
         }
@@ -527,7 +534,7 @@
          * @param tag an arbitrary Object to store with this request
          * @see CaptureRequest#getTag
          */
-        public void setTag(Object tag) {
+        public void setTag(@Nullable Object tag) {
             mRequest.mUserTag = tag;
         }
 
@@ -543,6 +550,7 @@
          * @return A new capture request instance, ready for submission to the
          * camera device.
          */
+        @NonNull
         public CaptureRequest build() {
             return new CaptureRequest(mRequest);
         }
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 0277c5b..f4017d0 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -16,6 +16,8 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.CaptureResultExtras;
 import android.hardware.camera2.impl.PublicKey;
@@ -102,6 +104,7 @@
          *
          * @return String representation of the key name
          */
+        @NonNull
         public String getName() {
             return mKey.getName();
         }
@@ -216,6 +219,7 @@
      * @param key The result field to read.
      * @return The value of that key, or {@code null} if the field is not set.
      */
+    @Nullable
     public <T> T get(Key<T> key) {
         T value = mResults.get(key);
         if (VERBOSE) Log.v(TAG, "#get for Key = " + key.getName() + ", returned value = " + value);
@@ -259,6 +263,7 @@
      * {@inheritDoc}
      */
     @Override
+    @NonNull
     public List<Key<?>> getKeys() {
         // Force the javadoc for this function to show up on the CaptureResult page
         return super.getKeys();
@@ -285,6 +290,7 @@
      *
      * @return The request associated with this result. Never {@code null}.
      */
+    @NonNull
     public CaptureRequest getRequest() {
         return mRequest;
     }
diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java
index f16d650..70afe5b 100644
--- a/core/java/android/hardware/camera2/DngCreator.java
+++ b/core/java/android/hardware/camera2/DngCreator.java
@@ -16,6 +16,9 @@
 
 package android.hardware.camera2;
 
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.ImageFormat;
@@ -80,7 +83,8 @@
      *          {@link android.hardware.camera2.CameraCharacteristics}.
      * @param metadata a metadata object to generate tags from.
      */
-    public DngCreator(CameraCharacteristics characteristics, CaptureResult metadata) {
+    public DngCreator(@NonNull CameraCharacteristics characteristics,
+            @NonNull CaptureResult metadata) {
         if (characteristics == null || metadata == null) {
             throw new IllegalArgumentException("Null argument to DngCreator constructor");
         }
@@ -126,6 +130,7 @@
      *                    </ul>
      * @return this {@link #DngCreator} object.
      */
+    @NonNull
     public DngCreator setOrientation(int orientation) {
         if (orientation < ExifInterface.ORIENTATION_UNDEFINED ||
                 orientation > ExifInterface.ORIENTATION_ROTATE_270) {
@@ -150,7 +155,8 @@
      * @throws java.lang.IllegalArgumentException if the given thumbnail image has a dimension
      *      larger than {@link #MAX_THUMBNAIL_DIMENSION}.
      */
-    public DngCreator setThumbnail(Bitmap pixels) {
+    @NonNull
+    public DngCreator setThumbnail(@NonNull Bitmap pixels) {
         if (pixels == null) {
             throw new IllegalArgumentException("Null argument to setThumbnail");
         }
@@ -185,7 +191,8 @@
      * @throws java.lang.IllegalArgumentException if the given thumbnail image has a dimension
      *      larger than {@link #MAX_THUMBNAIL_DIMENSION}.
      */
-    public DngCreator setThumbnail(Image pixels) {
+    @NonNull
+    public DngCreator setThumbnail(@NonNull Image pixels) {
         if (pixels == null) {
             throw new IllegalArgumentException("Null argument to setThumbnail");
         }
@@ -226,7 +233,8 @@
      * @throws java.lang.IllegalArgumentException if the given location object doesn't
      *          contain enough information to set location metadata.
      */
-    public DngCreator setLocation(Location location) {
+    @NonNull
+    public DngCreator setLocation(@NonNull Location location) {
         if (location == null) {
             throw new IllegalArgumentException("Null location passed to setLocation");
         }
@@ -258,7 +266,8 @@
      * @param description the user description string.
      * @return this {@link #DngCreator} object.
      */
-    public DngCreator setDescription(String description) {
+    @NonNull
+    public DngCreator setDescription(@NonNull String description) {
         if (description == null) {
             throw new IllegalArgumentException("Null description passed to setDescription.");
         }
@@ -293,8 +302,8 @@
      *          set to write a well-formatted DNG file.
      * @throws java.lang.IllegalArgumentException if the size passed in does not match the
      */
-    public void writeInputStream(OutputStream dngOutput, Size size, InputStream pixels, long offset)
-            throws IOException {
+    public void writeInputStream(@NonNull OutputStream dngOutput, @NonNull Size size,
+            @NonNull InputStream pixels, @IntRange(from=0) long offset) throws IOException {
         if (dngOutput == null) {
             throw new IllegalArgumentException("Null dngOutput passed to writeInputStream");
         } else if (size == null) {
@@ -345,7 +354,8 @@
      * @throws java.lang.IllegalStateException if not enough metadata information has been
      *          set to write a well-formatted DNG file.
      */
-    public void writeByteBuffer(OutputStream dngOutput, Size size, ByteBuffer pixels, long offset)
+    public void writeByteBuffer(@NonNull OutputStream dngOutput, @NonNull Size size,
+            @NonNull ByteBuffer pixels, @IntRange(from=0) long offset)
             throws IOException {
         if (dngOutput == null) {
             throw new IllegalArgumentException("Null dngOutput passed to writeByteBuffer");
@@ -381,7 +391,8 @@
      * @throws java.lang.IllegalStateException if not enough metadata information has been
      *          set to write a well-formatted DNG file.
      */
-    public void writeImage(OutputStream dngOutput, Image pixels) throws IOException {
+    public void writeImage(@NonNull OutputStream dngOutput, @NonNull Image pixels)
+            throws IOException {
         if (dngOutput == null) {
             throw new IllegalArgumentException("Null dngOutput to writeImage");
         } else if (pixels == null) {
diff --git a/core/java/android/hardware/camera2/TotalCaptureResult.java b/core/java/android/hardware/camera2/TotalCaptureResult.java
index fb3c098..657745c 100644
--- a/core/java/android/hardware/camera2/TotalCaptureResult.java
+++ b/core/java/android/hardware/camera2/TotalCaptureResult.java
@@ -16,6 +16,7 @@
 
 package android.hardware.camera2;
 
+import android.annotation.NonNull;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.CaptureResultExtras;
 
@@ -96,6 +97,7 @@
      *
      * @return unmodifiable list of partial results
      */
+    @NonNull
     public List<CaptureResult> getPartialResults() {
         return Collections.unmodifiableList(mPartialResults);
     }
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 4508dc8..c4e8b15 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -607,6 +607,8 @@
     }
 
     public void prepare(Surface surface) throws CameraAccessException {
+        if (surface == null) throw new IllegalArgumentException("Surface is null");
+
         synchronized(mInterfaceLock) {
             int streamId = -1;
             for (int i = 0; i < mConfiguredOutputs.size(); i++) {