Merge "Set up to migrate requestBugreport flavors to use bugreport API"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 58e1d47..8c0108d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -352,10 +352,10 @@
 
         private final BugreportInfo mInfo;
 
-        BugreportCallbackImpl(String name) {
+        BugreportCallbackImpl(String name, @Nullable String title, @Nullable String description) {
             // pid not used in this workflow, so setting default = 0
             mInfo = new BugreportInfo(mContext, 0 /* pid */, name,
-                    100 /* max progress*/);
+                    100 /* max progress*/, title, description);
         }
 
         @Override
@@ -578,6 +578,8 @@
         }
         int bugreportType = intent.getIntExtra(EXTRA_BUGREPORT_TYPE,
                 BugreportParams.BUGREPORT_MODE_INTERACTIVE);
+        String shareTitle = intent.getStringExtra(EXTRA_TITLE);
+        String shareDescription = intent.getStringExtra(EXTRA_DESCRIPTION);
 
         ParcelFileDescriptor screenshotFd = createReadWriteFile(BUGREPORT_DIR,
                 bugreportName + ".png");
@@ -595,7 +597,8 @@
                 + " bugreport file fd: " + bugreportFd
                 + " screenshot file fd: " + screenshotFd);
 
-        BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl(bugreportName);
+        BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl(bugreportName,
+                shareTitle, shareDescription);
         try {
             mBugreportManager.startBugreport(bugreportFd, screenshotFd,
                     new BugreportParams(bugreportType), executor, bugreportCallback);
@@ -982,7 +985,10 @@
             }
             screenshotFile = null;
         }
-        onBugreportFinished(id, bugreportFile, screenshotFile, info.title, info.description, max);
+        // TODO: Since we are passing id to the function, it should be able to find the info linked
+        // to the id and therefore use the value of shareTitle and shareDescription.
+        onBugreportFinished(id, bugreportFile, screenshotFile, info.shareTitle,
+                info.shareDescription, max);
     }
 
 
@@ -1844,6 +1850,14 @@
         String title;
 
         /**
+         * One-line summary of the bug; when set, will be used as the subject of the
+         * {@link Intent#ACTION_SEND_MULTIPLE} intent. This is the predefined title which is
+         * set initially when the request to take a bugreport is made. This overrides any changes
+         * in the title that the user makes after the bugreport starts.
+         */
+        String shareTitle;
+
+        /**
          * User-provided, detailed description of the bugreport; when set, will be added to the body
          * of the {@link Intent#ACTION_SEND_MULTIPLE} intent.
          */
@@ -1906,7 +1920,9 @@
         int screenshotCounter;
 
         /**
-         * Descriptive text that will be shown to the user in the notification message.
+         * Descriptive text that will be shown to the user in the notification message. This is the
+         * predefined description which is set initially when the request to take a bugreport is
+         * made.
          */
         String shareDescription;
 
@@ -1914,18 +1930,21 @@
          * Constructor for tracked bugreports - typically called upon receiving BUGREPORT_STARTED.
          */
         BugreportInfo(Context context, int id, int pid, String name, int max) {
-            this(context, pid, name, max);
+            this(context, pid, name, max, null, null);
             this.id = id;
         }
 
         /**
          * Constructor for tracked bugreports - typically called upon receiving BUGREPORT_REQUESTED.
          */
