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 */
16
17syntax = "proto2";
18
19import "atom_field_options.proto";
20import "attribution_node.proto";
21
22package android.stats_log_api_gen;
23
24message IntAtom {
25    optional int32 field1 = 1;
26}
27
28message AnotherIntAtom {
29    optional int32 field1 = 1;
30}
31
32message OutOfOrderAtom {
33    optional int32 field2 = 2;
34    optional int32 field1 = 1;
35}
36
37enum AnEnum {
38    VALUE0 = 0;
39    VALUE1 = 1;
40}
41
42message SubMessageWithUint {
43    optional uint32 field1 = 1;
44}
45
46message AllTypesAtom {
47  repeated android.os.statsd.AttributionNode attribution_chain = 1;
48  optional float float_field = 2;
49  optional int64 int64_field = 3;
50  optional int32 int32_field = 4;
51  optional bool bool_field = 5;
52  optional string string_field = 6;
53  optional AnEnum enum_field = 7;
54  repeated float repeated_float_field = 8;
55  repeated int64 repeated_int64_field = 9;
56  repeated int32 repeated_int32_field = 10;
57  repeated bool repeated_bool_field = 11;
58  repeated string repeated_string_field = 12;
59  optional SubMessageWithUint sub_message_with_uint_field = 13
60          [(android.os.statsd.log_mode) = MODE_BYTES];
61}
62
63// Separated from AllTypesAtom because tests can't properly check atoms with multiple enum type
64// fields
65message RepeatedEnumAtom {
66    repeated AnEnum repeated_enum_field = 1;
67}
68
69message Event {
70    oneof pushed {
71        OutOfOrderAtom out_of_order_atom = 2;
72        IntAtom int_atom = 1;
73        AnotherIntAtom another_int_atom = 3;
74        AllTypesAtom all_types_atom = 4;
75        RepeatedEnumAtom repeated_enum_atom = 5;
76    }
77}
78
79message BadTypesAtom {
80    optional IntAtom bad_int_atom = 1;
81    optional bytes bad_bytes = 2;
82    optional double double_field = 3;
83    optional fixed64 fixed64_field = 4;
84    optional fixed32 fixed32_field = 5;
85    optional sfixed64 sfixed64_field = 6;
86    optional sfixed32 sfixed32_field = 7;
87    optional sint64 sint64_field = 8;
88    optional sint32 sint32_field = 9;
89    repeated double double_repeated_field = 10;
90    repeated fixed64 fixed64_repeated_field = 11;
91    repeated fixed32 fixed32_repeated_field = 12;
92    repeated sfixed64 sfixed64_repeated_field = 13;
93    repeated sfixed32 sfixed32_repeated_field = 14;
94    repeated sint64 sint64_repeated_field = 15;
95    repeated sint32 sint32_repeated_field = 16;
96    repeated uint64 uint64_repeated_field = 17;
97    repeated uint32 uint32_repeated_field = 18;
98    repeated IntAtom bad_int_atom_repeated_field = 19;
99    repeated bytes bad_bytes_repeated_field = 20;
100    optional uint32 uint32_field = 21;
101    optional uint64 uint64_field = 22;
102}
103
104message BadTypesEvent {
105    oneof pushed {
106        BadTypesAtom bad_types_atom = 1;
107    }
108}
109
110message BadSkippedFieldSingleAtom {
111    optional int32 field2 = 2;
112}
113
114message BadSkippedFieldSingle {
115    oneof pushed {
116        BadSkippedFieldSingleAtom bad = 1;
117    }
118}
119
120message BadSkippedFieldMultipleAtom {
121    optional int32 field1 = 1;
122    optional int32 field3 = 3;
123    optional int32 field5 = 5;
124}
125
126message BadSkippedFieldMultiple {
127    oneof pushed {
128        BadSkippedFieldMultipleAtom bad = 1;
129    }
130}
131
132message BadAttributionNodePositionAtom {
133  optional int32 field1 = 1;
134  repeated android.os.statsd.AttributionNode attribution = 2;
135}
136
137message BadAttributionNodePosition {
138  oneof pushed { BadAttributionNodePositionAtom bad = 1; }
139}
140
141message GoodEventWithBinaryFieldAtom {
142    oneof pushed { GoodBinaryFieldAtom field1 = 1; }
143}
144
145message ComplexField {
146    optional string str = 1;
147}
148
149message GoodBinaryFieldAtom {
150    optional int32 field1 = 1;
151    optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
152}
153
154message BadEventWithBinaryFieldAtom {
155    oneof pushed { BadBinaryFieldAtom field1 = 1; }
156}
157
158message BadBinaryFieldAtom {
159    optional int32 field1 = 1;
160    optional ComplexField bf = 2;
161}
162
163message BadStateAtoms {
164    oneof pushed {
165        BadStateAtom1 bad1 = 1;
166        BadStateAtom2 bad2 = 2;
167        BadStateAtom3 bad3 = 3;
168        BadStateAtom4 bad4 = 4;
169    }
170}
171
172message GoodStateAtoms {
173    oneof pushed {
174        GoodStateAtom1 good1 = 1;
175        GoodStateAtom2 good2 = 2;
176    }
177}
178
179message GoodRestrictedAtom {
180    optional int64 int64_field = 1 [(android.os.statsd.field_restriction_option).app_usage = true];
181    optional int32 int32_field_1 = 2
182            [(android.os.statsd.field_restriction_option).health_connect = true];
183    optional bool bool_field = 3
184            [(android.os.statsd.field_restriction_option).accessibility = true];
185    optional string string_field = 4
186            [(android.os.statsd.field_restriction_option).system_search = true];
187    optional AnEnum enum_field = 5
188            [(android.os.statsd.field_restriction_option).ambient_sensing = true];
189    optional float float_field = 6
190            [(android.os.statsd.field_restriction_option).peripheral_device_info = true];
191    optional int32 int32_field_2 = 7
192            [(android.os.statsd.field_restriction_option).demographic_classification = true];
193}
194
195// Nonprimitive fields
196message BadRestrictedAtom1 {
197    repeated android.os.statsd.AttributionNode attribution_chain = 1
198        [(android.os.statsd.field_restriction_option).demographic_classification = true];
199    repeated float repeated_float_field = 2
200        [(android.os.statsd.field_restriction_option).app_usage = true];
201    repeated int64 repeated_int64_field = 3
202        [(android.os.statsd.field_restriction_option).app_activity = true];
203    repeated int32 repeated_int32_field = 4
204        [(android.os.statsd.field_restriction_option).health_connect = true];
205    repeated bool repeated_bool_field = 5
206        [(android.os.statsd.field_restriction_option).accessibility = true];
207    repeated string repeated_string_field = 6
208        [(android.os.statsd.field_restriction_option).system_search = true];
209}
210
211// Restriction category on atom field
212message BadRestrictedAtom2 {
213    optional int32 int32_field = 1
214        [(android.os.statsd.restriction_category) = RESTRICTION_DIAGNOSTIC];
215}
216
217// The atom has only primary field but no exclusive state field.
218message BadStateAtom1 {
219    optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
220}
221
222// Only primative types can be annotated.
223message BadStateAtom2 {
224    repeated android.os.statsd.AttributionNode attribution = 1
225            [(android.os.statsd.state_field_option).primary_field = true];
226    optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
227}
228
229// Having 2 exclusive state field in the atom means the atom is badly designed.
230// E.g., putting bluetooth state and wifi state in the same atom.
231message BadStateAtom3 {
232    optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
233    optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
234    optional int32 state2 = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
235}
236
237// Repeated fields can't have state annotations.
238message BadStateAtom4 {
239    repeated int32 state = 1 [(android.os.statsd.state_field_option).exclusive_state = true];
240}
241
242message GoodStateAtom1 {
243    optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
244    optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
245}
246
247// Atoms can have exclusive state field, but no primary field. That means
248// the state is globally exclusive (e.g., DisplayState).
249message GoodStateAtom2 {
250    optional int32 uid = 1;
251    optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true];
252}
253
254// We can have more than one primary fields. That means their combination is a
255// primary key.
256message GoodStateAtom3 {
257    optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true];
258    optional int32 tid = 2 [(android.os.statsd.state_field_option).primary_field = true];
259    optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
260}
261
262message BadUidAtoms {
263    oneof pushed {
264        BadUidAtom1 bad1 = 1;
265        BadUidAtom2 bad2 = 2;
266    }
267}
268
269message GoodUidAtoms {
270    oneof pushed {
271        GoodUidAtom1 good1 = 1;
272        GoodUidAtom2 good2 = 2;
273    }
274}
275
276// The only repeated field type that can have is_uid annotation is int32.
277message BadUidAtom1 {
278    repeated int64 uid = 1 [(android.os.statsd.is_uid) = true];
279}
280
281message BadUidAtom2 {
282    optional string uid = 1 [(android.os.statsd.is_uid) = true];
283}
284
285message GoodUidAtom1 {
286    optional int32 uid = 1 [(android.os.statsd.is_uid) = true];
287}
288
289message GoodUidAtom2 {
290    repeated int32 uid = 1 [(android.os.statsd.is_uid) = true];
291}
292
293message ModuleOneAtom {
294    optional int32 field = 1 [(android.os.statsd.is_uid) = true];
295}
296
297message ModuleTwoAtom {
298    optional int32 field = 1;
299}
300
301message ModuleOneAndTwoAtom {
302    optional int32 field = 1 [(android.os.statsd.state_field_option).exclusive_state = true];
303}
304
305message NoModuleAtom {
306    optional string field = 1;
307}
308
309message ModuleAtoms {
310    oneof pushed {
311        ModuleOneAtom module_one_atom = 1 [(android.os.statsd.module) = "module1"];
312        ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.module) = "module2"];
313        ModuleOneAndTwoAtom module_one_and_two_atom = 3 [
314                (android.os.statsd.module) = "module1", (android.os.statsd.module) = "module2"
315        ];
316        NoModuleAtom no_module_atom = 4;
317    }
318}
319
320message PushedAndPulledAtoms {
321    oneof pushed {
322        IntAtom int_atom_1 = 1;
323    }
324
325    oneof pulled {
326        OutOfOrderAtom out_of_order_atom = 99999;
327        AnotherIntAtom another_int_atom = 10000;
328    }
329}
330
331message VendorAtoms {
332    optional IntAtom pushed_atom_100000 = 100000;
333    optional AnotherIntAtom pulled_atom_199999 = 199999;
334}
335
336message GoodRestrictedAtoms {
337    optional GoodRestrictedAtom pushed_atom_1 = 1
338        [(android.os.statsd.restriction_category) = RESTRICTION_DIAGNOSTIC];
339    optional GoodRestrictedAtom pushed_atom_2 = 2
340        [(android.os.statsd.restriction_category) = RESTRICTION_SYSTEM_INTELLIGENCE];
341}
342
343// Nonprimitive fields
344message BadRestrictedAtoms1 {
345    optional BadRestrictedAtom1 pushed_atom_1 = 1
346        [(android.os.statsd.restriction_category) = RESTRICTION_AUTHENTICATION];
347}
348
349// Restriction category on atom field
350message BadRestrictedAtoms2 {
351    optional BadRestrictedAtom2 pushed_atom_1 = 1;
352}
353
354// Field restriction without restriction category
355message BadRestrictedAtoms3 {
356    optional GoodRestrictedAtom pushed_atom_1 = 1;
357}
358
359// Field restriction option on top level atom field
360message BadRestrictedAtoms4 {
361    optional IntAtom pushed_atom_1 = 1
362        [(android.os.statsd.field_restriction_option).peripheral_device_info = true];
363}
364
365// Restricted pulled atoms
366message BadRestrictedAtoms5 {
367    optional GoodRestrictedAtom pulled_atom_10001 = 10001
368        [(android.os.statsd.restriction_category) = RESTRICTION_AUTHENTICATION];
369    optional GoodRestrictedAtom pulled_atom_10002 = 10002
370        [(android.os.statsd.restriction_category) = RESTRICTION_FRAUD_AND_ABUSE];
371}
372
373// Allowed uint atoms.
374message AppDied {
375    optional uint32 uint32_field = 1;
376}
377
378message SystemUptime {
379    optional uint64 uint64_field = 1;
380}
381
382message GoodUintAtoms {
383    oneof pushed {
384        AppDied app_died = 1;
385    }
386    oneof pulled {
387        SystemUptime system_uptime = 2;
388    }
389}
390
391message ExtensionAtoms {
392    oneof pushed {
393        IntAtom int_atom_1 = 1;
394    }
395    oneof pulled {
396        OutOfOrderAtom out_of_order_atom = 10000;
397    }
398
399    extensions 9999; // Pushed atom extension, ExtensionAtomPushed
400
401    extensions 99999; // Pulled atom extension, ExtensionAtomPulled
402}
403