Merge "Fix fd leak while bypassing transcoding in media APIs" into sc-dev

This commit is contained in:
Zimuzo Ezeozue
2021-07-30 14:23:48 +00:00
committed by Android (Google) Code Review
4 changed files with 37 additions and 20 deletions

View File

@@ -1460,15 +1460,15 @@ public final class FileUtils {
/** {@hide} */ /** {@hide} */
@VisibleForTesting @VisibleForTesting
public static ParcelFileDescriptor convertToModernFd(FileDescriptor fd) { public static ParcelFileDescriptor convertToModernFd(FileDescriptor fd) {
try { Context context = AppGlobals.getInitialApplication();
Context context = AppGlobals.getInitialApplication(); if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) { // Never convert modern fd for MediaProvider, because this requires
// Never convert modern fd for MediaProvider, because this requires // MediaStore#scanFile and can cause infinite loops when MediaProvider scans
// MediaStore#scanFile and can cause infinite loops when MediaProvider scans return null;
return null; }
}
return MediaStore.getOriginalMediaFormatFileDescriptor(context, try (ParcelFileDescriptor dupFd = ParcelFileDescriptor.dup(fd)) {
ParcelFileDescriptor.dup(fd)); return MediaStore.getOriginalMediaFormatFileDescriptor(context, dupFd);
} catch (Exception e) { } catch (Exception e) {
Log.d(TAG, "Failed to convert to modern format file descriptor", e); Log.d(TAG, "Failed to convert to modern format file descriptor", e);
return null; return null;

View File

@@ -1573,6 +1573,9 @@ public class ExifInterface {
if (isFdDuped) { if (isFdDuped) {
closeFileDescriptor(fileDescriptor); closeFileDescriptor(fileDescriptor);
} }
if (modernFd != null) {
modernFd.close();
}
} }
} }
@@ -2554,12 +2557,13 @@ public class ExifInterface {
private void initForFilename(String filename) throws IOException { private void initForFilename(String filename) throws IOException {
FileInputStream in = null; FileInputStream in = null;
ParcelFileDescriptor modernFd = null;
mAssetInputStream = null; mAssetInputStream = null;
mFilename = filename; mFilename = filename;
mIsInputStream = false; mIsInputStream = false;
try { try {
in = new FileInputStream(filename); in = new FileInputStream(filename);
ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(in.getFD()); modernFd = FileUtils.convertToModernFd(in.getFD());
if (modernFd != null) { if (modernFd != null) {
closeQuietly(in); closeQuietly(in);
in = new FileInputStream(modernFd.getFileDescriptor()); in = new FileInputStream(modernFd.getFileDescriptor());
@@ -2570,6 +2574,9 @@ public class ExifInterface {
loadAttributes(in); loadAttributes(in);
} finally { } finally {
closeQuietly(in); closeQuietly(in);
if (modernFd != null) {
modernFd.close();
}
} }
} }

View File

@@ -36,6 +36,7 @@ import android.os.IBinder;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -52,6 +53,8 @@ import java.util.Map;
* frame and meta data from an input media file. * frame and meta data from an input media file.
*/ */
public class MediaMetadataRetriever implements AutoCloseable { public class MediaMetadataRetriever implements AutoCloseable {
private static final String TAG = "MediaMetadataRetriever";
// borrowed from ExoPlayer // borrowed from ExoPlayer
private static final String[] STANDARD_GENRES = new String[] { private static final String[] STANDARD_GENRES = new String[] {
// These are the official ID3v1 genres. // These are the official ID3v1 genres.
@@ -301,11 +304,15 @@ public class MediaMetadataRetriever implements AutoCloseable {
*/ */
public void setDataSource(FileDescriptor fd, long offset, long length) public void setDataSource(FileDescriptor fd, long offset, long length)
throws IllegalArgumentException { throws IllegalArgumentException {
ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd);
if (modernFd == null) { try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
_setDataSource(fd, offset, length); if (modernFd == null) {
} else { _setDataSource(fd, offset, length);
_setDataSource(modernFd.getFileDescriptor(), offset, length); } else {
_setDataSource(modernFd.getFileDescriptor(), offset, length);
}
} catch (IOException e) {
Log.w(TAG, "Ignoring IO error while setting data source", e);
} }
} }

View File

@@ -1271,11 +1271,14 @@ public class MediaPlayer extends PlayerBase
*/ */
public void setDataSource(FileDescriptor fd, long offset, long length) public void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException { throws IOException, IllegalArgumentException, IllegalStateException {
ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd); try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
if (modernFd == null) { if (modernFd == null) {
_setDataSource(fd, offset, length); _setDataSource(fd, offset, length);
} else { } else {
_setDataSource(modernFd.getFileDescriptor(), offset, length); _setDataSource(modernFd.getFileDescriptor(), offset, length);
}
} catch (IOException e) {
Log.w(TAG, "Ignoring IO error while setting data source", e);
} }
} }