-        BugreportInfo(Context context, int pid, String name, int max) {
+        BugreportInfo(Context context, int pid, String name, int max, @Nullable String shareTitle,
+                @Nullable String shareDescription) {
             this.context = context;
             this.pid = pid;
             this.name = name;
             this.max = this.realMax = max;
+            this.shareTitle = shareTitle == null ? "" : shareTitle;
+            this.shareDescription = shareDescription == null ? "" : shareDescription;
         }
 
         /**
@@ -2019,6 +2038,7 @@
                 .append("\n\taddingDetailsToZip: ").append(addingDetailsToZip)
                 .append(" addedDetailsToZip: ").append(addedDetailsToZip)
                 .append("\n\tshareDescription: ").append(shareDescription)
+                .append("\n\tshareTitle: ").append(shareTitle)
                 .toString();
         }
 
@@ -2046,6 +2066,7 @@
             finished = in.readInt() == 1;
             screenshotCounter = in.readInt();
             shareDescription = in.readString();
+            shareTitle = in.readString();
         }
 
         @Override
@@ -2071,6 +2092,7 @@
             dest.writeInt(finished ? 1 : 0);
             dest.writeInt(screenshotCounter);
             dest.writeString(shareDescription);
+            dest.writeString(shareTitle);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d759be2..2292889 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -282,6 +282,7 @@
 import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.EventLog;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Pair;
 import android.util.PrintWriterPrinter;
@@ -378,7 +379,7 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -437,6 +438,10 @@
     // need not be the case.
     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
 
+    private static final String INTENT_BUGREPORT_REQUESTED =
+            "com.android.internal.intent.action.BUGREPORT_REQUESTED";
+    private static final String SHELL_APP_PACKAGE = "com.android.shell";
+
     /** Control over CPU and battery monitoring */
     // write battery stats every 30 minutes.
     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
@@ -555,6 +560,10 @@
     OomAdjuster mOomAdjuster;
     final LowMemDetector mLowMemDetector;
 
+    static final String EXTRA_TITLE = "android.intent.extra.TITLE";
+    static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
+    static final String EXTRA_BUGREPORT_TYPE = "android.intent.extra.BUGREPORT_TYPE";
+
     /** All system services */
     SystemServiceManager mSystemServiceManager;
 
@@ -8201,6 +8210,53 @@
     @Deprecated
     @Override
     public void requestBugReport(int bugreportType) {
+        requestBugReportWithDescription(null, null, bugreportType);
+    }
+
+    /**
+     * @deprecated This method is only used by a few internal components and it will soon be
+     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
+     * No new code should be calling it.
+     */
+    @Deprecated
+    public void requestBugReportWithDescription(@Nullable String shareTitle,
+            @Nullable String shareDescription, int bugreportType) {
+        if (!TextUtils.isEmpty(shareTitle)) {
+            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
+                String errorStr = "shareTitle should be less than " +
+                        MAX_BUGREPORT_TITLE_SIZE + " characters";
+                throw new IllegalArgumentException(errorStr);
+            }
+            if (!TextUtils.isEmpty(shareDescription)) {
+                int length = shareDescription.getBytes(StandardCharsets.UTF_8).length;
+                if (length > SystemProperties.PROP_VALUE_MAX) {
+                    String errorStr = "shareTitle should be less than " +
+                            SystemProperties.PROP_VALUE_MAX + " bytes";
+                    throw new IllegalArgumentException(errorStr);
+                } else {
+                    SystemProperties.set("dumpstate.options.description", shareDescription);
+                }
+            }
+            SystemProperties.set("dumpstate.options.title", shareTitle);
+            Slog.d(TAG, "Bugreport notification title " + shareTitle
+                    + " description " + shareDescription);
+        }
+        final boolean useApi = FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.USE_BUGREPORT_API);
+
+        if (useApi) {
+            // Create intent to trigger Bugreport API via Shell
+            Intent triggerShellBugreport = new Intent();
+            triggerShellBugreport.setAction(INTENT_BUGREPORT_REQUESTED);
+            triggerShellBugreport.setPackage(SHELL_APP_PACKAGE);
+            triggerShellBugreport.putExtra(EXTRA_BUGREPORT_TYPE, bugreportType);
+            if (shareTitle != null) {
+                triggerShellBugreport.putExtra(EXTRA_TITLE, shareTitle);
+            }
+            if (shareDescription != null) {
+                triggerShellBugreport.putExtra(EXTRA_DESCRIPTION, shareDescription);
+            }
+        }
         String extraOptions = null;
         switch (bugreportType) {
             case ActivityManager.BUGREPORT_OPTION_FULL:
@@ -8242,45 +8298,6 @@
      * No new code should be calling it.
      */
     @Deprecated
-    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
-                                                 int bugreportType) {
-        if (!TextUtils.isEmpty(shareTitle)) {
-            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
-                String errorStr = "shareTitle should be less than " +
-                        MAX_BUGREPORT_TITLE_SIZE + " characters";
-                throw new IllegalArgumentException(errorStr);
-            } else {
-                if (!TextUtils.isEmpty(shareDescription)) {
-                    int length;
-                    try {
-                        length = shareDescription.getBytes("UTF-8").length;
-                    } catch (UnsupportedEncodingException e) {
-                        String errorStr = "shareDescription: UnsupportedEncodingException";
-                        throw new IllegalArgumentException(errorStr);
-                    }
-                    if (length > SystemProperties.PROP_VALUE_MAX) {
-                        String errorStr = "shareTitle should be less than " +
-                                SystemProperties.PROP_VALUE_MAX + " bytes";
-                        throw new IllegalArgumentException(errorStr);
-                    } else {
-                        SystemProperties.set("dumpstate.options.description", shareDescription);
-                    }
-                }
-                SystemProperties.set("dumpstate.options.title", shareTitle);
-            }
-        }
-
-        Slog.d(TAG, "Bugreport notification title " + shareTitle
-                + " description " + shareDescription);
-        requestBugReport(bugreportType);
-    }
-
-    /**
-     * @deprecated This method is only used by a few internal components and it will soon be
-     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
-     * No new code should be calling it.
-     */
-    @Deprecated
     @Override
     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
         requestBugReportWithDescription(shareTitle, shareDescription,