1import {defer} from '../base/deferred';
2
3enum WebContentScriptMessageType {
4  UNKNOWN,
5  CONVERT_OBJECT_URL,
6  CONVERT_OBJECT_URL_RESPONSE,
7}
8
9const ANDROID_BUG_TOOL_EXTENSION_ID = 'mbbaofdfoekifkfpgehgffcpagbbjkmj';
10
11interface Attachment {
12  name: string;
13  objectUrl: string;
14  restrictionSeverity: number;
15}
16
17interface ConvertObjectUrlResponse {
18  action: WebContentScriptMessageType.CONVERT_OBJECT_URL_RESPONSE;
19  attachments: Attachment[];
20  issueAccessLevel: string;
21  issueId: string;
22  issueTitle: string;
23}
24
25export interface TraceFromBuganizer {
26  issueId: string;
27  issueTitle: string;
28  file: File;
29}
30
31export function loadAndroidBugToolInfo(): Promise<TraceFromBuganizer> {
32  const deferred = defer<TraceFromBuganizer>();
33
34  // Request to convert the blob object url "blob:chrome-extension://xxx"
35  // the chrome extension has to a web downloadable url "blob:http://xxx".
36  chrome.runtime.sendMessage(
37      ANDROID_BUG_TOOL_EXTENSION_ID,
38      {action: WebContentScriptMessageType.CONVERT_OBJECT_URL},
39      async (response: ConvertObjectUrlResponse) => {
40        switch (response.action) {
41          case WebContentScriptMessageType.CONVERT_OBJECT_URL_RESPONSE:
42          if (response.attachments?.length > 0) {
43            const filesBlobPromises =
44                response.attachments.map(async attachment => {
45                  const fileQueryResponse = await fetch(attachment.objectUrl);
46                  const blob = await fileQueryResponse.blob();
47                  // Note: The blob's media type is always set to "image/png".
48                  // Clone blob to clear media type.
49                  return new File([blob], attachment.name);
50                });
51            const files = await Promise.all(filesBlobPromises);
52            deferred.resolve({
53              issueId: response.issueId,
54              issueTitle: response.issueTitle,
55              file: files[0],
56            });
57          } else {
58            throw new Error('Got no attachements from extension');
59          }
60          break;
61          default:
62            throw new Error(`Received unhandled response code (${
63                response.action}) from extension.`);
64        }
65      });
66  return deferred;
67}
68