1/* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {defer} from '../base/deferred'; 18 19enum WebContentScriptMessageType { 20 UNKNOWN, 21 CONVERT_OBJECT_URL, 22 CONVERT_OBJECT_URL_RESPONSE, 23} 24 25const ANDROID_BUG_TOOL_EXTENSION_ID = 'mbbaofdfoekifkfpgehgffcpagbbjkmj'; 26 27interface Attachment { 28 name: string; 29 objectUrl: string; 30 restrictionSeverity: number; 31} 32 33interface ConvertObjectUrlResponse { 34 action: WebContentScriptMessageType.CONVERT_OBJECT_URL_RESPONSE; 35 attachments: Attachment[]; 36 issueAccessLevel: string; 37 issueId: string; 38 issueTitle: string; 39} 40 41export interface TraceFromBuganizer { 42 issueId: string; 43 issueTitle: string; 44 file: File; 45} 46 47export function loadAndroidBugToolInfo(): Promise<TraceFromBuganizer> { 48 const deferred = defer<TraceFromBuganizer>(); 49 50 // Request to convert the blob object url "blob:chrome-extension://xxx" 51 // the chrome extension has to a web downloadable url "blob:http://xxx". 52 chrome.runtime.sendMessage( 53 ANDROID_BUG_TOOL_EXTENSION_ID, 54 {action: WebContentScriptMessageType.CONVERT_OBJECT_URL}, 55 async (response: ConvertObjectUrlResponse) => { 56 switch (response.action) { 57 case WebContentScriptMessageType.CONVERT_OBJECT_URL_RESPONSE: 58 if (response.attachments?.length > 0) { 59 const filesBlobPromises = 60 response.attachments.map(async (attachment) => { 61 const fileQueryResponse = await fetch(attachment.objectUrl); 62 const blob = await fileQueryResponse.blob(); 63 // Note: The blob's media type is always set to "image/png". 64 // Clone blob to clear media type. 65 return new File([blob], attachment.name); 66 }); 67 const files = await Promise.all(filesBlobPromises); 68 deferred.resolve({ 69 issueId: response.issueId, 70 issueTitle: response.issueTitle, 71 file: files[0], 72 }); 73 } else { 74 throw new Error('Got no attachements from extension'); 75 } 76 break; 77 default: 78 throw new Error(`Received unhandled response code (${ 79 response.action}) from extension.`); 80 } 81 }); 82 return deferred; 83} 84