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 {assertDefined} from 'common/assert_utils'; 18import {Store} from 'common/store'; 19import {Trace} from 'trace/trace'; 20import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 21import { 22 AbstractLogViewerPresenter, 23 NotifyLogViewCallbackType, 24} from 'viewers/common/abstract_log_viewer_presenter'; 25import {LogSelectFilter, LogTextFilter} from 'viewers/common/log_filters'; 26import {LogPresenter} from 'viewers/common/log_presenter'; 27import {TextFilter} from 'viewers/common/text_filter'; 28import {LogEntry, LogField, LogHeader} from 'viewers/common/ui_data_log'; 29import {ProtologEntry, UiData} from './ui_data'; 30 31export class Presenter extends AbstractLogViewerPresenter< 32 UiData, 33 PropertyTreeNode 34> { 35 private static readonly COLUMNS = { 36 logLevel: { 37 name: 'Log Level', 38 cssClass: 'log-level', 39 }, 40 tag: { 41 name: 'Tag', 42 cssClass: 'tag', 43 }, 44 sourceFile: { 45 name: 'Source files', 46 cssClass: 'source-file', 47 }, 48 text: { 49 name: 'Search text', 50 cssClass: 'text', 51 }, 52 }; 53 protected override logPresenter = new LogPresenter<LogEntry>(); 54 55 constructor( 56 trace: Trace<PropertyTreeNode>, 57 notifyViewCallback: NotifyLogViewCallbackType<UiData>, 58 private storage: Store, 59 ) { 60 super(trace, notifyViewCallback, UiData.createEmpty()); 61 } 62 63 protected override makeHeaders(): LogHeader[] { 64 return [ 65 new LogHeader(Presenter.COLUMNS.logLevel, new LogSelectFilter([])), 66 new LogHeader( 67 Presenter.COLUMNS.tag, 68 new LogSelectFilter([], false, '150'), 69 ), 70 new LogHeader( 71 Presenter.COLUMNS.sourceFile, 72 new LogSelectFilter([], false, '300'), 73 ), 74 new LogHeader( 75 Presenter.COLUMNS.text, 76 new LogTextFilter(new TextFilter()), 77 ), 78 ]; 79 } 80 81 protected override async makeUiDataEntries(): Promise<ProtologEntry[]> { 82 const messages: ProtologEntry[] = []; 83 84 for ( 85 let traceIndex = 0; 86 traceIndex < this.trace.lengthEntries; 87 ++traceIndex 88 ) { 89 const entry = assertDefined(this.trace.getEntry(traceIndex)); 90 const messageNode = await entry.getValue(); 91 const fields: LogField[] = [ 92 { 93 spec: Presenter.COLUMNS.logLevel, 94 value: assertDefined( 95 messageNode.getChildByName('level'), 96 ).formattedValue(), 97 }, 98 { 99 spec: Presenter.COLUMNS.tag, 100 value: assertDefined( 101 messageNode.getChildByName('tag'), 102 ).formattedValue(), 103 }, 104 { 105 spec: Presenter.COLUMNS.sourceFile, 106 value: assertDefined( 107 messageNode.getChildByName('at'), 108 ).formattedValue(), 109 }, 110 { 111 spec: Presenter.COLUMNS.text, 112 value: assertDefined( 113 messageNode.getChildByName('text'), 114 ).formattedValue(), 115 }, 116 ]; 117 messages.push(new ProtologEntry(entry, fields)); 118 } 119 120 return messages; 121 } 122 123 protected override updateFiltersInHeaders( 124 headers: LogHeader[], 125 allEntries: ProtologEntry[], 126 ) { 127 for (const header of headers) { 128 if (header.filter instanceof LogSelectFilter) { 129 assertDefined(header.filter).options = this.getUniqueMessageValues( 130 allEntries, 131 (entry: ProtologEntry) => 132 assertDefined( 133 entry.fields.find((f) => f.spec === header.spec), 134 ).value.toString(), 135 ); 136 } 137 } 138 } 139 140 private getUniqueMessageValues( 141 allMessages: ProtologEntry[], 142 getValue: (message: ProtologEntry) => string, 143 ): string[] { 144 const uniqueValues = new Set<string>(); 145 allMessages.forEach((message) => { 146 uniqueValues.add(getValue(message)); 147 }); 148 const result = [...uniqueValues]; 149 result.sort(); 150 return result; 151 } 152} 153