Merge "[Exif] Throw NPE after checking @NonNull parameters"
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index ccabd7c..f0a7eaa 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1316,10 +1316,10 @@
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private final String mFilename;
-    private final FileDescriptor mSeekableFileDescriptor;
-    private final AssetManager.AssetInputStream mAssetInputStream;
-    private final boolean mIsInputStream;
+    private String mFilename;
+    private FileDescriptor mSeekableFileDescriptor;
+    private AssetManager.AssetInputStream mAssetInputStream;
+    private boolean mIsInputStream;
     private int mMimeType;
     @UnsupportedAppUsage
     private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
@@ -1350,7 +1350,10 @@
      * Reads Exif tags from the specified image file.
      */
     public ExifInterface(@NonNull File file) throws IOException {
-        this(file.getAbsolutePath());
+        if (file == null) {
+            throw new NullPointerException("file cannot be null");
+        }
+        initForFilename(file.getName());
     }
 
     /**
@@ -1358,23 +1361,9 @@
      */
     public ExifInterface(@NonNull String filename) throws IOException {
         if (filename == null) {
-            throw new IllegalArgumentException("filename cannot be null");
+            throw new NullPointerException("filename cannot be null");
         }
-        FileInputStream in = null;
-        mAssetInputStream = null;
-        mFilename = filename;
-        mIsInputStream = false;
-        try {
-            in = new FileInputStream(filename);
-            if (isSeekableFD(in.getFD())) {
-                mSeekableFileDescriptor = in.getFD();
-            } else {
-                mSeekableFileDescriptor = null;
-            }
-            loadAttributes(in);
-        } finally {
-            IoUtils.closeQuietly(in);
-        }
+        initForFilename(filename);
     }
 
     /**
@@ -1384,7 +1373,7 @@
      */
     public ExifInterface(@NonNull FileDescriptor fileDescriptor) throws IOException {
         if (fileDescriptor == null) {
-            throw new IllegalArgumentException("fileDescriptor cannot be null");
+            throw new NullPointerException("fileDescriptor cannot be null");
         }
         mAssetInputStream = null;
         mFilename = null;
@@ -1418,7 +1407,7 @@
      */
     public ExifInterface(@NonNull InputStream inputStream) throws IOException {
         if (inputStream == null) {
-            throw new IllegalArgumentException("inputStream cannot be null");
+            throw new NullPointerException("inputStream cannot be null");
         }
         mFilename = null;
         if (inputStream instanceof AssetManager.AssetInputStream) {
@@ -1443,6 +1432,9 @@
      * @param tag the name of the tag.
      */
     private @Nullable ExifAttribute getExifAttribute(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         // Retrieves all tag groups. The value from primary image tag group has a higher priority
         // than the value from the thumbnail tag group if there are more than one candidates.
         for (int i = 0; i < EXIF_TAGS.length; ++i) {
@@ -1461,6 +1453,9 @@
      * @param tag the name of the tag.
      */
     public @Nullable String getAttribute(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         ExifAttribute attribute = getExifAttribute(tag);
         if (attribute != null) {
             if (!sTagSetForCompatibility.contains(tag)) {
@@ -1499,6 +1494,9 @@
      * @param defaultValue the value to return if the tag is not available.
      */
     public int getAttributeInt(@NonNull String tag, int defaultValue) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         ExifAttribute exifAttribute = getExifAttribute(tag);
         if (exifAttribute == null) {
             return defaultValue;
@@ -1520,6 +1518,9 @@
      * @param defaultValue the value to return if the tag is not available.
      */
     public double getAttributeDouble(@NonNull String tag, double defaultValue) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         ExifAttribute exifAttribute = getExifAttribute(tag);
         if (exifAttribute == null) {
             return defaultValue;
@@ -1539,6 +1540,9 @@
      * @param value the value of the tag.
      */
     public void setAttribute(@NonNull String tag, @Nullable String value) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         // Convert the given value to rational values for backwards compatibility.
         if (value != null && sTagSetForCompatibility.contains(tag)) {
             if (tag.equals(TAG_GPS_TIMESTAMP)) {
@@ -1708,6 +1712,9 @@
      * determine whether the image data format is JPEG or not.
      */
     private void loadAttributes(@NonNull InputStream in) throws IOException {
+        if (in == null) {
+            throw new NullPointerException("inputstream shouldn't be null");
+        }
         try {
             // Initialize mAttributes.
             for (int i = 0; i < EXIF_TAGS.length; ++i) {
@@ -2043,6 +2050,9 @@
      *             that means offsets may have changed.
      */
     public @Nullable long[] getAttributeRange(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         if (mModified) {
             throw new IllegalStateException(
                     "The underlying file has been modified since being parsed");
@@ -2064,6 +2074,9 @@
      *         no tag was found.
      */
     public @Nullable byte[] getAttributeBytes(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
         final ExifAttribute attribute = getExifAttribute(tag);
         if (attribute != null) {
             return attribute.bytes;
@@ -2234,6 +2247,24 @@
         }
     }
 
+    private void initForFilename(String filename) throws IOException {
+        FileInputStream in = null;
+        mAssetInputStream = null;
+        mFilename = filename;
+        mIsInputStream = false;
+        try {
+            in = new FileInputStream(filename);
+            if (isSeekableFD(in.getFD())) {
+                mSeekableFileDescriptor = in.getFD();
+            } else {
+                mSeekableFileDescriptor = null;
+            }
+            loadAttributes(in);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
     // Checks the type of image file
     private int getMimeType(BufferedInputStream in) throws IOException {
         in.mark(SIGNATURE_CHECK_SIZE);