Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78ae2b5b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Skeleton API for IncidentManager to retrieve incident reports."

parents 7b8b30b4 8daca758
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,7 @@ package android.content {
    field public static final String ACTION_DEVICE_CUSTOMIZATION_READY = "android.intent.action.DEVICE_CUSTOMIZATION_READY";
    field public static final String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET";
    field public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
    field public static final String ACTION_INCIDENT_REPORT_READY = "android.intent.action.INCIDENT_REPORT_READY";
    field public static final String ACTION_INSTALL_INSTANT_APP_PACKAGE = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE";
    field public static final String ACTION_INSTANT_APP_RESOLVER_SETTINGS = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS";
    field public static final String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION";
@@ -5362,11 +5363,17 @@ package android.os {
  public class IncidentManager {
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void approveReport(android.net.Uri);
    method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void cancelAuthorization(android.os.IncidentManager.AuthListener);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void deleteIncidentReports(android.net.Uri);
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void denyReport(android.net.Uri);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public java.util.List<android.net.Uri> getIncidentReportList(String);
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
    method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
    field public static final int FLAG_CONFIRMATION_DIALOG = 1; // 0x1
    field public static final int PRIVACY_POLICY_AUTO = 200; // 0xc8
    field public static final int PRIVACY_POLICY_EXPLICIT = 100; // 0x64
    field public static final int PRIVACY_POLICY_LOCAL = 0; // 0x0
  }
  public static class IncidentManager.AuthListener {
@@ -5375,6 +5382,17 @@ package android.os {
    method public void onReportDenied();
  }
  public static class IncidentManager.IncidentReport implements java.io.Closeable android.os.Parcelable {
    ctor public IncidentManager.IncidentReport(android.os.Parcel);
    method public void close();
    method public int describeContents();
    method public java.io.InputStream getInputStream() throws java.io.IOException;
    method public long getPrivacyPolicy();
    method public long getTimestamp();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.os.IncidentManager.IncidentReport> CREATOR;
  }
  public static class IncidentManager.PendingReport {
    ctor public IncidentManager.PendingReport(@NonNull android.net.Uri);
    method public int getFlags();
+17 −0
Original line number Diff line number Diff line
@@ -1285,11 +1285,17 @@ package android.os {
  public class IncidentManager {
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void approveReport(android.net.Uri);
    method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void cancelAuthorization(android.os.IncidentManager.AuthListener);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void deleteIncidentReports(android.net.Uri);
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void denyReport(android.net.Uri);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public java.util.List<android.net.Uri> getIncidentReportList(String);
    method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
    method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
    field public static final int FLAG_CONFIRMATION_DIALOG = 1; // 0x1
    field public static final int PRIVACY_POLICY_AUTO = 200; // 0xc8
    field public static final int PRIVACY_POLICY_EXPLICIT = 100; // 0x64
    field public static final int PRIVACY_POLICY_LOCAL = 0; // 0x0
  }

  public static class IncidentManager.AuthListener {
@@ -1298,6 +1304,17 @@ package android.os {
    method public void onReportDenied();
  }

  public static class IncidentManager.IncidentReport implements java.io.Closeable android.os.Parcelable {
    ctor public IncidentManager.IncidentReport(android.os.Parcel);
    method public void close();
    method public int describeContents();
    method public java.io.InputStream getInputStream() throws java.io.IOException;
    method public long getPrivacyPolicy();
    method public long getTimestamp();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.os.IncidentManager.IncidentReport> CREATOR;
  }

  public static class IncidentManager.PendingReport {
    ctor public IncidentManager.PendingReport(@NonNull android.net.Uri);
    method public int getFlags();
+18 −0
Original line number Diff line number Diff line
@@ -1486,6 +1486,24 @@ public class Intent implements Parcelable, Cloneable {
    public static final String ACTION_PENDING_INCIDENT_REPORTS_CHANGED =
            "android.intent.action.PENDING_INCIDENT_REPORTS_CHANGED";

    /**
     * An incident report has been taken, and the user has approved it for sharing.
     * <p>
     * This will be sent directly to the registered receiver, which must have
     * both the DUMP and USAGE_STATS permissions.
     * <p>
     * After receiving this, the application should wait until a suitable time
     * (e.g. network available), get the list of available reports with
     * {@link IncidentManager#getIncidentReportList IncidentManager.getIncidentReportList(String)}
     * and then when the reports have been successfully uploaded, call
     * {@link IncidentManager#deleteIncidentReport IncidentManager.deleteIncidentReport(Uri)}.
     *
     * @hide
     */
    @SystemApi
    public static final String ACTION_INCIDENT_REPORT_READY =
            "android.intent.action.INCIDENT_REPORT_READY";

    /**
     * Activity Action: Show power usage information to the user.
     * <p>Input: Nothing.
+185 −1
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.os;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -25,6 +27,11 @@ import android.content.Context;
import android.net.Uri;
import android.util.Slog;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

@@ -95,6 +102,33 @@ public class IncidentManager {
     */
    public static final int FLAG_CONFIRMATION_DIALOG = 0x1;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device only via adb.
     */
    public static final int PRIVACY_POLICY_LOCAL = 0;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device with contemporary consent.
     */
    public static final int PRIVACY_POLICY_EXPLICIT = 100;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device with prior consent.
     */
    public static final int PRIVACY_POLICY_AUTO = 200;

    /** @hide */
    @IntDef(flag = false, prefix = { "PRIVACY_POLICY_" }, value = {
            PRIVACY_POLICY_AUTO,
            PRIVACY_POLICY_EXPLICIT,
            PRIVACY_POLICY_LOCAL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PrivacyPolicy {}

    private final Context mContext;

    private Object mLock = new Object();
@@ -202,6 +236,110 @@ public class IncidentManager {
        }
    }

    /**
     * Record of an incident report that has previously been taken.
     * @hide
     */
    @SystemApi
    @TestApi
    public static class IncidentReport implements Parcelable, Closeable {
        private final long mTimestampMs;
        private final int mPrivacyPolicy;
        private ParcelFileDescriptor mFileDescriptor;

        public IncidentReport(Parcel in) {
            mTimestampMs = in.readLong();
            mPrivacyPolicy = in.readInt();
            if (in.readInt() != 0) {
                mFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
            } else {
                mFileDescriptor = null;
            }
        }

        /**
         * Close the input stream associated with this entry.
         */
        public void close() {
            try {
                if (mFileDescriptor != null) {
                    mFileDescriptor.close();
                    mFileDescriptor = null;
                }
            } catch (IOException e) {
            }
        }

        /**
         * Get the time at which this incident report was taken, in wall clock time
         * ({@link System#uptimeMillis System.uptimeMillis()} time base).
         */
        public long getTimestamp() {
            return mTimestampMs;
        }

        /**
         * Get the privacy level to which this report has been filtered.
         *
         * @see #PRIVACY_POLICY_AUTO
         * @see #PRIVACY_POLICY_EXPLICIT
         * @see #PRIVACY_POLICY_LOCAL
         */
        public long getPrivacyPolicy() {
            return mPrivacyPolicy;
        }

        /**
         * Get the contents of this incident report.
         */
        public InputStream getInputStream() throws IOException {
            if (mFileDescriptor == null) {
                return null;
            }
            return new ParcelFileDescriptor.AutoCloseInputStream(mFileDescriptor);
        }

        /**
         * @inheritDoc
         */
        public int describeContents() {
            return mFileDescriptor != null ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
        }

        /**
         * @inheritDoc
         */
        public void writeToParcel(Parcel out, int flags) {
            out.writeLong(mTimestampMs);
            out.writeInt(mPrivacyPolicy);
            if (mFileDescriptor != null) {
                out.writeInt(1);
                mFileDescriptor.writeToParcel(out, flags);
            } else {
                out.writeInt(0);
            }
        }

        /**
         * {@link Parcelable.Creator Creator} for {@link IncidentReport}.
         */
        public static final Parcelable.Creator<IncidentReport> CREATOR = new Parcelable.Creator() {
            /**
             * @inheritDoc
             */
            public IncidentReport[] newArray(int size) {
                return new IncidentReport[size];
            }

            /**
             * @inheritDoc
             */
            public IncidentReport createFromParcel(Parcel in) {
                return new IncidentReport(in);
            }
        };
    }

    /**
     * Listener for the status of an incident report being authroized or denied.
     *
@@ -242,7 +380,7 @@ public class IncidentManager {
    }

    /**
     * Take an incident report and put it in dropbox.
     * Take an incident report.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
@@ -325,6 +463,52 @@ public class IncidentManager {
        }
    }

    /**
     * Get the incident reports that are available for upload for the supplied
     * broadcast recevier.
     *
     * @param receiverClass Class name of broadcast receiver in this package that
     *   was registered to retrieve reports.
     *
     * @return A list of {@link Uri Uris} that are awaiting upload.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public @NonNull List<Uri> getIncidentReportList(String receiverClass) {
        throw new RuntimeException("implement me");
    }

    /**
     * Get the incident report with the given URI id.
     *
     * @param uri Identifier of the incident report.
     *
     * @return an IncidentReport object, or null if the incident report has been
     *  expired from disk.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public @Nullable IncidentReport getIncidentReport(Uri uri) {
        throw new RuntimeException("implement me");
    }

    /**
     * Delete the incident report with the given URI id.
     *
     * @param uri Identifier of the incident report.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public void deleteIncidentReports(Uri uri) {
        throw new RuntimeException("implement me");
    }

    private void reportIncidentInternal(IncidentReportArgs args) {
        try {
            final IIncidentManager service = getIIncidentManagerLocked();
+12 −14
Original line number Diff line number Diff line
@@ -32,19 +32,16 @@ import java.util.ArrayList;
@TestApi
public final class IncidentReportArgs implements Parcelable {

    private static final int DEST_EXPLICIT = 100;
    private static final int DEST_AUTO = 200;

    private final IntArray mSections = new IntArray();
    private final ArrayList<byte[]> mHeaders = new ArrayList<byte[]>();
    private boolean mAll;
    private int mDest;
    private int mPrivacyPolicy;

    /**
     * Construct an incident report args with no fields.
     */
    public IncidentReportArgs() {
        mDest = DEST_AUTO;
        mPrivacyPolicy = IncidentManager.PRIVACY_POLICY_AUTO;
    }

    /**
@@ -75,7 +72,7 @@ public final class IncidentReportArgs implements Parcelable {
            out.writeByteArray(mHeaders.get(i));
        }

        out.writeInt(mDest);
        out.writeInt(mPrivacyPolicy);
    }

    public void readFromParcel(Parcel in) {
@@ -93,7 +90,7 @@ public final class IncidentReportArgs implements Parcelable {
            mHeaders.add(in.createByteArray());
        }

        mDest = in.readInt();
        mPrivacyPolicy = in.readInt();
    }

    public static final Parcelable.Creator<IncidentReportArgs> CREATOR
@@ -128,7 +125,7 @@ public final class IncidentReportArgs implements Parcelable {
        sb.append(", ");
        sb.append(mHeaders.size());
        sb.append(" headers), ");
        sb.append("Dest enum value: ").append(mDest);
        sb.append("privacy: ").append(mPrivacyPolicy);
        return sb.toString();
    }

@@ -145,14 +142,15 @@ public final class IncidentReportArgs implements Parcelable {
    /**
     * Set this incident report privacy policy spec.
     */
    public void setPrivacyPolicy(int dest) {
        switch (dest) {
            case DEST_EXPLICIT:
            case DEST_AUTO:
                mDest = dest;
    public void setPrivacyPolicy(int privacyPolicy) {
        switch (privacyPolicy) {
            case IncidentManager.PRIVACY_POLICY_LOCAL:
            case IncidentManager.PRIVACY_POLICY_EXPLICIT:
            case IncidentManager.PRIVACY_POLICY_AUTO:
                mPrivacyPolicy = privacyPolicy;
                break;
            default:
                mDest = DEST_AUTO;
                mPrivacyPolicy = IncidentManager.PRIVACY_POLICY_AUTO;
        }
    }