diff options
author | Kean Mariotti <keanmariotti@google.com> | 2023-05-30 20:11:06 +0000 |
---|---|---|
committer | Kean Mariotti <keanmariotti@google.com> | 2023-06-02 12:08:00 +0000 |
commit | bc966c455c4926e8d835c09a8f4240e049fce048 (patch) | |
tree | 26f2328953ce1d3065b866991fd931732aa5e326 | |
parent | 35e2e69f95eb8ad75736ea0c27242ec7e46d0318 (diff) | |
download | development-bc966c455c4926e8d835c09a8f4240e049fce048.tar.gz |
Optimize bugreport loading
Fix: b/269342535
Test: npm run test:all
Change-Id: I89e03fff08fe1c7e7169a6eeb08efeda04d098d0
-rw-r--r-- | tools/winscope/src/abt_chrome_extension/abt_chrome_extension_protocol.ts | 7 | ||||
-rw-r--r-- | tools/winscope/src/app/mediator.ts | 4 | ||||
-rw-r--r-- | tools/winscope/src/app/trace_pipeline.ts | 31 | ||||
-rw-r--r-- | tools/winscope/src/app/trace_pipeline_test.ts | 68 | ||||
-rw-r--r-- | tools/winscope/src/common/file_utils.ts | 3 | ||||
-rw-r--r-- | tools/winscope/src/common/time_utils.ts | 1 | ||||
-rw-r--r-- | tools/winscope/src/test/common/file_impl.ts | 6 | ||||
-rw-r--r-- | tools/winscope/src/test/common/utils.ts | 9 | ||||
-rw-r--r-- | tools/winscope/src/test/fixtures/bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt | 6 | ||||
-rw-r--r-- | tools/winscope/src/test/fixtures/bugreports/bugreport_stripped.zip | bin | 1035771 -> 1035794 bytes | |||
-rw-r--r-- | tools/winscope/src/test/fixtures/bugreports/main_entry.txt | 1 | ||||
-rw-r--r-- | tools/winscope/src/trace/trace_file.ts | 4 |
12 files changed, 127 insertions, 13 deletions
diff --git a/tools/winscope/src/abt_chrome_extension/abt_chrome_extension_protocol.ts b/tools/winscope/src/abt_chrome_extension/abt_chrome_extension_protocol.ts index a8aba832f..787cc2eab 100644 --- a/tools/winscope/src/abt_chrome_extension/abt_chrome_extension_protocol.ts +++ b/tools/winscope/src/abt_chrome_extension/abt_chrome_extension_protocol.ts @@ -26,14 +26,15 @@ export class AbtChromeExtensionProtocol implements BuganizerAttachmentsDownloadE static readonly ABT_EXTENSION_ID = 'mbbaofdfoekifkfpgehgffcpagbbjkmj'; private onAttachmentsDownloadStart: OnBuganizerAttachmentsDownloadStart = FunctionUtils.DO_NOTHING; - private onttachmentsDownloaded: OnBuganizerAttachmentsDownloaded = FunctionUtils.DO_NOTHING_ASYNC; + private onAttachmentsDownloaded: OnBuganizerAttachmentsDownloaded = + FunctionUtils.DO_NOTHING_ASYNC; setOnBuganizerAttachmentsDownloadStart(callback: OnBuganizerAttachmentsDownloadStart) { this.onAttachmentsDownloadStart = callback; } setOnBuganizerAttachmentsDownloaded(callback: OnBuganizerAttachmentsDownloaded) { - this.onttachmentsDownloaded = callback; + this.onAttachmentsDownloaded = callback; } run() { @@ -83,7 +84,7 @@ export class AbtChromeExtensionProtocol implements BuganizerAttachmentsDownloadE }); const files = await Promise.all(filesBlobPromises); - await this.onttachmentsDownloaded(files); + await this.onAttachmentsDownloaded(files); } private isOpenBuganizerResponseMessage( diff --git a/tools/winscope/src/app/mediator.ts b/tools/winscope/src/app/mediator.ts index 3544a2cd6..60ee7eab8 100644 --- a/tools/winscope/src/app/mediator.ts +++ b/tools/winscope/src/app/mediator.ts @@ -83,7 +83,7 @@ export class Mediator { } ); - this.crossToolProtocol.setOnTimestampReceived(async (timestamp: Timestamp) => { + this.crossToolProtocol.setOnTimestampReceived((timestamp: Timestamp) => { this.onRemoteTimestampReceived(timestamp); }); @@ -203,7 +203,7 @@ export class Mediator { private async processRemoteFilesReceived(files: File[]) { this.resetAppToInitialState(); - this.processFiles(files); + await this.processFiles(files); } private async processFiles(files: File[]) { diff --git a/tools/winscope/src/app/trace_pipeline.ts b/tools/winscope/src/app/trace_pipeline.ts index 8ab16b70f..cad4c6120 100644 --- a/tools/winscope/src/app/trace_pipeline.ts +++ b/tools/winscope/src/app/trace_pipeline.ts @@ -37,6 +37,7 @@ class TracePipeline { traceFiles: TraceFile[], onLoadProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING ): Promise<ParserError[]> { + traceFiles = await this.filterBugreportFilesIfNeeded(traceFiles); const [parsers, parserErrors] = await this.parserFactory.createParsers( traceFiles, onLoadProgressUpdate @@ -111,6 +112,36 @@ class TracePipeline { this.files = new Map<TraceType, TraceFile>(); } + private async filterBugreportFilesIfNeeded(files: TraceFile[]): Promise<TraceFile[]> { + const bugreportMainEntry = files.find((file) => file.file.name === 'main_entry.txt'); + if (!bugreportMainEntry) { + return files; + } + + const bugreportName = (await bugreportMainEntry.file.text()).trim(); + const isBugreport = files.find((file) => file.file.name === bugreportName) !== undefined; + if (!isBugreport) { + return files; + } + + const BUGREPORT_TRACE_DIRS = ['FS/data/misc/wmtrace/', 'FS/data/misc/perfetto-traces/']; + const isFileWithinBugreportTraceDir = (file: TraceFile) => { + for (const traceDir of BUGREPORT_TRACE_DIRS) { + if (file.file.name.startsWith(traceDir)) { + return true; + } + } + return false; + }; + + const fileBelongsToBugreport = (file: TraceFile) => + file.parentArchive === bugreportMainEntry.parentArchive; + + return files.filter((file) => { + return isFileWithinBugreportTraceDir(file) || !fileBelongsToBugreport(file); + }); + } + private getCommonTimestampType(): TimestampType { if (this.commonTimestampType !== undefined) { return this.commonTimestampType; diff --git a/tools/winscope/src/app/trace_pipeline_test.ts b/tools/winscope/src/app/trace_pipeline_test.ts index 20e01a07c..46c670177 100644 --- a/tools/winscope/src/app/trace_pipeline_test.ts +++ b/tools/winscope/src/app/trace_pipeline_test.ts @@ -39,6 +39,74 @@ describe('TracePipeline', () => { expect(traceEntries.get(TraceType.SURFACE_FLINGER)?.length).toBeGreaterThan(0); }); + it('can load bugreport and ignores non-trace dirs', async () => { + expect(tracePipeline.getLoadedTraces().length).toEqual(0); + + // Could be any file, we just need an instance of File to be used as a fake bugreport archive + const bugreportArchive = await UnitTestUtils.getFixtureFile( + 'bugreports/bugreport_stripped.zip' + ); + + const bugreportFiles = [ + new TraceFile( + await UnitTestUtils.getFixtureFile('bugreports/main_entry.txt', 'main_entry.txt'), + bugreportArchive + ), + new TraceFile( + await UnitTestUtils.getFixtureFile( + 'bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt', + 'bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt' + ), + bugreportArchive + ), + new TraceFile( + await UnitTestUtils.getFixtureFile( + 'traces/elapsed_and_real_timestamp/SurfaceFlinger.pb', + 'FS/data/misc/wmtrace/surface_flinger.bp' + ), + bugreportArchive + ), + new TraceFile( + await UnitTestUtils.getFixtureFile( + 'traces/elapsed_and_real_timestamp/Transactions.pb', + 'FS/data/misc/wmtrace/transactions.bp' + ), + bugreportArchive + ), + new TraceFile( + await UnitTestUtils.getFixtureFile( + 'traces/elapsed_and_real_timestamp/WindowManager.pb', + 'FS/data/misc/ignored-dir/window_manager.bp' + ), + bugreportArchive + ), + ]; + + // Corner case: + // A plain trace file is loaded along the bugreport -> trace file must not be ignored + // + // Note: + // The even weirder corner case where two bugreports are loaded at the same time is + // currently not properly handled. + const plainTraceFile = new TraceFile( + await UnitTestUtils.getFixtureFile( + 'traces/elapsed_and_real_timestamp/InputMethodClients.pb', + 'would-be-ignored-if-was-part-of-bugreport/input_method_clients.pb' + ) + ); + + const mergedFiles = bugreportFiles.concat([plainTraceFile]); + const errors = await tracePipeline.loadTraceFiles(mergedFiles); + expect(errors.length).toEqual(0); + tracePipeline.buildTraces(); + const traces = tracePipeline.getTraces(); + + expect(traces.getTrace(TraceType.SURFACE_FLINGER)).toBeDefined(); + expect(traces.getTrace(TraceType.TRANSACTIONS)).toBeDefined(); + expect(traces.getTrace(TraceType.WINDOW_MANAGER)).toBeUndefined(); // ignored + expect(traces.getTrace(TraceType.INPUT_METHOD_CLIENTS)).toBeDefined(); + }); + it('is robust to invalid trace files', async () => { const invalidTraceFiles = [ new TraceFile(await UnitTestUtils.getFixtureFile('winscope_homepage.png')), diff --git a/tools/winscope/src/common/file_utils.ts b/tools/winscope/src/common/file_utils.ts index 447e043ad..ac2b688a7 100644 --- a/tools/winscope/src/common/file_utils.ts +++ b/tools/winscope/src/common/file_utils.ts @@ -61,9 +61,8 @@ class FileUtils { // Ignore directories continue; } else { - const name = FileUtils.removeDirFromFileName(filename); const fileBlob = await file.async('blob'); - const unzippedFile = new File([fileBlob], name); + const unzippedFile = new File([fileBlob], filename); unzippedFiles.push(unzippedFile); } diff --git a/tools/winscope/src/common/time_utils.ts b/tools/winscope/src/common/time_utils.ts index 876c3c1e8..42d6cf109 100644 --- a/tools/winscope/src/common/time_utils.ts +++ b/tools/winscope/src/common/time_utils.ts @@ -128,7 +128,6 @@ export class TimeUtils { } static formattedKotlinTimestamp(time: any, timestampType: TimestampType): string { - console.log('time', time); if (timestampType === TimestampType.ELAPSED) { return TimeUtils.format(new ElapsedTimestamp(BigInt(time.elapsedNanos.toString()))); } diff --git a/tools/winscope/src/test/common/file_impl.ts b/tools/winscope/src/test/common/file_impl.ts index 8ad842bcf..315bbe1b4 100644 --- a/tools/winscope/src/test/common/file_impl.ts +++ b/tools/winscope/src/test/common/file_impl.ts @@ -46,7 +46,11 @@ class FileImpl { } text(): Promise<string> { - throw new Error('Not implemented!'); + const utf8Decoder = new TextDecoder(); + const text = utf8Decoder.decode(this.buffer); + return new Promise<string>((resolve) => { + resolve(text); + }); } } diff --git a/tools/winscope/src/test/common/utils.ts b/tools/winscope/src/test/common/utils.ts index d7f1e8853..8c81a6394 100644 --- a/tools/winscope/src/test/common/utils.ts +++ b/tools/winscope/src/test/common/utils.ts @@ -18,9 +18,12 @@ import * as path from 'path'; import {FileImpl} from './file_impl'; class CommonTestUtils { - static async getFixtureFile(filename: string): Promise<File> { - const buffer = CommonTestUtils.loadFixture(filename); - return new FileImpl(buffer, filename) as unknown as File; + static async getFixtureFile( + srcFilename: string, + dstFilename: string = srcFilename + ): Promise<File> { + const buffer = CommonTestUtils.loadFixture(srcFilename); + return new FileImpl(buffer, dstFilename) as unknown as File; } static loadFixture(filename: string): ArrayBuffer { diff --git a/tools/winscope/src/test/fixtures/bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt b/tools/winscope/src/test/fixtures/bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt new file mode 100644 index 000000000..c02add504 --- /dev/null +++ b/tools/winscope/src/test/fixtures/bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt @@ -0,0 +1,6 @@ +======================================================== +== dumpstate: 2023-05-30 14:33:48 +======================================================== + +# ORIGINAL CONTENTS REMOVED TO AVOID INFORMATION LEAKS + diff --git a/tools/winscope/src/test/fixtures/bugreports/bugreport_stripped.zip b/tools/winscope/src/test/fixtures/bugreports/bugreport_stripped.zip Binary files differindex 36a2e7300..c91a59532 100644 --- a/tools/winscope/src/test/fixtures/bugreports/bugreport_stripped.zip +++ b/tools/winscope/src/test/fixtures/bugreports/bugreport_stripped.zip diff --git a/tools/winscope/src/test/fixtures/bugreports/main_entry.txt b/tools/winscope/src/test/fixtures/bugreports/main_entry.txt new file mode 100644 index 000000000..33992053a --- /dev/null +++ b/tools/winscope/src/test/fixtures/bugreports/main_entry.txt @@ -0,0 +1 @@ +bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt diff --git a/tools/winscope/src/trace/trace_file.ts b/tools/winscope/src/trace/trace_file.ts index 4f2f6da16..0ae7a9801 100644 --- a/tools/winscope/src/trace/trace_file.ts +++ b/tools/winscope/src/trace/trace_file.ts @@ -14,11 +14,13 @@ * limitations under the License. */ +import {FileUtils} from 'common/file_utils'; + export class TraceFile { constructor(public file: File, public parentArchive?: File) {} getDescriptor(): string { - let descriptor = this.file.name; + let descriptor = FileUtils.removeDirFromFileName(this.file.name); if (this.parentArchive?.name !== undefined) { descriptor += ` (${this.parentArchive?.name})`; } |