1/* 2 * Copyright (C) 2024 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 {TraceType} from 'trace/trace_type'; 18import {AbstractSearchViewFactory} from './abstract_search_view_factory'; 19 20export class SearchViewFactorySf extends AbstractSearchViewFactory { 21 override readonly traceType = TraceType.SURFACE_FLINGER; 22 23 override async createSearchViews(): Promise<string[]> { 24 const layerArgsTable = await this.createSqlTableWithDefaults( 25 'surfaceflinger_layer', 26 ); 27 const snapshotArgsTable = await this.createSqlTableWithDefaults( 28 'surfaceflinger_layers_snapshot', 29 ); 30 31 const sqlCreateTableSfStateChanges = ` 32 CREATE PERFETTO TABLE sf_state_changes AS 33 SELECT 34 STATE.id as state_id, 35 (SELECT X.id 36 FROM surfaceflinger_layers_snapshot X 37 WHERE X.ts < STATE.ts 38 ORDER BY X.ts DESC 39 LIMIT 1 40 ) as previous_state_id 41 FROM surfaceflinger_layers_snapshot STATE; 42 `; 43 await this.traceProcessor.query(sqlCreateTableSfStateChanges); 44 45 const sqlCreateTableSfLayerIdentifier = ` 46 CREATE PERFETTO TABLE sf_layer_identifier AS 47 SELECT 48 LAYER.snapshot_id as state_id, 49 LAYER_ID.int_value as layer_id, 50 PARENT_PROPERTY.int_value as parent_id, 51 NAME.string_value as layer_name, 52 LAYER.base64_proto_id 53 FROM surfaceflinger_layer LAYER 54 INNER JOIN ${layerArgsTable} LAYER_ID ON LAYER_ID.base64_proto_id = LAYER.base64_proto_id AND LAYER_ID.key = 'id' 55 INNER JOIN ${layerArgsTable} PARENT_PROPERTY ON PARENT_PROPERTY.base64_proto_id = LAYER.base64_proto_id AND PARENT_PROPERTY.key = 'parent' 56 INNER JOIN ${layerArgsTable} NAME ON NAME.base64_proto_id = LAYER.base64_proto_id AND NAME.key = 'name'; 57 `; 58 await this.traceProcessor.query(sqlCreateTableSfLayerIdentifier); 59 60 const sqlCreateViewSfLayerWithProperties = ` 61 CREATE PERFETTO VIEW sf_layer_with_properties AS 62 SELECT 63 STATE.id as state_id, 64 STATE.ts, 65 LAYER.layer_id, 66 LAYER.parent_id, 67 LAYER.layer_name, 68 PROPERTY.key as property, 69 PROPERTY.flat_key as flat_property, 70 PROPERTY.display_value as value 71 FROM surfaceflinger_layers_snapshot STATE 72 INNER JOIN sf_layer_identifier LAYER ON LAYER.state_id = STATE.id 73 INNER JOIN ${layerArgsTable} PROPERTY ON PROPERTY.base64_proto_id = LAYER.base64_proto_id; 74 `; 75 await this.traceProcessor.query(sqlCreateViewSfLayerWithProperties); 76 77 const layerSearchView = 'sf_layer_search'; 78 const sqlCreateViewSfLayerSearch = ` 79 CREATE PERFETTO VIEW ${layerSearchView}( 80 state_id INT, 81 ts INT, 82 layer_id INT, 83 parent_id INT, 84 layer_name STRING, 85 property STRING, 86 flat_property STRING, 87 value STRING, 88 previous_value STRING 89 ) AS 90 SELECT 91 CURRENT.state_id, 92 CURRENT.ts, 93 CURRENT.layer_id, 94 CURRENT.parent_id, 95 CURRENT.layer_name, 96 CURRENT.property, 97 CURRENT.flat_property, 98 CURRENT.value, 99 PREVIOUS.value as previous_value 100 FROM sf_state_changes CHANGE 101 INNER JOIN sf_layer_with_properties CURRENT ON CURRENT.state_id = CHANGE.state_id 102 INNER JOIN sf_layer_with_properties PREVIOUS ON PREVIOUS.state_id = CHANGE.previous_state_id AND PREVIOUS.layer_id = CURRENT.layer_id AND PREVIOUS.property = CURRENT.property; 103 `; 104 await this.traceProcessor.query(sqlCreateViewSfLayerSearch); 105 106 const sqlCreateViewSfEntry = ` 107 CREATE PERFETTO VIEW sf_entry AS 108 SELECT 109 STATE.id as state_id, 110 STATE.ts, 111 PROPERTY.key as property, 112 PROPERTY.flat_key as flat_property, 113 PROPERTY.display_value as value 114 FROM surfaceflinger_layers_snapshot STATE 115 INNER JOIN ${snapshotArgsTable} PROPERTY ON PROPERTY.base64_proto_id = STATE.base64_proto_id; 116 `; 117 await this.traceProcessor.query(sqlCreateViewSfEntry); 118 119 const entrySearchView = 'sf_entry_search'; 120 const sqlCreateViewSfEntrySearch = ` 121 CREATE PERFETTO VIEW ${entrySearchView} AS 122 SELECT 123 STATE.*, 124 PREVIOUS.value as previous_value 125 FROM sf_entry STATE 126 INNER JOIN sf_state_changes STATE_CHANGES ON STATE_CHANGES.state_id = STATE.state_id 127 LEFT JOIN sf_entry PREVIOUS ON PREVIOUS.state_id = STATE_CHANGES.previous_state_id 128 AND PREVIOUS.property = STATE.property; 129 `; 130 await this.traceProcessor.query(sqlCreateViewSfEntrySearch); 131 132 return [layerSearchView, entrySearchView]; 133 } 134} 135