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 = response.attachments.map( 60 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 ); 68 const files = await Promise.all(filesBlobPromises); 69 deferred.resolve({ 70 issueId: response.issueId, 71 issueTitle: response.issueTitle, 72 file: files[0], 73 }); 74 } else { 75 throw new Error('Got no attachements from extension'); 76 } 77 break; 78 default: 79 throw new Error( 80 `Received unhandled response code (${response.action}) from extension.`, 81 ); 82 } 83 }, 84 ); 85 return deferred; 86} 87