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

Commit 8daca758 authored by Joe Onorato's avatar Joe Onorato
Browse files

Skeleton API for IncidentManager to retrieve incident reports.

Bug: 123543706
Test: make
Change-Id: I0a41d476703cb0c1c728c6de1bf290162129e699
parent 917955a4
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1298,6 +1298,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";
@@ -5336,11 +5337,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 {
@@ -5349,6 +5356,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
@@ -1284,11 +1284,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 {
@@ -1297,6 +1303,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;
        }
    }