Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -32138,9 +32138,11 @@ package android.os { method public void onEarlyReportFinished(); method public void onError(int); method public void onFinished(); method public void onFinished(@NonNull String); method public void onProgress(@FloatRange(from=0.0f, to=100.0f) float); field public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = 5; // 0x5 field public static final int BUGREPORT_ERROR_INVALID_INPUT = 1; // 0x1 field public static final int BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE = 6; // 0x6 field public static final int BUGREPORT_ERROR_RUNTIME = 2; // 0x2 field public static final int BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT = 4; // 0x4 field public static final int BUGREPORT_ERROR_USER_DENIED_CONSENT = 3; // 0x3 core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -9934,6 +9934,7 @@ package android.os { public final class BugreportManager { method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void preDumpUiData(); method @RequiresPermission(android.Manifest.permission.DUMP) public void requestBugreport(@NonNull android.os.BugreportParams, @Nullable CharSequence, @Nullable CharSequence); method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void retrieveBugreport(@NonNull String, @NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback); method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback); } Loading @@ -9942,6 +9943,7 @@ package android.os { ctor public BugreportParams(int, int); method public int getFlags(); method public int getMode(); field public static final int BUGREPORT_FLAG_DEFER_CONSENT = 2; // 0x2 field public static final int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 1; // 0x1 field public static final int BUGREPORT_MODE_FULL = 0; // 0x0 field public static final int BUGREPORT_MODE_INTERACTIVE = 1; // 0x1 core/java/android/os/BugreportManager.java +98 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FloatRange; import android.annotation.IntDef; Loading Loading @@ -69,7 +70,10 @@ public final class BugreportManager { * An interface describing the callback for bugreport progress and status. * * <p>Callers will receive {@link #onProgress} calls as the bugreport progresses, followed by a * terminal call to either {@link #onFinished} or {@link #onError}. * terminal call to either {@link #onFinished} or {@link #onError}. Note that * {@link #onFinished(String)} will only be invoked when calling {@code startBugreport} with the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag set. Otherwise, * {@link #onFinished()} will be invoked. * * <p>If an issue is encountered while starting the bugreport asynchronously, callers will * receive an {@link #onError} call without any {@link #onProgress} callbacks. Loading @@ -88,7 +92,8 @@ public final class BugreportManager { BUGREPORT_ERROR_RUNTIME, BUGREPORT_ERROR_USER_DENIED_CONSENT, BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT, BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS, BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE }) public @interface BugreportErrorCode {} Loading @@ -115,6 +120,10 @@ public final class BugreportManager { public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = IDumpstateListener.BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS; /** There is no bugreport to retrieve for the caller. */ public static final int BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE = IDumpstateListener.BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE; /** * Called when there is a progress update. * Loading @@ -137,9 +146,25 @@ public final class BugreportManager { */ public void onError(@BugreportErrorCode int errorCode) {} /** Called when taking bugreport finishes successfully. */ /** Called when taking bugreport finishes successfully. * * <p>This callback will be invoked if the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is not set. Otherwise, the * {@link #onFinished(String)} callback will be invoked. */ public void onFinished() {} /** Called when taking bugreport finishes successfully. * * <p>This callback will only be invoked if the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is set. Otherwise, the * {@link #onFinished()} callback will be invoked. * * @param bugreportFile the absolute path of the generated bugreport file. */ public void onFinished(@NonNull String bugreportFile) {} /** * Called when it is ready for calling app to show UI, showing any extra UI before this * callback can interfere with bugreport generation. Loading Loading @@ -178,7 +203,9 @@ public final class BugreportManager { * updates. * * <p>The bugreport artifacts will be copied over to the given file descriptors only if the user * consents to sharing with the calling app. * consents to sharing with the calling app. If * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} is set, user consent will be deferred * and no files will be copied to the given file descriptors. * * <p>{@link BugreportManager} takes ownership of {@code bugreportFd} and {@code screenshotFd}. * Loading @@ -205,7 +232,9 @@ public final class BugreportManager { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(callback); boolean isScreenshotRequested = screenshotFd != null; boolean deferConsent = (params.getFlags() & BugreportParams.BUGREPORT_FLAG_DEFER_CONSENT) != 0; boolean isScreenshotRequested = screenshotFd != null || deferConsent; if (screenshotFd == null) { // Binder needs a valid File Descriptor to be passed screenshotFd = Loading @@ -213,7 +242,7 @@ public final class BugreportManager { new File("/dev/null"), ParcelFileDescriptor.MODE_READ_ONLY); } DumpstateListener dsListener = new DumpstateListener(executor, callback, isScreenshotRequested); new DumpstateListener(executor, callback, isScreenshotRequested, deferConsent); // Note: mBinder can get callingUid from the binder transaction. mBinder.startBugreport( -1 /* callingUid */, Loading @@ -237,6 +266,58 @@ public final class BugreportManager { } } /** * Retrieves a previously generated bugreport. * * <p>The previously generated bugreport must have been generated by calling {@link * #startBugreport(ParcelFileDescriptor, ParcelFileDescriptor, BugreportParams, * Executor, BugreportCallback)} with the {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} * flag set. The bugreport file returned by the {@link BugreportCallback#onFinished(String)} * callback for a previously generated bugreport must be passed to this method. A caller may * only retrieve bugreports that they have previously requested. * * <p>The bugreport artifacts will be copied over to the given file descriptor only if the user * consents to sharing with the calling app. * * <p>{@link BugreportManager} takes ownership of {@code bugreportFd} and {@code screenshotFd}. * * <p>The caller may only request to retrieve a given bugreport once. Subsequent calls will fail * with error code {@link BugreportCallback#BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE}. * * @param bugreportFile the identifier for a bugreport that was previously generated for this * caller using {@code startBugreport}. * @param bugreportFd file to copy over the previous bugreport. This should be opened in * write-only, append mode. * @param executor the executor to execute callback methods. * @param callback callback for progress and status updates. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.DUMP) @WorkerThread public void retrieveBugreport( @NonNull String bugreportFile, @NonNull ParcelFileDescriptor bugreportFd, @NonNull @CallbackExecutor Executor executor, @NonNull BugreportCallback callback ) { try { Preconditions.checkNotNull(bugreportFile); Preconditions.checkNotNull(bugreportFd); Preconditions.checkNotNull(executor); Preconditions.checkNotNull(callback); DumpstateListener dsListener = new DumpstateListener(executor, callback, false, false); mBinder.retrieveBugreport(Binder.getCallingUid(), mContext.getOpPackageName(), bugreportFd.getFileDescriptor(), bugreportFile, dsListener); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } finally { IoUtils.closeQuietly(bugreportFd); } } /** * Starts a connectivity bugreport. * Loading Loading @@ -316,7 +397,7 @@ public final class BugreportManager { * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.DUMP) @RequiresPermission(Manifest.permission.DUMP) public void requestBugreport( @NonNull BugreportParams params, @Nullable CharSequence shareTitle, Loading @@ -335,12 +416,15 @@ public final class BugreportManager { private final Executor mExecutor; private final BugreportCallback mCallback; private final boolean mIsScreenshotRequested; private final boolean mIsConsentDeferred; DumpstateListener( Executor executor, BugreportCallback callback, boolean isScreenshotRequested) { Executor executor, BugreportCallback callback, boolean isScreenshotRequested, boolean isConsentDeferred) { mExecutor = executor; mCallback = callback; mIsScreenshotRequested = isScreenshotRequested; mIsConsentDeferred = isConsentDeferred; } @Override Loading @@ -364,10 +448,14 @@ public final class BugreportManager { } @Override public void onFinished() throws RemoteException { public void onFinished(String bugreportFile) throws RemoteException { final long identity = Binder.clearCallingIdentity(); try { if (mIsConsentDeferred) { mExecutor.execute(() -> mCallback.onFinished(bugreportFile)); } else { mExecutor.execute(() -> mCallback.onFinished()); } } finally { Binder.restoreCallingIdentity(identity); } Loading core/java/android/os/BugreportParams.java +13 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** * Parameters that specify what kind of bugreport should be taken. Loading Loading @@ -125,7 +126,8 @@ public final class BugreportParams { */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "BUGREPORT_FLAG_" }, value = { BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA, BUGREPORT_FLAG_DEFER_CONSENT }) public @interface BugreportFlag {} Loading @@ -135,4 +137,14 @@ public final class BugreportParams { */ public static final int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = IDumpstate.BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA; /** * Flag for deferring user consent. * * <p>This flag should be used in cases where it may not be possible for the user to respond * to a consent dialog immediately, such as when the user is driving. The generated bugreport * may be retrieved at a later time using {@link BugreportManager#retrieveBugreport( * String, ParcelFileDescriptor, Executor, BugreportManager.BugreportCallback)}. */ public static final int BUGREPORT_FLAG_DEFER_CONSENT = IDumpstate.BUGREPORT_FLAG_DEFER_CONSENT; } packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ public class BugreportReceiverTest { if (mScreenshotFd != null) { writeScreenshotFile(mScreenshotFd, SCREENSHOT_CONTENT); } mIDumpstateListener.onFinished(); mIDumpstateListener.onFinished(""); getInstrumentation().waitForIdleSync(); } Loading Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -32138,9 +32138,11 @@ package android.os { method public void onEarlyReportFinished(); method public void onError(int); method public void onFinished(); method public void onFinished(@NonNull String); method public void onProgress(@FloatRange(from=0.0f, to=100.0f) float); field public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = 5; // 0x5 field public static final int BUGREPORT_ERROR_INVALID_INPUT = 1; // 0x1 field public static final int BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE = 6; // 0x6 field public static final int BUGREPORT_ERROR_RUNTIME = 2; // 0x2 field public static final int BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT = 4; // 0x4 field public static final int BUGREPORT_ERROR_USER_DENIED_CONSENT = 3; // 0x3
core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -9934,6 +9934,7 @@ package android.os { public final class BugreportManager { method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void preDumpUiData(); method @RequiresPermission(android.Manifest.permission.DUMP) public void requestBugreport(@NonNull android.os.BugreportParams, @Nullable CharSequence, @Nullable CharSequence); method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void retrieveBugreport(@NonNull String, @NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback); method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback); } Loading @@ -9942,6 +9943,7 @@ package android.os { ctor public BugreportParams(int, int); method public int getFlags(); method public int getMode(); field public static final int BUGREPORT_FLAG_DEFER_CONSENT = 2; // 0x2 field public static final int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 1; // 0x1 field public static final int BUGREPORT_MODE_FULL = 0; // 0x0 field public static final int BUGREPORT_MODE_INTERACTIVE = 1; // 0x1
core/java/android/os/BugreportManager.java +98 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FloatRange; import android.annotation.IntDef; Loading Loading @@ -69,7 +70,10 @@ public final class BugreportManager { * An interface describing the callback for bugreport progress and status. * * <p>Callers will receive {@link #onProgress} calls as the bugreport progresses, followed by a * terminal call to either {@link #onFinished} or {@link #onError}. * terminal call to either {@link #onFinished} or {@link #onError}. Note that * {@link #onFinished(String)} will only be invoked when calling {@code startBugreport} with the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag set. Otherwise, * {@link #onFinished()} will be invoked. * * <p>If an issue is encountered while starting the bugreport asynchronously, callers will * receive an {@link #onError} call without any {@link #onProgress} callbacks. Loading @@ -88,7 +92,8 @@ public final class BugreportManager { BUGREPORT_ERROR_RUNTIME, BUGREPORT_ERROR_USER_DENIED_CONSENT, BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT, BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS, BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE }) public @interface BugreportErrorCode {} Loading @@ -115,6 +120,10 @@ public final class BugreportManager { public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = IDumpstateListener.BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS; /** There is no bugreport to retrieve for the caller. */ public static final int BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE = IDumpstateListener.BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE; /** * Called when there is a progress update. * Loading @@ -137,9 +146,25 @@ public final class BugreportManager { */ public void onError(@BugreportErrorCode int errorCode) {} /** Called when taking bugreport finishes successfully. */ /** Called when taking bugreport finishes successfully. * * <p>This callback will be invoked if the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is not set. Otherwise, the * {@link #onFinished(String)} callback will be invoked. */ public void onFinished() {} /** Called when taking bugreport finishes successfully. * * <p>This callback will only be invoked if the * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is set. Otherwise, the * {@link #onFinished()} callback will be invoked. * * @param bugreportFile the absolute path of the generated bugreport file. */ public void onFinished(@NonNull String bugreportFile) {} /** * Called when it is ready for calling app to show UI, showing any extra UI before this * callback can interfere with bugreport generation. Loading Loading @@ -178,7 +203,9 @@ public final class BugreportManager { * updates. * * <p>The bugreport artifacts will be copied over to the given file descriptors only if the user * consents to sharing with the calling app. * consents to sharing with the calling app. If * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} is set, user consent will be deferred * and no files will be copied to the given file descriptors. * * <p>{@link BugreportManager} takes ownership of {@code bugreportFd} and {@code screenshotFd}. * Loading @@ -205,7 +232,9 @@ public final class BugreportManager { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(callback); boolean isScreenshotRequested = screenshotFd != null; boolean deferConsent = (params.getFlags() & BugreportParams.BUGREPORT_FLAG_DEFER_CONSENT) != 0; boolean isScreenshotRequested = screenshotFd != null || deferConsent; if (screenshotFd == null) { // Binder needs a valid File Descriptor to be passed screenshotFd = Loading @@ -213,7 +242,7 @@ public final class BugreportManager { new File("/dev/null"), ParcelFileDescriptor.MODE_READ_ONLY); } DumpstateListener dsListener = new DumpstateListener(executor, callback, isScreenshotRequested); new DumpstateListener(executor, callback, isScreenshotRequested, deferConsent); // Note: mBinder can get callingUid from the binder transaction. mBinder.startBugreport( -1 /* callingUid */, Loading @@ -237,6 +266,58 @@ public final class BugreportManager { } } /** * Retrieves a previously generated bugreport. * * <p>The previously generated bugreport must have been generated by calling {@link * #startBugreport(ParcelFileDescriptor, ParcelFileDescriptor, BugreportParams, * Executor, BugreportCallback)} with the {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} * flag set. The bugreport file returned by the {@link BugreportCallback#onFinished(String)} * callback for a previously generated bugreport must be passed to this method. A caller may * only retrieve bugreports that they have previously requested. * * <p>The bugreport artifacts will be copied over to the given file descriptor only if the user * consents to sharing with the calling app. * * <p>{@link BugreportManager} takes ownership of {@code bugreportFd} and {@code screenshotFd}. * * <p>The caller may only request to retrieve a given bugreport once. Subsequent calls will fail * with error code {@link BugreportCallback#BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE}. * * @param bugreportFile the identifier for a bugreport that was previously generated for this * caller using {@code startBugreport}. * @param bugreportFd file to copy over the previous bugreport. This should be opened in * write-only, append mode. * @param executor the executor to execute callback methods. * @param callback callback for progress and status updates. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.DUMP) @WorkerThread public void retrieveBugreport( @NonNull String bugreportFile, @NonNull ParcelFileDescriptor bugreportFd, @NonNull @CallbackExecutor Executor executor, @NonNull BugreportCallback callback ) { try { Preconditions.checkNotNull(bugreportFile); Preconditions.checkNotNull(bugreportFd); Preconditions.checkNotNull(executor); Preconditions.checkNotNull(callback); DumpstateListener dsListener = new DumpstateListener(executor, callback, false, false); mBinder.retrieveBugreport(Binder.getCallingUid(), mContext.getOpPackageName(), bugreportFd.getFileDescriptor(), bugreportFile, dsListener); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } finally { IoUtils.closeQuietly(bugreportFd); } } /** * Starts a connectivity bugreport. * Loading Loading @@ -316,7 +397,7 @@ public final class BugreportManager { * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.DUMP) @RequiresPermission(Manifest.permission.DUMP) public void requestBugreport( @NonNull BugreportParams params, @Nullable CharSequence shareTitle, Loading @@ -335,12 +416,15 @@ public final class BugreportManager { private final Executor mExecutor; private final BugreportCallback mCallback; private final boolean mIsScreenshotRequested; private final boolean mIsConsentDeferred; DumpstateListener( Executor executor, BugreportCallback callback, boolean isScreenshotRequested) { Executor executor, BugreportCallback callback, boolean isScreenshotRequested, boolean isConsentDeferred) { mExecutor = executor; mCallback = callback; mIsScreenshotRequested = isScreenshotRequested; mIsConsentDeferred = isConsentDeferred; } @Override Loading @@ -364,10 +448,14 @@ public final class BugreportManager { } @Override public void onFinished() throws RemoteException { public void onFinished(String bugreportFile) throws RemoteException { final long identity = Binder.clearCallingIdentity(); try { if (mIsConsentDeferred) { mExecutor.execute(() -> mCallback.onFinished(bugreportFile)); } else { mExecutor.execute(() -> mCallback.onFinished()); } } finally { Binder.restoreCallingIdentity(identity); } Loading
core/java/android/os/BugreportParams.java +13 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** * Parameters that specify what kind of bugreport should be taken. Loading Loading @@ -125,7 +126,8 @@ public final class BugreportParams { */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "BUGREPORT_FLAG_" }, value = { BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA, BUGREPORT_FLAG_DEFER_CONSENT }) public @interface BugreportFlag {} Loading @@ -135,4 +137,14 @@ public final class BugreportParams { */ public static final int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = IDumpstate.BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA; /** * Flag for deferring user consent. * * <p>This flag should be used in cases where it may not be possible for the user to respond * to a consent dialog immediately, such as when the user is driving. The generated bugreport * may be retrieved at a later time using {@link BugreportManager#retrieveBugreport( * String, ParcelFileDescriptor, Executor, BugreportManager.BugreportCallback)}. */ public static final int BUGREPORT_FLAG_DEFER_CONSENT = IDumpstate.BUGREPORT_FLAG_DEFER_CONSENT; }
packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ public class BugreportReceiverTest { if (mScreenshotFd != null) { writeScreenshotFile(mScreenshotFd, SCREENSHOT_CONTENT); } mIDumpstateListener.onFinished(); mIDumpstateListener.onFinished(""); getInstrumentation().waitForIdleSync(); } Loading