xref: /aosp_15_r20/development/tools/winscope/protos/build.js (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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