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'; 19import {SearchView} from './trace_search_initializer'; 20 21export class SearchViewFactoryTransactions extends AbstractSearchViewFactory { 22 override readonly traceType = TraceType.TRANSACTIONS; 23 private static readonly VIEW: SearchView = { 24 name: 'transactions_search', 25 dataType: 26 'the Transactions trace, including transactions, added/destroyed layers and added/removed/changed displays', 27 columns: [ 28 { 29 name: 'state_id', 30 desc: 'Unique id of entry to which proto property belongs', 31 }, 32 { 33 name: 'ts', 34 desc: 'Timestamp of entry to which proto property belongs', 35 }, 36 { 37 name: 'transaction_id', 38 desc: 'Transaction id if available', 39 }, 40 { 41 name: 'property', 42 desc: 'Property name accounting for repeated fields', 43 }, 44 { 45 name: 'flat_property', 46 desc: 'Property name not accounting for repeated fields', 47 }, 48 {name: 'value', desc: 'Property value in string format'}, 49 ], 50 examples: [ 51 { 52 query: `SELECT ts, transaction_id FROM transactions_search 53WHERE flat_property='transactions.layer_changes.x' 54AND value='-54.0'`, 55 desc: 'returns timestamp and transaction id when layer x position was changed to -54.0', 56 }, 57 { 58 query: `SELECT ts FROM transactions_search 59WHERE flat_property='added_layers.name' 60AND value='ImeContainer'`, 61 desc: 'returns timestamp when ImeContainer layer was added', 62 }, 63 ], 64 }; 65 66 static getPossibleSearchViews(): SearchView[] { 67 return [SearchViewFactoryTransactions.VIEW]; 68 } 69 70 override async createSearchViews(): Promise<string[]> { 71 const dataTable = await this.createSqlTableWithDefaults( 72 'surfaceflinger_transactions', 73 ); 74 75 const sqlCreateViewTransactionWithProperties = ` 76 CREATE PERFETTO VIEW transaction_with_properties AS 77 SELECT 78 STATE.id as state_id, 79 STATE.ts, 80 TX_ID.display_value as transaction_id, 81 PROPERTY.key as property, 82 PROPERTY.flat_key as flat_property, 83 PROPERTY.display_value as value 84 FROM surfaceflinger_transactions STATE 85 INNER JOIN ${dataTable} PROPERTY 86 ON PROPERTY.base64_proto_id = STATE.base64_proto_id 87 LEFT JOIN ${dataTable} TX_ID 88 ON TX_ID.base64_proto_id = STATE.base64_proto_id 89 AND TX_ID.flat_key = 'transactions.transaction_id' 90 AND SUBSTRING(TX_ID.key, 0, instr(TX_ID.key, ']')) = SUBSTRING(PROPERTY.key, 0, instr(PROPERTY.key, ']')); 91 `; 92 await this.traceProcessor.query(sqlCreateViewTransactionWithProperties); 93 94 const sqlCreateViewTransactionSearch = ` 95 CREATE PERFETTO VIEW ${SearchViewFactoryTransactions.VIEW.name}( 96 state_id INT, 97 ts INT, 98 transaction_id STRING, 99 property STRING, 100 flat_property STRING, 101 value STRING 102 ) AS 103 SELECT 104 TRANS.state_id, 105 TRANS.ts, 106 TRANS.transaction_id, 107 TRANS.property, 108 TRANS.flat_property, 109 TRANS.value 110 FROM surfaceflinger_transactions CURRENT 111 INNER JOIN transaction_with_properties TRANS ON CURRENT.id = TRANS.state_id 112 ORDER BY TRANS.ts; 113 `; 114 await this.traceProcessor.query(sqlCreateViewTransactionSearch); 115 return [SearchViewFactoryTransactions.VIEW.name]; 116 } 117} 118