From 06e7d766be50021c42b828ad39f8a5c87399c421 Mon Sep 17 00:00:00 2001 From: Jin Seok Park Date: Fri, 18 Sep 2020 16:31:18 +0900 Subject: [PATCH] Remove using File(FileDescriptor, boolean) Instead, manually close the duplicated file descriptor. Bug: 159569444 Test: N/A Change-Id: If6860791fff1b1794031922d9e0f936f3861cac5 --- media/java/android/media/ExifInterface.java | 23 ++++++++++++------- .../android/media/ExifInterfaceUtils.java | 18 +++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 57e8e438d5926..ddc7db7715501 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -17,6 +17,7 @@ package android.media; import static android.media.ExifInterfaceUtils.byteArrayToHexString; +import static android.media.ExifInterfaceUtils.closeFileDescriptor; import static android.media.ExifInterfaceUtils.closeQuietly; import static android.media.ExifInterfaceUtils.convertToLongArray; import static android.media.ExifInterfaceUtils.copy; @@ -1529,9 +1530,8 @@ public class ExifInterface { mAssetInputStream = null; mFilename = null; - // When FileDescriptor is duplicated and set to FileInputStream, ownership needs to be - // clarified in order for garbage collection to take place. - boolean isFdOwner = false; + + boolean isFdDuped = false; if (isSeekableFD(fileDescriptor)) { mSeekableFileDescriptor = fileDescriptor; // Keep the original file descriptor in order to save attributes when it's seekable. @@ -1539,7 +1539,7 @@ public class ExifInterface { // feature won't be working. try { fileDescriptor = Os.dup(fileDescriptor); - isFdOwner = true; + isFdDuped = true; } catch (ErrnoException e) { throw e.rethrowAsIOException(); } @@ -1549,10 +1549,13 @@ public class ExifInterface { mIsInputStream = false; FileInputStream in = null; try { - in = new FileInputStream(fileDescriptor, isFdOwner); + in = new FileInputStream(fileDescriptor); loadAttributes(in); } finally { closeQuietly(in); + if (isFdDuped) { + closeFileDescriptor(fileDescriptor); + } } } @@ -2199,6 +2202,7 @@ public class ExifInterface { // Read the thumbnail. InputStream in = null; + FileDescriptor newFileDescriptor = null; try { if (mAssetInputStream != null) { in = mAssetInputStream; @@ -2211,9 +2215,9 @@ public class ExifInterface { } else if (mFilename != null) { in = new FileInputStream(mFilename); } else if (mSeekableFileDescriptor != null) { - FileDescriptor fileDescriptor = Os.dup(mSeekableFileDescriptor); - Os.lseek(fileDescriptor, 0, OsConstants.SEEK_SET); - in = new FileInputStream(fileDescriptor, true); + newFileDescriptor = Os.dup(mSeekableFileDescriptor); + Os.lseek(newFileDescriptor, 0, OsConstants.SEEK_SET); + in = new FileInputStream(newFileDescriptor); } if (in == null) { // Should not be reached this. @@ -2234,6 +2238,9 @@ public class ExifInterface { Log.d(TAG, "Encountered exception while getting thumbnail", e); } finally { closeQuietly(in); + if (newFileDescriptor != null) { + closeFileDescriptor(newFileDescriptor); + } } return null; } diff --git a/media/java/android/media/ExifInterfaceUtils.java b/media/java/android/media/ExifInterfaceUtils.java index 6ff706e8041f0..491fe1d64ab92 100644 --- a/media/java/android/media/ExifInterfaceUtils.java +++ b/media/java/android/media/ExifInterfaceUtils.java @@ -16,7 +16,12 @@ package android.media; +import android.system.ErrnoException; +import android.system.Os; +import android.util.Log; + import java.io.Closeable; +import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -25,6 +30,8 @@ import java.io.OutputStream; * Package private utility class for ExifInterface. */ class ExifInterfaceUtils { + private static final String TAG = "ExifInterface"; + /** * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed. * Returns the total number of bytes transferred. @@ -114,4 +121,15 @@ class ExifInterfaceUtils { } } } + + /** + * Closes a file descriptor that has been duplicated. + */ + public static void closeFileDescriptor(FileDescriptor fd) { + try { + Os.close(fd); + } catch (ErrnoException ex) { + Log.e(TAG, "Error closing fd.", ex); + } + } }