Merge "Pass valid file descriptor to binder"
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index f87abde..0feed68 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -25,12 +25,14 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.util.Log;
import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
-import java.io.FileDescriptor;
+import java.io.File;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
@@ -43,6 +45,9 @@
@SystemApi
@SystemService(Context.BUGREPORT_SERVICE)
public final class BugreportManager {
+
+ private static final String TAG = "BugreportManager";
+
private final Context mContext;
private final IDumpstate mBinder;
@@ -141,22 +146,35 @@
@NonNull BugreportParams params,
@NonNull @CallbackExecutor Executor executor,
@NonNull BugreportCallback callback) {
+ File tmpScreenshotFile = null;
try {
Preconditions.checkNotNull(bugreportFd);
Preconditions.checkNotNull(params);
Preconditions.checkNotNull(executor);
Preconditions.checkNotNull(callback);
- DumpstateListener dsListener = new DumpstateListener(executor, callback);
+ if (screenshotFd == null) {
+ // Binder needs a valid File Descriptor to be passed
+ tmpScreenshotFile = File.createTempFile("tmp", ".png");
+ screenshotFd = ParcelFileDescriptor.open(tmpScreenshotFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ }
+ DumpstateListener dsListener = new DumpstateListener(executor,
+ callback, tmpScreenshotFile);
+
// Note: mBinder can get callingUid from the binder transaction.
mBinder.startBugreport(-1 /* callingUid */,
mContext.getOpPackageName(),
bugreportFd.getFileDescriptor(),
- (screenshotFd != null
- ? screenshotFd.getFileDescriptor() : new FileDescriptor()),
+ screenshotFd.getFileDescriptor(),
params.getMode(), dsListener);
} catch (RemoteException e) {
+ deleteFile(tmpScreenshotFile);
throw e.rethrowFromSystemServer();
+ } catch (IOException e) {
+ // Need to delete the file if it was created but failed while trying to get fd
+ deleteFile(tmpScreenshotFile);
+ Log.e(TAG, "Not able to create/open temporary screenshot file ", e);
} finally {
// We can close the file descriptors here because binder would have duped them.
IoUtils.closeQuietly(bugreportFd);
@@ -178,13 +196,26 @@
}
}
+ private void deleteFile(@Nullable File tmpScreenshotFile) {
+ try {
+ if (tmpScreenshotFile != null && tmpScreenshotFile.exists()) {
+ tmpScreenshotFile.delete();
+ }
+ } catch (SecurityException e) {
+ Log.e(TAG, "Not able to delete temporary screenshot file ", e);
+ }
+ }
+
private final class DumpstateListener extends IDumpstateListener.Stub {
private final Executor mExecutor;
private final BugreportCallback mCallback;
+ private final File mTmpScreenshotFile;
- DumpstateListener(Executor executor, BugreportCallback callback) {
+ DumpstateListener(Executor executor, BugreportCallback callback,
+ @Nullable File tmpScreenshotFile) {
mExecutor = executor;
mCallback = callback;
+ mTmpScreenshotFile = tmpScreenshotFile;
}
@Override
@@ -208,6 +239,7 @@
});
} finally {
Binder.restoreCallingIdentity(identity);
+ deleteFile(mTmpScreenshotFile);
}
}
@@ -220,6 +252,7 @@
});
} finally {
Binder.restoreCallingIdentity(identity);
+ deleteFile(mTmpScreenshotFile);
}
}