1/* 2 * Copyright (C) 2023 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 */ 16const {exec} = require('child_process'); 17 18const ANDROID_BUILD_TOP = __dirname + '/../../../../'; 19const WINSCOPE_TOP = __dirname + '/..'; 20const PERFETTO_TOP = ANDROID_BUILD_TOP + '/external/perfetto'; 21const OUT_TOP = __dirname + '/../deps_build/protos'; 22 23build(); 24 25async function build() { 26 await runCommand(`rm -rf ${OUT_TOP}`); 27 28 const promises = [ 29 // IME 30 buildProtos([ 31 '../../../../frameworks/base/core/proto/android/view/inputmethod/inputmethodeditortrace.proto' 32 ], 'ime/udc'), 33 buildProtos([ 34 'ime/latest/wrapper.proto', 35 ], 'ime/latest'), 36 37 // ProtoLog 38 buildProtos([ 39 'protolog/udc/protolog.proto' 40 ], 'protolog/udc'), 41 buildProtos([ 42 '../../../../external/perfetto/protos/perfetto/trace/android/protolog.proto' 43 ], 'protolog/latest'), 44 45 // SurfaceFlinger 46 buildProtos([ 47 'surfaceflinger/udc/layerstrace.proto', 48 ], 'surfaceflinger/udc'), 49 buildProtos([ 50 '../../../../external/perfetto/protos/perfetto/trace/android/surfaceflinger_layers.proto', 51 ], 'surfaceflinger/latest'), 52 53 // Transactions 54 buildProtos([ 55 'surfaceflinger/udc/transactions.proto', 56 ], 'transactions/udc'), 57 buildProtos([ 58 '../../../../external/perfetto/protos/perfetto/trace/android/surfaceflinger_transactions.proto', 59 ], 'transactions/latest'), 60 61 // Transitions 62 buildProtos([ 63 'transitions/udc/windowmanagertransitiontrace.proto', 64 'transitions/udc/wm_shell_transition_trace.proto' 65 ], 'transitions/udc'), 66 buildProtos([ 67 '../../../../external/perfetto/protos/perfetto/trace/android/shell_transition.proto', 68 ], 'transitions/latest'), 69 70 // ViewCapture 71 buildProtos([ 72 '../../../../frameworks/libs/systemui/viewcapturelib/src/com/android/app/viewcapture/proto/view_capture.proto' 73 ], 'viewcapture/udc'), 74 buildProtos([ 75 'viewcapture/latest/wrapper.proto', 76 ], 'viewcapture/latest'), 77 78 // WindowManager 79 buildProtos([ 80 '../../../../frameworks/base/core/proto/android/server/windowmanagertrace.proto', 81 ], 'windowmanager/udc'), 82 buildProtos([ 83 'windowmanager/latest/wrapper.proto', 84 ], 'windowmanager/latest'), 85 86 // Input 87 buildProtos([ 88 '../../../../external/perfetto/protos/perfetto/trace/android/android_input_event.proto', 89 'input/latest/input_event_wrapper.proto', 90 ], 'input/latest'), 91 92 // Test proto fields 93 buildProtos([ 94 'test/fake_proto_test.proto', 95 ], 'test/fake_proto'), 96 97 // Test intdef translation 98 buildProtos([ 99 'test/intdef_translation_test.proto', 100 ], 'test/intdef_translation'), 101 ]; 102 103 await Promise.all(promises); 104} 105 106async function buildProtos(protoPaths, outSubdir) { 107 const outDir = OUT_TOP + '/' + outSubdir; 108 const protoFullPaths = protoPaths.map((path) => __dirname + '/' + path); 109 const rootName = outSubdir.replaceAll('/', '_'); 110 111 const commandBuildJson = [ 112 'npx', 113 'pbjs', 114 //TODO(b/318480413): for perfetto traces use '--force-bigint' as soon as available, 115 // i.e. when this PR is merged https://github.com/protobufjs/protobuf.js/pull/1557 116 '--force-long', 117 '--target json-module', 118 '--wrap es6', 119 `--out ${outDir}/json.js`, 120 `--root ${rootName}`, 121 `--path ${PERFETTO_TOP}`, 122 `--path ${WINSCOPE_TOP}`, 123 `--path ${ANDROID_BUILD_TOP}`, 124 protoFullPaths.join(' ') 125 ].join(' '); 126 127 const commandBuildJs = [ 128 'npx', 129 'pbjs', 130 '--force-long', 131 '--target static-module', 132 `--root ${outSubdir.replace('/', '')}`, 133 `--out ${outDir}/static.js`, 134 `--path ${PERFETTO_TOP}`, 135 `--path ${WINSCOPE_TOP}`, 136 `--path ${ANDROID_BUILD_TOP}`, 137 protoFullPaths.join(' '), 138 ].join(' '); 139 140 const commandBuildTs = [ 141 'npx', 142 'pbts', 143 `--out ${outDir}/static.d.ts`, 144 `${outDir}/static.js` 145 ].join(' '); 146 147 await runCommand(`mkdir -p ${outDir}`) 148 await runCommand(commandBuildJson); 149 await runCommand(commandBuildJs); 150 await runCommand(commandBuildTs); 151} 152 153function runCommand(command) { 154 return new Promise((resolve, reject) => { 155 exec(command, (err, stdout, stderr) => { 156 if (err) { 157 const errorMessage = 158 "Failed to execute command" + 159 `\n\ncommand: ${command}` + 160 `\n\nstdout: ${stdout}` + 161 `\n\nstderr: ${stderr}`; 162 reject(errorMessage); 163 } 164 resolve(); 165 }); 166 }); 167} 168