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 */ 16import {Component, EventEmitter, Input, Output} from '@angular/core'; 17import {assertDefined} from 'common/assert_utils'; 18import { 19 EnableConfiguration, 20 SelectionConfiguration, 21 TraceConfiguration, 22 TraceConfigurationMap, 23} from 'trace_collection/trace_collection_utils'; 24 25@Component({ 26 selector: 'trace-config', 27 template: ` 28 <h3 class="mat-subheading-2">Trace targets</h3> 29 30 <div class="checkboxes"> 31 <mat-checkbox 32 *ngFor="let traceKey of objectKeys(this.traceConfig)" 33 color="primary" 34 class="trace-checkbox" 35 [checked]="this.traceConfig[traceKey].run" 36 (change)="changeRunTrace($event.checked, this.traceConfig[traceKey])" 37 >{{ this.traceConfig[traceKey].name }}</mat-checkbox 38 > 39 </div> 40 41 <ng-container *ngFor="let traceKey of advancedConfigTraces()"> 42 <mat-divider></mat-divider> 43 44 <h3 class="mat-subheading-2">{{ this.traceConfig[traceKey].name }} configuration</h3> 45 46 <div 47 *ngIf="this.traceConfig[traceKey].config?.enableConfigs.length > 0" 48 class="enable-config-opt"> 49 <mat-checkbox 50 *ngFor="let enableConfig of traceEnableConfigs(this.traceConfig[traceKey])" 51 color="primary" 52 class="enable-config" 53 [disabled]="!this.traceConfig[traceKey].run" 54 [(ngModel)]="enableConfig.enabled" 55 >{{ enableConfig.name }}</mat-checkbox 56 > 57 </div> 58 59 <div 60 *ngIf="this.traceConfig[traceKey].config?.selectionConfigs.length > 0" 61 class="selection-config-opt"> 62 <mat-form-field 63 *ngFor="let selectionConfig of traceSelectionConfigs(this.traceConfig[traceKey])" 64 class="config-selection" 65 appearance="fill"> 66 <mat-label>{{ selectionConfig.name }}</mat-label> 67 68 <mat-select 69 class="selected-value" 70 [(value)]="selectionConfig.value" 71 [disabled]="!this.traceConfig[traceKey].run"> 72 <mat-option *ngFor="let option of selectionConfig.options" value="{{ option }}">{{ 73 option 74 }}</mat-option> 75 </mat-select> 76 </mat-form-field> 77 </div> 78 </ng-container> 79 `, 80 styles: [ 81 ` 82 .checkboxes { 83 display: grid; 84 grid-template-columns: repeat(3, 1fr); 85 column-gap: 10px; 86 } 87 .enable-config-opt, 88 .selection-config-opt { 89 display: flex; 90 flex-direction: row; 91 flex-wrap: wrap; 92 gap: 10px; 93 } 94 `, 95 ], 96}) 97export class TraceConfigComponent { 98 objectKeys = Object.keys; 99 100 @Input() traceConfig: TraceConfigurationMap | undefined; 101 @Output() readonly traceConfigChange = 102 new EventEmitter<TraceConfigurationMap>(); 103 104 advancedConfigTraces() { 105 const advancedConfigs: string[] = []; 106 Object.keys(assertDefined(this.traceConfig)).forEach((traceKey: string) => { 107 if (assertDefined(this.traceConfig)[traceKey].config) { 108 advancedConfigs.push(traceKey); 109 } 110 }); 111 return advancedConfigs; 112 } 113 114 traceEnableConfigs(trace: TraceConfiguration): EnableConfiguration[] { 115 if (trace.config) { 116 return trace.config.enableConfigs; 117 } else { 118 return []; 119 } 120 } 121 122 traceSelectionConfigs(trace: TraceConfiguration): SelectionConfiguration[] { 123 if (trace.config) { 124 return trace.config.selectionConfigs; 125 } else { 126 return []; 127 } 128 } 129 130 someTraces(trace: TraceConfiguration): boolean { 131 return ( 132 !trace.run && 133 this.traceEnableConfigs(trace).filter((trace) => trace.enabled).length > 0 134 ); 135 } 136 137 changeRunTrace(run: boolean, trace: TraceConfiguration): void { 138 trace.run = run; 139 } 140} 141