xref: /aosp_15_r20/system/extras/libatrace_rust/src/lib.rs (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker // Copyright (C) 2023 The Android Open Source Project
2*288bf522SAndroid Build Coastguard Worker //
3*288bf522SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*288bf522SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*288bf522SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*288bf522SAndroid Build Coastguard Worker //
7*288bf522SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*288bf522SAndroid Build Coastguard Worker //
9*288bf522SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*288bf522SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*288bf522SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*288bf522SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*288bf522SAndroid Build Coastguard Worker // limitations under the License.
14*288bf522SAndroid Build Coastguard Worker 
15*288bf522SAndroid Build Coastguard Worker //! ATrace instrumentation methods from cutils.
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker use std::ffi::CString;
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #[cfg(not(test))]
20*288bf522SAndroid Build Coastguard Worker use cutils_trace_bindgen as trace_bind;
21*288bf522SAndroid Build Coastguard Worker 
22*288bf522SAndroid Build Coastguard Worker // Wrap tags into a mod to allow missing docs.
23*288bf522SAndroid Build Coastguard Worker // We have to use the mod for this because Rust won't apply the attribute to the bitflags macro
24*288bf522SAndroid Build Coastguard Worker // invocation.
25*288bf522SAndroid Build Coastguard Worker pub use self::tags::*;
26*288bf522SAndroid Build Coastguard Worker pub mod tags {
27*288bf522SAndroid Build Coastguard Worker     // Tag constants are not documented in libcutils, so we don't document them here.
28*288bf522SAndroid Build Coastguard Worker     #![allow(missing_docs)]
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker     use bitflags::bitflags;
31*288bf522SAndroid Build Coastguard Worker     use static_assertions::const_assert_eq;
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker     bitflags! {
34*288bf522SAndroid Build Coastguard Worker         /// The trace tag is used to filter tracing in userland to avoid some of the runtime cost of
35*288bf522SAndroid Build Coastguard Worker         /// tracing when it is not desired.
36*288bf522SAndroid Build Coastguard Worker         ///
37*288bf522SAndroid Build Coastguard Worker         /// Using `AtraceTag::Always` will result in the tracing always being enabled - this should
38*288bf522SAndroid Build Coastguard Worker         /// ONLY be done for debug code, as userland tracing has a performance cost even when the
39*288bf522SAndroid Build Coastguard Worker         /// trace is not being recorded. `AtraceTag::Never` will result in the tracing always being
40*288bf522SAndroid Build Coastguard Worker         /// disabled.
41*288bf522SAndroid Build Coastguard Worker         ///
42*288bf522SAndroid Build Coastguard Worker         /// `AtraceTag::Hal` should be bitwise ORed with the relevant tags for tracing
43*288bf522SAndroid Build Coastguard Worker         /// within a hardware module. For example a camera hardware module would use
44*288bf522SAndroid Build Coastguard Worker         /// `AtraceTag::Camera | AtraceTag::Hal`.
45*288bf522SAndroid Build Coastguard Worker         ///
46*288bf522SAndroid Build Coastguard Worker         /// Source of truth is `system/core/libcutils/include/cutils/trace.h`.
47*288bf522SAndroid Build Coastguard Worker         #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
48*288bf522SAndroid Build Coastguard Worker         pub struct AtraceTag: u64 {
49*288bf522SAndroid Build Coastguard Worker             const Never           = cutils_trace_bindgen::ATRACE_TAG_NEVER as u64;
50*288bf522SAndroid Build Coastguard Worker             const Always          = cutils_trace_bindgen::ATRACE_TAG_ALWAYS as u64;
51*288bf522SAndroid Build Coastguard Worker             const Graphics        = cutils_trace_bindgen::ATRACE_TAG_GRAPHICS as u64;
52*288bf522SAndroid Build Coastguard Worker             const Input           = cutils_trace_bindgen::ATRACE_TAG_INPUT as u64;
53*288bf522SAndroid Build Coastguard Worker             const View            = cutils_trace_bindgen::ATRACE_TAG_VIEW as u64;
54*288bf522SAndroid Build Coastguard Worker             const Webview         = cutils_trace_bindgen::ATRACE_TAG_WEBVIEW as u64;
55*288bf522SAndroid Build Coastguard Worker             const WindowManager   = cutils_trace_bindgen::ATRACE_TAG_WINDOW_MANAGER as u64;
56*288bf522SAndroid Build Coastguard Worker             const ActivityManager = cutils_trace_bindgen::ATRACE_TAG_ACTIVITY_MANAGER as u64;
57*288bf522SAndroid Build Coastguard Worker             const SyncManager     = cutils_trace_bindgen::ATRACE_TAG_SYNC_MANAGER as u64;
58*288bf522SAndroid Build Coastguard Worker             const Audio           = cutils_trace_bindgen::ATRACE_TAG_AUDIO as u64;
59*288bf522SAndroid Build Coastguard Worker             const Video           = cutils_trace_bindgen::ATRACE_TAG_VIDEO as u64;
60*288bf522SAndroid Build Coastguard Worker             const Camera          = cutils_trace_bindgen::ATRACE_TAG_CAMERA as u64;
61*288bf522SAndroid Build Coastguard Worker             const Hal             = cutils_trace_bindgen::ATRACE_TAG_HAL as u64;
62*288bf522SAndroid Build Coastguard Worker             const App             = cutils_trace_bindgen::ATRACE_TAG_APP as u64;
63*288bf522SAndroid Build Coastguard Worker             const Resources       = cutils_trace_bindgen::ATRACE_TAG_RESOURCES as u64;
64*288bf522SAndroid Build Coastguard Worker             const Dalvik          = cutils_trace_bindgen::ATRACE_TAG_DALVIK as u64;
65*288bf522SAndroid Build Coastguard Worker             const Rs              = cutils_trace_bindgen::ATRACE_TAG_RS as u64;
66*288bf522SAndroid Build Coastguard Worker             const Bionic          = cutils_trace_bindgen::ATRACE_TAG_BIONIC as u64;
67*288bf522SAndroid Build Coastguard Worker             const Power           = cutils_trace_bindgen::ATRACE_TAG_POWER as u64;
68*288bf522SAndroid Build Coastguard Worker             const PackageManager  = cutils_trace_bindgen::ATRACE_TAG_PACKAGE_MANAGER as u64;
69*288bf522SAndroid Build Coastguard Worker             const SystemServer    = cutils_trace_bindgen::ATRACE_TAG_SYSTEM_SERVER as u64;
70*288bf522SAndroid Build Coastguard Worker             const Database        = cutils_trace_bindgen::ATRACE_TAG_DATABASE as u64;
71*288bf522SAndroid Build Coastguard Worker             const Network         = cutils_trace_bindgen::ATRACE_TAG_NETWORK as u64;
72*288bf522SAndroid Build Coastguard Worker             const Adb             = cutils_trace_bindgen::ATRACE_TAG_ADB as u64;
73*288bf522SAndroid Build Coastguard Worker             const Vibrator        = cutils_trace_bindgen::ATRACE_TAG_VIBRATOR as u64;
74*288bf522SAndroid Build Coastguard Worker             const Aidl            = cutils_trace_bindgen::ATRACE_TAG_AIDL as u64;
75*288bf522SAndroid Build Coastguard Worker             const Nnapi           = cutils_trace_bindgen::ATRACE_TAG_NNAPI as u64;
76*288bf522SAndroid Build Coastguard Worker             const Rro             = cutils_trace_bindgen::ATRACE_TAG_RRO as u64;
77*288bf522SAndroid Build Coastguard Worker             const Thermal         = cutils_trace_bindgen::ATRACE_TAG_THERMAL as u64;
78*288bf522SAndroid Build Coastguard Worker             const Last            = cutils_trace_bindgen::ATRACE_TAG_LAST as u64;
79*288bf522SAndroid Build Coastguard Worker             const NotReady        = cutils_trace_bindgen::ATRACE_TAG_NOT_READY as u64;
80*288bf522SAndroid Build Coastguard Worker             const ValidMask       = cutils_trace_bindgen::ATRACE_TAG_VALID_MASK as u64;
81*288bf522SAndroid Build Coastguard Worker         }
82*288bf522SAndroid Build Coastguard Worker     }
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker     // Assertion to keep tags in sync. If it fails, it means there are new tags added to
85*288bf522SAndroid Build Coastguard Worker     // cutils/trace.h. Add them to the tags above and update the assertion.
86*288bf522SAndroid Build Coastguard Worker     const_assert_eq!(AtraceTag::Thermal.bits(), cutils_trace_bindgen::ATRACE_TAG_LAST as u64);
87*288bf522SAndroid Build Coastguard Worker }
88*288bf522SAndroid Build Coastguard Worker 
89*288bf522SAndroid Build Coastguard Worker /// RAII guard to close an event with tag.
90*288bf522SAndroid Build Coastguard Worker pub struct ScopedEvent {
91*288bf522SAndroid Build Coastguard Worker     tag: AtraceTag,
92*288bf522SAndroid Build Coastguard Worker }
93*288bf522SAndroid Build Coastguard Worker 
94*288bf522SAndroid Build Coastguard Worker impl Drop for ScopedEvent {
drop(&mut self)95*288bf522SAndroid Build Coastguard Worker     fn drop(&mut self) {
96*288bf522SAndroid Build Coastguard Worker         atrace_end(self.tag);
97*288bf522SAndroid Build Coastguard Worker     }
98*288bf522SAndroid Build Coastguard Worker }
99*288bf522SAndroid Build Coastguard Worker 
100*288bf522SAndroid Build Coastguard Worker /// Begins an event via `atrace_begin` and returns a guard that calls `atrace_end` when dropped.
begin_scoped_event(tag: AtraceTag, name: &str) -> ScopedEvent101*288bf522SAndroid Build Coastguard Worker pub fn begin_scoped_event(tag: AtraceTag, name: &str) -> ScopedEvent {
102*288bf522SAndroid Build Coastguard Worker     atrace_begin(tag, name);
103*288bf522SAndroid Build Coastguard Worker     ScopedEvent { tag }
104*288bf522SAndroid Build Coastguard Worker }
105*288bf522SAndroid Build Coastguard Worker 
106*288bf522SAndroid Build Coastguard Worker /// Creates a scoped event with the current method name.
107*288bf522SAndroid Build Coastguard Worker #[macro_export]
108*288bf522SAndroid Build Coastguard Worker macro_rules! trace_method {
109*288bf522SAndroid Build Coastguard Worker     {$tag:expr} => {
110*288bf522SAndroid Build Coastguard Worker         let mut _atrace_trace_method_name: &'static str = "";
111*288bf522SAndroid Build Coastguard Worker         {
112*288bf522SAndroid Build Coastguard Worker             // Declares function f inside current function.
113*288bf522SAndroid Build Coastguard Worker             fn f() {}
114*288bf522SAndroid Build Coastguard Worker             fn type_name_of<T>(_: T) -> &'static str {
115*288bf522SAndroid Build Coastguard Worker                 std::any::type_name::<T>()
116*288bf522SAndroid Build Coastguard Worker             }
117*288bf522SAndroid Build Coastguard Worker             // type name of f is struct_or_crate_name::calling_function_name::f
118*288bf522SAndroid Build Coastguard Worker             let name = type_name_of(f);
119*288bf522SAndroid Build Coastguard Worker             // Remove the third to last character ("::f")
120*288bf522SAndroid Build Coastguard Worker             _atrace_trace_method_name = &name[..name.len() - 3];
121*288bf522SAndroid Build Coastguard Worker         }
122*288bf522SAndroid Build Coastguard Worker         let _atrace_trace_method_guard = atrace::begin_scoped_event($tag, _atrace_trace_method_name);
123*288bf522SAndroid Build Coastguard Worker     };
124*288bf522SAndroid Build Coastguard Worker }
125*288bf522SAndroid Build Coastguard Worker 
126*288bf522SAndroid Build Coastguard Worker /// Set whether tracing is enabled for the current process. This is used to prevent tracing within
127*288bf522SAndroid Build Coastguard Worker /// the Zygote process.
atrace_set_tracing_enabled(enabled: bool)128*288bf522SAndroid Build Coastguard Worker pub fn atrace_set_tracing_enabled(enabled: bool) {
129*288bf522SAndroid Build Coastguard Worker     // SAFETY: No pointers are transferred.
130*288bf522SAndroid Build Coastguard Worker     unsafe {
131*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_set_tracing_enabled(enabled);
132*288bf522SAndroid Build Coastguard Worker     }
133*288bf522SAndroid Build Coastguard Worker }
134*288bf522SAndroid Build Coastguard Worker 
135*288bf522SAndroid Build Coastguard Worker /// `atrace_init` readies the process for tracing by opening the trace_marker file.
136*288bf522SAndroid Build Coastguard Worker /// Calling any trace function causes this to be run, so calling it is optional.
137*288bf522SAndroid Build Coastguard Worker /// This can be explicitly run to avoid setup delay on first trace function.
atrace_init()138*288bf522SAndroid Build Coastguard Worker pub fn atrace_init() {
139*288bf522SAndroid Build Coastguard Worker     // SAFETY: Call with no arguments.
140*288bf522SAndroid Build Coastguard Worker     unsafe {
141*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_init();
142*288bf522SAndroid Build Coastguard Worker     }
143*288bf522SAndroid Build Coastguard Worker }
144*288bf522SAndroid Build Coastguard Worker 
145*288bf522SAndroid Build Coastguard Worker /// Returns enabled tags as a bitmask.
146*288bf522SAndroid Build Coastguard Worker ///
147*288bf522SAndroid Build Coastguard Worker /// The tag mask is converted into an `AtraceTag`, keeping flags that do not correspond to a tag.
atrace_get_enabled_tags() -> AtraceTag148*288bf522SAndroid Build Coastguard Worker pub fn atrace_get_enabled_tags() -> AtraceTag {
149*288bf522SAndroid Build Coastguard Worker     // SAFETY: Call with no arguments that returns a 64-bit int.
150*288bf522SAndroid Build Coastguard Worker     unsafe { AtraceTag::from_bits_retain(trace_bind::atrace_get_enabled_tags()) }
151*288bf522SAndroid Build Coastguard Worker }
152*288bf522SAndroid Build Coastguard Worker 
153*288bf522SAndroid Build Coastguard Worker /// Test if a given tag is currently enabled.
154*288bf522SAndroid Build Coastguard Worker ///
155*288bf522SAndroid Build Coastguard Worker /// It can be used as a guard condition around more expensive trace calculations.
atrace_is_tag_enabled(tag: AtraceTag) -> bool156*288bf522SAndroid Build Coastguard Worker pub fn atrace_is_tag_enabled(tag: AtraceTag) -> bool {
157*288bf522SAndroid Build Coastguard Worker     // SAFETY: No pointers are transferred.
158*288bf522SAndroid Build Coastguard Worker     unsafe { trace_bind::atrace_is_tag_enabled_wrap(tag.bits()) != 0 }
159*288bf522SAndroid Build Coastguard Worker }
160*288bf522SAndroid Build Coastguard Worker 
161*288bf522SAndroid Build Coastguard Worker /// Trace the beginning of a context. `name` is used to identify the context.
162*288bf522SAndroid Build Coastguard Worker ///
163*288bf522SAndroid Build Coastguard Worker /// This is often used to time function execution.
atrace_begin(tag: AtraceTag, name: &str)164*288bf522SAndroid Build Coastguard Worker pub fn atrace_begin(tag: AtraceTag, name: &str) {
165*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
166*288bf522SAndroid Build Coastguard Worker         return;
167*288bf522SAndroid Build Coastguard Worker     }
168*288bf522SAndroid Build Coastguard Worker 
169*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
170*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
171*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
172*288bf522SAndroid Build Coastguard Worker     unsafe {
173*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_begin_wrap(tag.bits(), name_cstr.as_ptr());
174*288bf522SAndroid Build Coastguard Worker     }
175*288bf522SAndroid Build Coastguard Worker }
176*288bf522SAndroid Build Coastguard Worker 
177*288bf522SAndroid Build Coastguard Worker /// Trace the end of a context.
178*288bf522SAndroid Build Coastguard Worker ///
179*288bf522SAndroid Build Coastguard Worker /// This should match up (and occur after) a corresponding `atrace_begin`.
atrace_end(tag: AtraceTag)180*288bf522SAndroid Build Coastguard Worker pub fn atrace_end(tag: AtraceTag) {
181*288bf522SAndroid Build Coastguard Worker     // SAFETY: No pointers are transferred.
182*288bf522SAndroid Build Coastguard Worker     unsafe {
183*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_end_wrap(tag.bits());
184*288bf522SAndroid Build Coastguard Worker     }
185*288bf522SAndroid Build Coastguard Worker }
186*288bf522SAndroid Build Coastguard Worker 
187*288bf522SAndroid Build Coastguard Worker /// Trace the beginning of an asynchronous event. Unlike `atrace_begin`/`atrace_end` contexts,
188*288bf522SAndroid Build Coastguard Worker /// asynchronous events do not need to be nested.
189*288bf522SAndroid Build Coastguard Worker ///
190*288bf522SAndroid Build Coastguard Worker /// The name describes the event, and the cookie provides a unique identifier for distinguishing
191*288bf522SAndroid Build Coastguard Worker /// simultaneous events.
192*288bf522SAndroid Build Coastguard Worker ///
193*288bf522SAndroid Build Coastguard Worker /// The name and cookie used to begin an event must be used to end it.
atrace_async_begin(tag: AtraceTag, name: &str, cookie: i32)194*288bf522SAndroid Build Coastguard Worker pub fn atrace_async_begin(tag: AtraceTag, name: &str, cookie: i32) {
195*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
196*288bf522SAndroid Build Coastguard Worker         return;
197*288bf522SAndroid Build Coastguard Worker     }
198*288bf522SAndroid Build Coastguard Worker 
199*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
200*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
201*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
202*288bf522SAndroid Build Coastguard Worker     unsafe {
203*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_async_begin_wrap(tag.bits(), name_cstr.as_ptr(), cookie);
204*288bf522SAndroid Build Coastguard Worker     }
205*288bf522SAndroid Build Coastguard Worker }
206*288bf522SAndroid Build Coastguard Worker 
207*288bf522SAndroid Build Coastguard Worker /// Trace the end of an asynchronous event.
208*288bf522SAndroid Build Coastguard Worker ///
209*288bf522SAndroid Build Coastguard Worker /// This should have a corresponding `atrace_async_begin`.
atrace_async_end(tag: AtraceTag, name: &str, cookie: i32)210*288bf522SAndroid Build Coastguard Worker pub fn atrace_async_end(tag: AtraceTag, name: &str, cookie: i32) {
211*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
212*288bf522SAndroid Build Coastguard Worker         return;
213*288bf522SAndroid Build Coastguard Worker     }
214*288bf522SAndroid Build Coastguard Worker 
215*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
216*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
217*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
218*288bf522SAndroid Build Coastguard Worker     unsafe {
219*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_async_end_wrap(tag.bits(), name_cstr.as_ptr(), cookie);
220*288bf522SAndroid Build Coastguard Worker     }
221*288bf522SAndroid Build Coastguard Worker }
222*288bf522SAndroid Build Coastguard Worker 
223*288bf522SAndroid Build Coastguard Worker /// Trace the beginning of an asynchronous event.
224*288bf522SAndroid Build Coastguard Worker ///
225*288bf522SAndroid Build Coastguard Worker /// In addition to the name and a cookie as in `atrace_async_begin`/`atrace_async_end`, a track name
226*288bf522SAndroid Build Coastguard Worker /// argument is provided, which is the name of the row where this async event should be recorded.
227*288bf522SAndroid Build Coastguard Worker ///
228*288bf522SAndroid Build Coastguard Worker /// The track name and cookie used to begin an event must be used to end it.
229*288bf522SAndroid Build Coastguard Worker ///
230*288bf522SAndroid Build Coastguard Worker /// The cookie here must be unique on the track_name level, not the name level.
atrace_async_for_track_begin(tag: AtraceTag, track_name: &str, name: &str, cookie: i32)231*288bf522SAndroid Build Coastguard Worker pub fn atrace_async_for_track_begin(tag: AtraceTag, track_name: &str, name: &str, cookie: i32) {
232*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
233*288bf522SAndroid Build Coastguard Worker         return;
234*288bf522SAndroid Build Coastguard Worker     }
235*288bf522SAndroid Build Coastguard Worker 
236*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
237*288bf522SAndroid Build Coastguard Worker     let track_name_cstr = CString::new(track_name.as_bytes()).expect("CString::new failed");
238*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
239*288bf522SAndroid Build Coastguard Worker     // The passed strings are guaranteed to be null-terminated by CString.
240*288bf522SAndroid Build Coastguard Worker     unsafe {
241*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_async_for_track_begin_wrap(
242*288bf522SAndroid Build Coastguard Worker             tag.bits(),
243*288bf522SAndroid Build Coastguard Worker             track_name_cstr.as_ptr(),
244*288bf522SAndroid Build Coastguard Worker             name_cstr.as_ptr(),
245*288bf522SAndroid Build Coastguard Worker             cookie,
246*288bf522SAndroid Build Coastguard Worker         );
247*288bf522SAndroid Build Coastguard Worker     }
248*288bf522SAndroid Build Coastguard Worker }
249*288bf522SAndroid Build Coastguard Worker 
250*288bf522SAndroid Build Coastguard Worker /// Trace the end of an asynchronous event.
251*288bf522SAndroid Build Coastguard Worker ///
252*288bf522SAndroid Build Coastguard Worker /// This should correspond to a previous `atrace_async_for_track_begin`.
atrace_async_for_track_end(tag: AtraceTag, track_name: &str, cookie: i32)253*288bf522SAndroid Build Coastguard Worker pub fn atrace_async_for_track_end(tag: AtraceTag, track_name: &str, cookie: i32) {
254*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
255*288bf522SAndroid Build Coastguard Worker         return;
256*288bf522SAndroid Build Coastguard Worker     }
257*288bf522SAndroid Build Coastguard Worker 
258*288bf522SAndroid Build Coastguard Worker     let track_name_cstr = CString::new(track_name.as_bytes()).expect("CString::new failed");
259*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
260*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
261*288bf522SAndroid Build Coastguard Worker     unsafe {
262*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_async_for_track_end_wrap(tag.bits(), track_name_cstr.as_ptr(), cookie);
263*288bf522SAndroid Build Coastguard Worker     }
264*288bf522SAndroid Build Coastguard Worker }
265*288bf522SAndroid Build Coastguard Worker 
266*288bf522SAndroid Build Coastguard Worker /// Trace an instantaneous context. `name` is used to identify the context.
267*288bf522SAndroid Build Coastguard Worker ///
268*288bf522SAndroid Build Coastguard Worker /// An "instant" is an event with no defined duration. Visually is displayed like a single marker
269*288bf522SAndroid Build Coastguard Worker /// in the timeline (rather than a span, in the case of begin/end events).
270*288bf522SAndroid Build Coastguard Worker ///
271*288bf522SAndroid Build Coastguard Worker /// By default, instant events are added into a dedicated track that has the same name of the event.
272*288bf522SAndroid Build Coastguard Worker /// Use `atrace_instant_for_track` to put different instant events into the same timeline track/row.
atrace_instant(tag: AtraceTag, name: &str)273*288bf522SAndroid Build Coastguard Worker pub fn atrace_instant(tag: AtraceTag, name: &str) {
274*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
275*288bf522SAndroid Build Coastguard Worker         return;
276*288bf522SAndroid Build Coastguard Worker     }
277*288bf522SAndroid Build Coastguard Worker 
278*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
279*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
280*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
281*288bf522SAndroid Build Coastguard Worker     unsafe {
282*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_instant_wrap(tag.bits(), name_cstr.as_ptr());
283*288bf522SAndroid Build Coastguard Worker     }
284*288bf522SAndroid Build Coastguard Worker }
285*288bf522SAndroid Build Coastguard Worker 
286*288bf522SAndroid Build Coastguard Worker /// Trace an instantaneous context. `name` is used to identify the context. `track_name` is the name
287*288bf522SAndroid Build Coastguard Worker /// of the row where the event should be recorded.
288*288bf522SAndroid Build Coastguard Worker ///
289*288bf522SAndroid Build Coastguard Worker /// An "instant" is an event with no defined duration. Visually is displayed like a single marker
290*288bf522SAndroid Build Coastguard Worker /// in the timeline (rather than a span, in the case of begin/end events).
atrace_instant_for_track(tag: AtraceTag, track_name: &str, name: &str)291*288bf522SAndroid Build Coastguard Worker pub fn atrace_instant_for_track(tag: AtraceTag, track_name: &str, name: &str) {
292*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
293*288bf522SAndroid Build Coastguard Worker         return;
294*288bf522SAndroid Build Coastguard Worker     }
295*288bf522SAndroid Build Coastguard Worker 
296*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
297*288bf522SAndroid Build Coastguard Worker     let track_name_cstr = CString::new(track_name.as_bytes()).expect("CString::new failed");
298*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
299*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
300*288bf522SAndroid Build Coastguard Worker     unsafe {
301*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_instant_for_track_wrap(
302*288bf522SAndroid Build Coastguard Worker             tag.bits(),
303*288bf522SAndroid Build Coastguard Worker             track_name_cstr.as_ptr(),
304*288bf522SAndroid Build Coastguard Worker             name_cstr.as_ptr(),
305*288bf522SAndroid Build Coastguard Worker         );
306*288bf522SAndroid Build Coastguard Worker     }
307*288bf522SAndroid Build Coastguard Worker }
308*288bf522SAndroid Build Coastguard Worker 
309*288bf522SAndroid Build Coastguard Worker /// Traces an integer counter value. `name` is used to identify the counter.
310*288bf522SAndroid Build Coastguard Worker ///
311*288bf522SAndroid Build Coastguard Worker /// This can be used to track how a value changes over time.
atrace_int(tag: AtraceTag, name: &str, value: i32)312*288bf522SAndroid Build Coastguard Worker pub fn atrace_int(tag: AtraceTag, name: &str, value: i32) {
313*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
314*288bf522SAndroid Build Coastguard Worker         return;
315*288bf522SAndroid Build Coastguard Worker     }
316*288bf522SAndroid Build Coastguard Worker 
317*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
318*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
319*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
320*288bf522SAndroid Build Coastguard Worker     unsafe {
321*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_int_wrap(tag.bits(), name_cstr.as_ptr(), value);
322*288bf522SAndroid Build Coastguard Worker     }
323*288bf522SAndroid Build Coastguard Worker }
324*288bf522SAndroid Build Coastguard Worker 
325*288bf522SAndroid Build Coastguard Worker /// Traces a 64-bit integer counter value. `name` is used to identify the counter.
326*288bf522SAndroid Build Coastguard Worker ///
327*288bf522SAndroid Build Coastguard Worker /// This can be used to track how a value changes over time.
atrace_int64(tag: AtraceTag, name: &str, value: i64)328*288bf522SAndroid Build Coastguard Worker pub fn atrace_int64(tag: AtraceTag, name: &str, value: i64) {
329*288bf522SAndroid Build Coastguard Worker     if !atrace_is_tag_enabled(tag) {
330*288bf522SAndroid Build Coastguard Worker         return;
331*288bf522SAndroid Build Coastguard Worker     }
332*288bf522SAndroid Build Coastguard Worker 
333*288bf522SAndroid Build Coastguard Worker     let name_cstr = CString::new(name.as_bytes()).expect("CString::new failed");
334*288bf522SAndroid Build Coastguard Worker     // SAFETY: The function does not accept the pointer ownership, only reads its contents.
335*288bf522SAndroid Build Coastguard Worker     // The passed string is guaranteed to be null-terminated by CString.
336*288bf522SAndroid Build Coastguard Worker     unsafe {
337*288bf522SAndroid Build Coastguard Worker         trace_bind::atrace_int64_wrap(tag.bits(), name_cstr.as_ptr(), value);
338*288bf522SAndroid Build Coastguard Worker     }
339*288bf522SAndroid Build Coastguard Worker }
340*288bf522SAndroid Build Coastguard Worker 
341*288bf522SAndroid Build Coastguard Worker #[cfg(test)]
342*288bf522SAndroid Build Coastguard Worker use self::tests::mock_atrace as trace_bind;
343*288bf522SAndroid Build Coastguard Worker 
344*288bf522SAndroid Build Coastguard Worker #[cfg(test)]
345*288bf522SAndroid Build Coastguard Worker mod tests {
346*288bf522SAndroid Build Coastguard Worker     use super::*;
347*288bf522SAndroid Build Coastguard Worker 
348*288bf522SAndroid Build Coastguard Worker     use std::ffi::CStr;
349*288bf522SAndroid Build Coastguard Worker     use std::os::raw::c_char;
350*288bf522SAndroid Build Coastguard Worker 
351*288bf522SAndroid Build Coastguard Worker     /// Utilities to mock ATrace bindings.
352*288bf522SAndroid Build Coastguard Worker     ///
353*288bf522SAndroid Build Coastguard Worker     /// Normally, for behavior-driven testing we focus on the outcomes of the functions rather than
354*288bf522SAndroid Build Coastguard Worker     /// calls into bindings. However, since the purpose of the library is to forward data into
355*288bf522SAndroid Build Coastguard Worker     /// the underlying implementation (which we assume to be correct), that's what we test.
356*288bf522SAndroid Build Coastguard Worker     pub mod mock_atrace {
357*288bf522SAndroid Build Coastguard Worker         use std::cell::RefCell;
358*288bf522SAndroid Build Coastguard Worker         use std::os::raw::c_char;
359*288bf522SAndroid Build Coastguard Worker 
360*288bf522SAndroid Build Coastguard Worker         /// Contains logic to check binding calls.
361*288bf522SAndroid Build Coastguard Worker         /// Implement this trait in the test with mocking logic and checks in implemented functions.
362*288bf522SAndroid Build Coastguard Worker         /// Default implementations panic.
363*288bf522SAndroid Build Coastguard Worker         pub trait ATraceMocker {
atrace_set_tracing_enabled(&mut self, _enabled: bool)364*288bf522SAndroid Build Coastguard Worker             fn atrace_set_tracing_enabled(&mut self, _enabled: bool) {
365*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
366*288bf522SAndroid Build Coastguard Worker             }
atrace_init(&mut self)367*288bf522SAndroid Build Coastguard Worker             fn atrace_init(&mut self) {
368*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
369*288bf522SAndroid Build Coastguard Worker             }
atrace_get_enabled_tags(&mut self) -> u64370*288bf522SAndroid Build Coastguard Worker             fn atrace_get_enabled_tags(&mut self) -> u64 {
371*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
372*288bf522SAndroid Build Coastguard Worker             }
atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64373*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
374*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
375*288bf522SAndroid Build Coastguard Worker             }
atrace_begin_wrap(&mut self, _tag: u64, _name: *const c_char)376*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, _tag: u64, _name: *const c_char) {
377*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
378*288bf522SAndroid Build Coastguard Worker             }
atrace_end_wrap(&mut self, _tag: u64)379*288bf522SAndroid Build Coastguard Worker             fn atrace_end_wrap(&mut self, _tag: u64) {
380*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
381*288bf522SAndroid Build Coastguard Worker             }
atrace_async_begin_wrap(&mut self, _tag: u64, _name: *const c_char, _cookie: i32)382*288bf522SAndroid Build Coastguard Worker             fn atrace_async_begin_wrap(&mut self, _tag: u64, _name: *const c_char, _cookie: i32) {
383*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
384*288bf522SAndroid Build Coastguard Worker             }
atrace_async_end_wrap(&mut self, _tag: u64, _name: *const c_char, _cookie: i32)385*288bf522SAndroid Build Coastguard Worker             fn atrace_async_end_wrap(&mut self, _tag: u64, _name: *const c_char, _cookie: i32) {
386*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
387*288bf522SAndroid Build Coastguard Worker             }
atrace_async_for_track_begin_wrap( &mut self, _tag: u64, _track_name: *const c_char, _name: *const c_char, _cookie: i32, )388*288bf522SAndroid Build Coastguard Worker             fn atrace_async_for_track_begin_wrap(
389*288bf522SAndroid Build Coastguard Worker                 &mut self,
390*288bf522SAndroid Build Coastguard Worker                 _tag: u64,
391*288bf522SAndroid Build Coastguard Worker                 _track_name: *const c_char,
392*288bf522SAndroid Build Coastguard Worker                 _name: *const c_char,
393*288bf522SAndroid Build Coastguard Worker                 _cookie: i32,
394*288bf522SAndroid Build Coastguard Worker             ) {
395*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
396*288bf522SAndroid Build Coastguard Worker             }
atrace_async_for_track_end_wrap( &mut self, _tag: u64, _track_name: *const c_char, _cookie: i32, )397*288bf522SAndroid Build Coastguard Worker             fn atrace_async_for_track_end_wrap(
398*288bf522SAndroid Build Coastguard Worker                 &mut self,
399*288bf522SAndroid Build Coastguard Worker                 _tag: u64,
400*288bf522SAndroid Build Coastguard Worker                 _track_name: *const c_char,
401*288bf522SAndroid Build Coastguard Worker                 _cookie: i32,
402*288bf522SAndroid Build Coastguard Worker             ) {
403*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
404*288bf522SAndroid Build Coastguard Worker             }
atrace_instant_wrap(&mut self, _tag: u64, _name: *const c_char)405*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_wrap(&mut self, _tag: u64, _name: *const c_char) {
406*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
407*288bf522SAndroid Build Coastguard Worker             }
atrace_instant_for_track_wrap( &mut self, _tag: u64, _track_name: *const c_char, _name: *const c_char, )408*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_for_track_wrap(
409*288bf522SAndroid Build Coastguard Worker                 &mut self,
410*288bf522SAndroid Build Coastguard Worker                 _tag: u64,
411*288bf522SAndroid Build Coastguard Worker                 _track_name: *const c_char,
412*288bf522SAndroid Build Coastguard Worker                 _name: *const c_char,
413*288bf522SAndroid Build Coastguard Worker             ) {
414*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
415*288bf522SAndroid Build Coastguard Worker             }
atrace_int_wrap(&mut self, _tag: u64, _name: *const c_char, _value: i32)416*288bf522SAndroid Build Coastguard Worker             fn atrace_int_wrap(&mut self, _tag: u64, _name: *const c_char, _value: i32) {
417*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
418*288bf522SAndroid Build Coastguard Worker             }
atrace_int64_wrap(&mut self, _tag: u64, _name: *const c_char, _value: i64)419*288bf522SAndroid Build Coastguard Worker             fn atrace_int64_wrap(&mut self, _tag: u64, _name: *const c_char, _value: i64) {
420*288bf522SAndroid Build Coastguard Worker                 panic!("Unexpected call");
421*288bf522SAndroid Build Coastguard Worker             }
422*288bf522SAndroid Build Coastguard Worker 
423*288bf522SAndroid Build Coastguard Worker             /// This method should contain checks to be performed at the end of the test.
finish(&self)424*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {}
425*288bf522SAndroid Build Coastguard Worker         }
426*288bf522SAndroid Build Coastguard Worker 
427*288bf522SAndroid Build Coastguard Worker         struct DefaultMocker;
428*288bf522SAndroid Build Coastguard Worker         impl ATraceMocker for DefaultMocker {}
429*288bf522SAndroid Build Coastguard Worker 
430*288bf522SAndroid Build Coastguard Worker         // Global mock object is thread-local, so that the tests can run safely in parallel.
431*288bf522SAndroid Build Coastguard Worker         thread_local!(static MOCKER: RefCell<Box<dyn ATraceMocker>> = RefCell::new(Box::new(DefaultMocker{})));
432*288bf522SAndroid Build Coastguard Worker 
433*288bf522SAndroid Build Coastguard Worker         /// Sets the global mock object.
set_mocker(mocker: Box<dyn ATraceMocker>)434*288bf522SAndroid Build Coastguard Worker         fn set_mocker(mocker: Box<dyn ATraceMocker>) {
435*288bf522SAndroid Build Coastguard Worker             MOCKER.with(|m| *m.borrow_mut() = mocker)
436*288bf522SAndroid Build Coastguard Worker         }
437*288bf522SAndroid Build Coastguard Worker 
438*288bf522SAndroid Build Coastguard Worker         /// Calls the passed method `f` with a mutable reference to the global mock object.
439*288bf522SAndroid Build Coastguard Worker         /// Example:
440*288bf522SAndroid Build Coastguard Worker         /// ```
441*288bf522SAndroid Build Coastguard Worker         /// with_mocker(|mocker| mocker.atrace_begin_wrap(tag, name))
442*288bf522SAndroid Build Coastguard Worker         /// ```
with_mocker<F, R>(f: F) -> R where F: FnOnce(&mut dyn ATraceMocker) -> R,443*288bf522SAndroid Build Coastguard Worker         fn with_mocker<F, R>(f: F) -> R
444*288bf522SAndroid Build Coastguard Worker         where
445*288bf522SAndroid Build Coastguard Worker             F: FnOnce(&mut dyn ATraceMocker) -> R,
446*288bf522SAndroid Build Coastguard Worker         {
447*288bf522SAndroid Build Coastguard Worker             MOCKER.with(|m| f(m.borrow_mut().as_mut()))
448*288bf522SAndroid Build Coastguard Worker         }
449*288bf522SAndroid Build Coastguard Worker 
450*288bf522SAndroid Build Coastguard Worker         /// Finish the test and perform final checks in the mocker.
451*288bf522SAndroid Build Coastguard Worker         /// Calls `finish()` on the global mocker.
452*288bf522SAndroid Build Coastguard Worker         ///
453*288bf522SAndroid Build Coastguard Worker         /// Needs to be called manually at the end of each test that uses mocks.
454*288bf522SAndroid Build Coastguard Worker         ///
455*288bf522SAndroid Build Coastguard Worker         /// May panic, so it can not be called in `drop()` methods,
456*288bf522SAndroid Build Coastguard Worker         /// since it may result in double panic.
mocker_finish()457*288bf522SAndroid Build Coastguard Worker         pub fn mocker_finish() {
458*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.finish())
459*288bf522SAndroid Build Coastguard Worker         }
460*288bf522SAndroid Build Coastguard Worker 
461*288bf522SAndroid Build Coastguard Worker         /// RAII guard that resets the mock to the default implementation.
462*288bf522SAndroid Build Coastguard Worker         pub struct MockerGuard;
463*288bf522SAndroid Build Coastguard Worker         impl Drop for MockerGuard {
drop(&mut self)464*288bf522SAndroid Build Coastguard Worker             fn drop(&mut self) {
465*288bf522SAndroid Build Coastguard Worker                 set_mocker(Box::new(DefaultMocker {}));
466*288bf522SAndroid Build Coastguard Worker             }
467*288bf522SAndroid Build Coastguard Worker         }
468*288bf522SAndroid Build Coastguard Worker 
469*288bf522SAndroid Build Coastguard Worker         /// Sets the mock object for the duration of the scope.
470*288bf522SAndroid Build Coastguard Worker         ///
471*288bf522SAndroid Build Coastguard Worker         /// Returns a RAII guard that resets the mock back to default on destruction.
set_scoped_mocker<T: ATraceMocker + 'static>(m: T) -> MockerGuard472*288bf522SAndroid Build Coastguard Worker         pub fn set_scoped_mocker<T: ATraceMocker + 'static>(m: T) -> MockerGuard {
473*288bf522SAndroid Build Coastguard Worker             set_mocker(Box::new(m));
474*288bf522SAndroid Build Coastguard Worker             MockerGuard {}
475*288bf522SAndroid Build Coastguard Worker         }
476*288bf522SAndroid Build Coastguard Worker 
477*288bf522SAndroid Build Coastguard Worker         // Wrapped functions that forward calls into mocker.
478*288bf522SAndroid Build Coastguard Worker         // The functions are marked as unsafe to match the binding interface, won't compile otherwise.
479*288bf522SAndroid Build Coastguard Worker         // The mocker methods themselves are not marked as unsafe.
480*288bf522SAndroid Build Coastguard Worker 
atrace_set_tracing_enabled(enabled: bool)481*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_set_tracing_enabled(enabled: bool) {
482*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_set_tracing_enabled(enabled))
483*288bf522SAndroid Build Coastguard Worker         }
atrace_init()484*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_init() {
485*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_init())
486*288bf522SAndroid Build Coastguard Worker         }
atrace_get_enabled_tags() -> u64487*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_get_enabled_tags() -> u64 {
488*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_get_enabled_tags())
489*288bf522SAndroid Build Coastguard Worker         }
atrace_is_tag_enabled_wrap(tag: u64) -> u64490*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_is_tag_enabled_wrap(tag: u64) -> u64 {
491*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_is_tag_enabled_wrap(tag))
492*288bf522SAndroid Build Coastguard Worker         }
atrace_begin_wrap(tag: u64, name: *const c_char)493*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_begin_wrap(tag: u64, name: *const c_char) {
494*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_begin_wrap(tag, name))
495*288bf522SAndroid Build Coastguard Worker         }
atrace_end_wrap(tag: u64)496*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_end_wrap(tag: u64) {
497*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_end_wrap(tag))
498*288bf522SAndroid Build Coastguard Worker         }
atrace_async_begin_wrap(tag: u64, name: *const c_char, cookie: i32)499*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_async_begin_wrap(tag: u64, name: *const c_char, cookie: i32) {
500*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_async_begin_wrap(tag, name, cookie))
501*288bf522SAndroid Build Coastguard Worker         }
atrace_async_end_wrap(tag: u64, name: *const c_char, cookie: i32)502*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_async_end_wrap(tag: u64, name: *const c_char, cookie: i32) {
503*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_async_end_wrap(tag, name, cookie))
504*288bf522SAndroid Build Coastguard Worker         }
atrace_async_for_track_begin_wrap( tag: u64, track_name: *const c_char, name: *const c_char, cookie: i32, )505*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_async_for_track_begin_wrap(
506*288bf522SAndroid Build Coastguard Worker             tag: u64,
507*288bf522SAndroid Build Coastguard Worker             track_name: *const c_char,
508*288bf522SAndroid Build Coastguard Worker             name: *const c_char,
509*288bf522SAndroid Build Coastguard Worker             cookie: i32,
510*288bf522SAndroid Build Coastguard Worker         ) {
511*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_async_for_track_begin_wrap(tag, track_name, name, cookie))
512*288bf522SAndroid Build Coastguard Worker         }
atrace_async_for_track_end_wrap( tag: u64, track_name: *const c_char, cookie: i32, )513*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_async_for_track_end_wrap(
514*288bf522SAndroid Build Coastguard Worker             tag: u64,
515*288bf522SAndroid Build Coastguard Worker             track_name: *const c_char,
516*288bf522SAndroid Build Coastguard Worker             cookie: i32,
517*288bf522SAndroid Build Coastguard Worker         ) {
518*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_async_for_track_end_wrap(tag, track_name, cookie))
519*288bf522SAndroid Build Coastguard Worker         }
atrace_instant_wrap(tag: u64, name: *const c_char)520*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_instant_wrap(tag: u64, name: *const c_char) {
521*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_instant_wrap(tag, name))
522*288bf522SAndroid Build Coastguard Worker         }
atrace_instant_for_track_wrap( tag: u64, track_name: *const c_char, name: *const c_char, )523*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_instant_for_track_wrap(
524*288bf522SAndroid Build Coastguard Worker             tag: u64,
525*288bf522SAndroid Build Coastguard Worker             track_name: *const c_char,
526*288bf522SAndroid Build Coastguard Worker             name: *const c_char,
527*288bf522SAndroid Build Coastguard Worker         ) {
528*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_instant_for_track_wrap(tag, track_name, name))
529*288bf522SAndroid Build Coastguard Worker         }
atrace_int_wrap(tag: u64, name: *const c_char, value: i32)530*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_int_wrap(tag: u64, name: *const c_char, value: i32) {
531*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_int_wrap(tag, name, value))
532*288bf522SAndroid Build Coastguard Worker         }
atrace_int64_wrap(tag: u64, name: *const c_char, value: i64)533*288bf522SAndroid Build Coastguard Worker         pub unsafe fn atrace_int64_wrap(tag: u64, name: *const c_char, value: i64) {
534*288bf522SAndroid Build Coastguard Worker             with_mocker(|m| m.atrace_int64_wrap(tag, name, value))
535*288bf522SAndroid Build Coastguard Worker         }
536*288bf522SAndroid Build Coastguard Worker     }
537*288bf522SAndroid Build Coastguard Worker 
538*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_set_tracing_enabled()539*288bf522SAndroid Build Coastguard Worker     fn forwards_set_tracing_enabled() {
540*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
541*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
542*288bf522SAndroid Build Coastguard Worker             set_tracing_enabled_count: u32,
543*288bf522SAndroid Build Coastguard Worker         }
544*288bf522SAndroid Build Coastguard Worker 
545*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
546*288bf522SAndroid Build Coastguard Worker             fn atrace_set_tracing_enabled(&mut self, enabled: bool) {
547*288bf522SAndroid Build Coastguard Worker                 self.set_tracing_enabled_count += 1;
548*288bf522SAndroid Build Coastguard Worker                 assert!(self.set_tracing_enabled_count < 2);
549*288bf522SAndroid Build Coastguard Worker                 assert!(enabled);
550*288bf522SAndroid Build Coastguard Worker             }
551*288bf522SAndroid Build Coastguard Worker 
552*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
553*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.set_tracing_enabled_count, 1);
554*288bf522SAndroid Build Coastguard Worker             }
555*288bf522SAndroid Build Coastguard Worker         }
556*288bf522SAndroid Build Coastguard Worker 
557*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
558*288bf522SAndroid Build Coastguard Worker 
559*288bf522SAndroid Build Coastguard Worker         atrace_set_tracing_enabled(true);
560*288bf522SAndroid Build Coastguard Worker 
561*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
562*288bf522SAndroid Build Coastguard Worker     }
563*288bf522SAndroid Build Coastguard Worker 
564*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_atrace_init()565*288bf522SAndroid Build Coastguard Worker     fn forwards_atrace_init() {
566*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
567*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
568*288bf522SAndroid Build Coastguard Worker             init_count: u32,
569*288bf522SAndroid Build Coastguard Worker         }
570*288bf522SAndroid Build Coastguard Worker 
571*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
572*288bf522SAndroid Build Coastguard Worker             fn atrace_init(&mut self) {
573*288bf522SAndroid Build Coastguard Worker                 self.init_count += 1;
574*288bf522SAndroid Build Coastguard Worker                 assert!(self.init_count < 2);
575*288bf522SAndroid Build Coastguard Worker             }
576*288bf522SAndroid Build Coastguard Worker 
577*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
578*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.init_count, 1);
579*288bf522SAndroid Build Coastguard Worker             }
580*288bf522SAndroid Build Coastguard Worker         }
581*288bf522SAndroid Build Coastguard Worker 
582*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
583*288bf522SAndroid Build Coastguard Worker 
584*288bf522SAndroid Build Coastguard Worker         atrace_init();
585*288bf522SAndroid Build Coastguard Worker 
586*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
587*288bf522SAndroid Build Coastguard Worker     }
588*288bf522SAndroid Build Coastguard Worker 
589*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_atrace_get_enabled_tags()590*288bf522SAndroid Build Coastguard Worker     fn forwards_atrace_get_enabled_tags() {
591*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
592*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
593*288bf522SAndroid Build Coastguard Worker             get_enabled_tags_count: u32,
594*288bf522SAndroid Build Coastguard Worker         }
595*288bf522SAndroid Build Coastguard Worker 
596*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
597*288bf522SAndroid Build Coastguard Worker             fn atrace_get_enabled_tags(&mut self) -> u64 {
598*288bf522SAndroid Build Coastguard Worker                 self.get_enabled_tags_count += 1;
599*288bf522SAndroid Build Coastguard Worker                 assert!(self.get_enabled_tags_count < 2);
600*288bf522SAndroid Build Coastguard Worker                 (cutils_trace_bindgen::ATRACE_TAG_HAL | cutils_trace_bindgen::ATRACE_TAG_GRAPHICS)
601*288bf522SAndroid Build Coastguard Worker                     as u64
602*288bf522SAndroid Build Coastguard Worker             }
603*288bf522SAndroid Build Coastguard Worker 
604*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
605*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.get_enabled_tags_count, 1);
606*288bf522SAndroid Build Coastguard Worker             }
607*288bf522SAndroid Build Coastguard Worker         }
608*288bf522SAndroid Build Coastguard Worker 
609*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
610*288bf522SAndroid Build Coastguard Worker 
611*288bf522SAndroid Build Coastguard Worker         let res = atrace_get_enabled_tags();
612*288bf522SAndroid Build Coastguard Worker         assert_eq!(res, AtraceTag::Hal | AtraceTag::Graphics);
613*288bf522SAndroid Build Coastguard Worker 
614*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
615*288bf522SAndroid Build Coastguard Worker     }
616*288bf522SAndroid Build Coastguard Worker 
617*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_begin()618*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_begin() {
619*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
620*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
621*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
622*288bf522SAndroid Build Coastguard Worker         }
623*288bf522SAndroid Build Coastguard Worker 
624*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
625*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
626*288bf522SAndroid Build Coastguard Worker                 1
627*288bf522SAndroid Build Coastguard Worker             }
628*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, tag: u64, name: *const c_char) {
629*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
630*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
631*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
632*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
633*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
634*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
635*288bf522SAndroid Build Coastguard Worker                 unsafe {
636*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
637*288bf522SAndroid Build Coastguard Worker                 }
638*288bf522SAndroid Build Coastguard Worker             }
639*288bf522SAndroid Build Coastguard Worker 
640*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
641*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
642*288bf522SAndroid Build Coastguard Worker             }
643*288bf522SAndroid Build Coastguard Worker         }
644*288bf522SAndroid Build Coastguard Worker 
645*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
646*288bf522SAndroid Build Coastguard Worker 
647*288bf522SAndroid Build Coastguard Worker         atrace_begin(AtraceTag::App, "Test Name");
648*288bf522SAndroid Build Coastguard Worker 
649*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
650*288bf522SAndroid Build Coastguard Worker     }
651*288bf522SAndroid Build Coastguard Worker 
652*288bf522SAndroid Build Coastguard Worker     #[test]
trace_begin_not_called_with_disabled_tag()653*288bf522SAndroid Build Coastguard Worker     fn trace_begin_not_called_with_disabled_tag() {
654*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
655*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
656*288bf522SAndroid Build Coastguard Worker             is_tag_enabled_count: u32,
657*288bf522SAndroid Build Coastguard Worker         }
658*288bf522SAndroid Build Coastguard Worker 
659*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
660*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
661*288bf522SAndroid Build Coastguard Worker                 self.is_tag_enabled_count += 1;
662*288bf522SAndroid Build Coastguard Worker                 assert!(self.is_tag_enabled_count < 2);
663*288bf522SAndroid Build Coastguard Worker                 0
664*288bf522SAndroid Build Coastguard Worker             }
665*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, _tag: u64, _name: *const c_char) {
666*288bf522SAndroid Build Coastguard Worker                 panic!("Begin should not be called with disabled tag.")
667*288bf522SAndroid Build Coastguard Worker             }
668*288bf522SAndroid Build Coastguard Worker 
669*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
670*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.is_tag_enabled_count, 1);
671*288bf522SAndroid Build Coastguard Worker             }
672*288bf522SAndroid Build Coastguard Worker         }
673*288bf522SAndroid Build Coastguard Worker 
674*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
675*288bf522SAndroid Build Coastguard Worker 
676*288bf522SAndroid Build Coastguard Worker         atrace_begin(AtraceTag::App, "Ignore me");
677*288bf522SAndroid Build Coastguard Worker 
678*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
679*288bf522SAndroid Build Coastguard Worker     }
680*288bf522SAndroid Build Coastguard Worker 
681*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_end()682*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_end() {
683*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
684*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
685*288bf522SAndroid Build Coastguard Worker             end_count: u32,
686*288bf522SAndroid Build Coastguard Worker         }
687*288bf522SAndroid Build Coastguard Worker 
688*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
689*288bf522SAndroid Build Coastguard Worker             fn atrace_end_wrap(&mut self, tag: u64) {
690*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
691*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
692*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
693*288bf522SAndroid Build Coastguard Worker             }
694*288bf522SAndroid Build Coastguard Worker 
695*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
696*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
697*288bf522SAndroid Build Coastguard Worker             }
698*288bf522SAndroid Build Coastguard Worker         }
699*288bf522SAndroid Build Coastguard Worker 
700*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
701*288bf522SAndroid Build Coastguard Worker 
702*288bf522SAndroid Build Coastguard Worker         atrace_end(AtraceTag::App);
703*288bf522SAndroid Build Coastguard Worker 
704*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
705*288bf522SAndroid Build Coastguard Worker     }
706*288bf522SAndroid Build Coastguard Worker 
707*288bf522SAndroid Build Coastguard Worker     #[test]
can_combine_tags()708*288bf522SAndroid Build Coastguard Worker     fn can_combine_tags() {
709*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
710*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
711*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
712*288bf522SAndroid Build Coastguard Worker         }
713*288bf522SAndroid Build Coastguard Worker 
714*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
715*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
716*288bf522SAndroid Build Coastguard Worker                 1
717*288bf522SAndroid Build Coastguard Worker             }
718*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, tag: u64, _name: *const c_char) {
719*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
720*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
721*288bf522SAndroid Build Coastguard Worker                 assert_eq!(
722*288bf522SAndroid Build Coastguard Worker                     tag,
723*288bf522SAndroid Build Coastguard Worker                     (cutils_trace_bindgen::ATRACE_TAG_HAL | cutils_trace_bindgen::ATRACE_TAG_CAMERA)
724*288bf522SAndroid Build Coastguard Worker                         as u64
725*288bf522SAndroid Build Coastguard Worker                 );
726*288bf522SAndroid Build Coastguard Worker             }
727*288bf522SAndroid Build Coastguard Worker 
728*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
729*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
730*288bf522SAndroid Build Coastguard Worker             }
731*288bf522SAndroid Build Coastguard Worker         }
732*288bf522SAndroid Build Coastguard Worker 
733*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
734*288bf522SAndroid Build Coastguard Worker 
735*288bf522SAndroid Build Coastguard Worker         atrace_begin(AtraceTag::Hal | AtraceTag::Camera, "foo");
736*288bf522SAndroid Build Coastguard Worker 
737*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
738*288bf522SAndroid Build Coastguard Worker     }
739*288bf522SAndroid Build Coastguard Worker 
740*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_is_tag_enabled()741*288bf522SAndroid Build Coastguard Worker     fn forwards_is_tag_enabled() {
742*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
743*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
744*288bf522SAndroid Build Coastguard Worker             is_tag_enabled_count: u32,
745*288bf522SAndroid Build Coastguard Worker         }
746*288bf522SAndroid Build Coastguard Worker 
747*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
748*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, tag: u64) -> u64 {
749*288bf522SAndroid Build Coastguard Worker                 self.is_tag_enabled_count += 1;
750*288bf522SAndroid Build Coastguard Worker                 assert!(self.is_tag_enabled_count < 2);
751*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_ADB as u64);
752*288bf522SAndroid Build Coastguard Worker                 1
753*288bf522SAndroid Build Coastguard Worker             }
754*288bf522SAndroid Build Coastguard Worker 
755*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
756*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.is_tag_enabled_count, 1);
757*288bf522SAndroid Build Coastguard Worker             }
758*288bf522SAndroid Build Coastguard Worker         }
759*288bf522SAndroid Build Coastguard Worker 
760*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
761*288bf522SAndroid Build Coastguard Worker 
762*288bf522SAndroid Build Coastguard Worker         let res = atrace_is_tag_enabled(AtraceTag::Adb);
763*288bf522SAndroid Build Coastguard Worker         assert!(res);
764*288bf522SAndroid Build Coastguard Worker 
765*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
766*288bf522SAndroid Build Coastguard Worker     }
767*288bf522SAndroid Build Coastguard Worker 
768*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_async_begin()769*288bf522SAndroid Build Coastguard Worker     fn forwards_async_begin() {
770*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
771*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
772*288bf522SAndroid Build Coastguard Worker             async_begin_count: u32,
773*288bf522SAndroid Build Coastguard Worker         }
774*288bf522SAndroid Build Coastguard Worker 
775*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
776*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
777*288bf522SAndroid Build Coastguard Worker                 1
778*288bf522SAndroid Build Coastguard Worker             }
779*288bf522SAndroid Build Coastguard Worker             fn atrace_async_begin_wrap(&mut self, tag: u64, name: *const c_char, cookie: i32) {
780*288bf522SAndroid Build Coastguard Worker                 self.async_begin_count += 1;
781*288bf522SAndroid Build Coastguard Worker                 assert!(self.async_begin_count < 2);
782*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
783*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
784*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
785*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
786*288bf522SAndroid Build Coastguard Worker                 unsafe {
787*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
788*288bf522SAndroid Build Coastguard Worker                 }
789*288bf522SAndroid Build Coastguard Worker                 assert_eq!(cookie, 123);
790*288bf522SAndroid Build Coastguard Worker             }
791*288bf522SAndroid Build Coastguard Worker 
792*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
793*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.async_begin_count, 1);
794*288bf522SAndroid Build Coastguard Worker             }
795*288bf522SAndroid Build Coastguard Worker         }
796*288bf522SAndroid Build Coastguard Worker 
797*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
798*288bf522SAndroid Build Coastguard Worker 
799*288bf522SAndroid Build Coastguard Worker         atrace_async_begin(AtraceTag::App, "Test Name", 123);
800*288bf522SAndroid Build Coastguard Worker 
801*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
802*288bf522SAndroid Build Coastguard Worker     }
803*288bf522SAndroid Build Coastguard Worker 
804*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_async_end()805*288bf522SAndroid Build Coastguard Worker     fn forwards_async_end() {
806*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
807*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
808*288bf522SAndroid Build Coastguard Worker             async_end_count: u32,
809*288bf522SAndroid Build Coastguard Worker         }
810*288bf522SAndroid Build Coastguard Worker 
811*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
812*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
813*288bf522SAndroid Build Coastguard Worker                 1
814*288bf522SAndroid Build Coastguard Worker             }
815*288bf522SAndroid Build Coastguard Worker             fn atrace_async_end_wrap(&mut self, tag: u64, name: *const c_char, cookie: i32) {
816*288bf522SAndroid Build Coastguard Worker                 self.async_end_count += 1;
817*288bf522SAndroid Build Coastguard Worker                 assert!(self.async_end_count < 2);
818*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
819*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
820*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
821*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
822*288bf522SAndroid Build Coastguard Worker                 unsafe {
823*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
824*288bf522SAndroid Build Coastguard Worker                 }
825*288bf522SAndroid Build Coastguard Worker                 assert_eq!(cookie, 123);
826*288bf522SAndroid Build Coastguard Worker             }
827*288bf522SAndroid Build Coastguard Worker 
828*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
829*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.async_end_count, 1);
830*288bf522SAndroid Build Coastguard Worker             }
831*288bf522SAndroid Build Coastguard Worker         }
832*288bf522SAndroid Build Coastguard Worker 
833*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
834*288bf522SAndroid Build Coastguard Worker 
835*288bf522SAndroid Build Coastguard Worker         atrace_async_end(AtraceTag::App, "Test Name", 123);
836*288bf522SAndroid Build Coastguard Worker 
837*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
838*288bf522SAndroid Build Coastguard Worker     }
839*288bf522SAndroid Build Coastguard Worker 
840*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_async_for_track_begin()841*288bf522SAndroid Build Coastguard Worker     fn forwards_async_for_track_begin() {
842*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
843*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
844*288bf522SAndroid Build Coastguard Worker             async_for_track_begin_count: u32,
845*288bf522SAndroid Build Coastguard Worker         }
846*288bf522SAndroid Build Coastguard Worker 
847*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
848*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
849*288bf522SAndroid Build Coastguard Worker                 1
850*288bf522SAndroid Build Coastguard Worker             }
851*288bf522SAndroid Build Coastguard Worker             fn atrace_async_for_track_begin_wrap(
852*288bf522SAndroid Build Coastguard Worker                 &mut self,
853*288bf522SAndroid Build Coastguard Worker                 tag: u64,
854*288bf522SAndroid Build Coastguard Worker                 track_name: *const c_char,
855*288bf522SAndroid Build Coastguard Worker                 name: *const c_char,
856*288bf522SAndroid Build Coastguard Worker                 cookie: i32,
857*288bf522SAndroid Build Coastguard Worker             ) {
858*288bf522SAndroid Build Coastguard Worker                 self.async_for_track_begin_count += 1;
859*288bf522SAndroid Build Coastguard Worker                 assert!(self.async_for_track_begin_count < 2);
860*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
861*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
862*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
863*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
864*288bf522SAndroid Build Coastguard Worker                 unsafe {
865*288bf522SAndroid Build Coastguard Worker                     assert_eq!(
866*288bf522SAndroid Build Coastguard Worker                         CStr::from_ptr(track_name).to_str().expect("to_str failed"),
867*288bf522SAndroid Build Coastguard Worker                         "Track"
868*288bf522SAndroid Build Coastguard Worker                     );
869*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
870*288bf522SAndroid Build Coastguard Worker                 }
871*288bf522SAndroid Build Coastguard Worker                 assert_eq!(cookie, 123);
872*288bf522SAndroid Build Coastguard Worker             }
873*288bf522SAndroid Build Coastguard Worker 
874*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
875*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.async_for_track_begin_count, 1);
876*288bf522SAndroid Build Coastguard Worker             }
877*288bf522SAndroid Build Coastguard Worker         }
878*288bf522SAndroid Build Coastguard Worker 
879*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
880*288bf522SAndroid Build Coastguard Worker 
881*288bf522SAndroid Build Coastguard Worker         atrace_async_for_track_begin(AtraceTag::App, "Track", "Test Name", 123);
882*288bf522SAndroid Build Coastguard Worker 
883*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
884*288bf522SAndroid Build Coastguard Worker     }
885*288bf522SAndroid Build Coastguard Worker 
886*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_async_for_track_end()887*288bf522SAndroid Build Coastguard Worker     fn forwards_async_for_track_end() {
888*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
889*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
890*288bf522SAndroid Build Coastguard Worker             async_for_track_end_count: u32,
891*288bf522SAndroid Build Coastguard Worker         }
892*288bf522SAndroid Build Coastguard Worker 
893*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
894*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
895*288bf522SAndroid Build Coastguard Worker                 1
896*288bf522SAndroid Build Coastguard Worker             }
897*288bf522SAndroid Build Coastguard Worker             fn atrace_async_for_track_end_wrap(
898*288bf522SAndroid Build Coastguard Worker                 &mut self,
899*288bf522SAndroid Build Coastguard Worker                 tag: u64,
900*288bf522SAndroid Build Coastguard Worker                 track_name: *const c_char,
901*288bf522SAndroid Build Coastguard Worker                 cookie: i32,
902*288bf522SAndroid Build Coastguard Worker             ) {
903*288bf522SAndroid Build Coastguard Worker                 self.async_for_track_end_count += 1;
904*288bf522SAndroid Build Coastguard Worker                 assert!(self.async_for_track_end_count < 2);
905*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
906*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
907*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
908*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
909*288bf522SAndroid Build Coastguard Worker                 unsafe {
910*288bf522SAndroid Build Coastguard Worker                     assert_eq!(
911*288bf522SAndroid Build Coastguard Worker                         CStr::from_ptr(track_name).to_str().expect("to_str failed"),
912*288bf522SAndroid Build Coastguard Worker                         "Track"
913*288bf522SAndroid Build Coastguard Worker                     );
914*288bf522SAndroid Build Coastguard Worker                 }
915*288bf522SAndroid Build Coastguard Worker                 assert_eq!(cookie, 123);
916*288bf522SAndroid Build Coastguard Worker             }
917*288bf522SAndroid Build Coastguard Worker 
918*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
919*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.async_for_track_end_count, 1);
920*288bf522SAndroid Build Coastguard Worker             }
921*288bf522SAndroid Build Coastguard Worker         }
922*288bf522SAndroid Build Coastguard Worker 
923*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
924*288bf522SAndroid Build Coastguard Worker 
925*288bf522SAndroid Build Coastguard Worker         atrace_async_for_track_end(AtraceTag::App, "Track", 123);
926*288bf522SAndroid Build Coastguard Worker 
927*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
928*288bf522SAndroid Build Coastguard Worker     }
929*288bf522SAndroid Build Coastguard Worker 
930*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_instant()931*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_instant() {
932*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
933*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
934*288bf522SAndroid Build Coastguard Worker             trace_instant_count: u32,
935*288bf522SAndroid Build Coastguard Worker         }
936*288bf522SAndroid Build Coastguard Worker 
937*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
938*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
939*288bf522SAndroid Build Coastguard Worker                 1
940*288bf522SAndroid Build Coastguard Worker             }
941*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_wrap(&mut self, tag: u64, name: *const c_char) {
942*288bf522SAndroid Build Coastguard Worker                 self.trace_instant_count += 1;
943*288bf522SAndroid Build Coastguard Worker                 assert!(self.trace_instant_count < 2);
944*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
945*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
946*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
947*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
948*288bf522SAndroid Build Coastguard Worker                 unsafe {
949*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
950*288bf522SAndroid Build Coastguard Worker                 }
951*288bf522SAndroid Build Coastguard Worker             }
952*288bf522SAndroid Build Coastguard Worker 
953*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
954*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.trace_instant_count, 1);
955*288bf522SAndroid Build Coastguard Worker             }
956*288bf522SAndroid Build Coastguard Worker         }
957*288bf522SAndroid Build Coastguard Worker 
958*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
959*288bf522SAndroid Build Coastguard Worker 
960*288bf522SAndroid Build Coastguard Worker         atrace_instant(AtraceTag::App, "Test Name");
961*288bf522SAndroid Build Coastguard Worker 
962*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
963*288bf522SAndroid Build Coastguard Worker     }
964*288bf522SAndroid Build Coastguard Worker 
965*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_instant_for_track()966*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_instant_for_track() {
967*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
968*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
969*288bf522SAndroid Build Coastguard Worker             trace_instant_for_track_count: u32,
970*288bf522SAndroid Build Coastguard Worker         }
971*288bf522SAndroid Build Coastguard Worker 
972*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
973*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
974*288bf522SAndroid Build Coastguard Worker                 1
975*288bf522SAndroid Build Coastguard Worker             }
976*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_for_track_wrap(
977*288bf522SAndroid Build Coastguard Worker                 &mut self,
978*288bf522SAndroid Build Coastguard Worker                 tag: u64,
979*288bf522SAndroid Build Coastguard Worker                 track_name: *const c_char,
980*288bf522SAndroid Build Coastguard Worker                 name: *const c_char,
981*288bf522SAndroid Build Coastguard Worker             ) {
982*288bf522SAndroid Build Coastguard Worker                 self.trace_instant_for_track_count += 1;
983*288bf522SAndroid Build Coastguard Worker                 assert!(self.trace_instant_for_track_count < 2);
984*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
985*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
986*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
987*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
988*288bf522SAndroid Build Coastguard Worker                 unsafe {
989*288bf522SAndroid Build Coastguard Worker                     assert_eq!(
990*288bf522SAndroid Build Coastguard Worker                         CStr::from_ptr(track_name).to_str().expect("to_str failed"),
991*288bf522SAndroid Build Coastguard Worker                         "Track"
992*288bf522SAndroid Build Coastguard Worker                     );
993*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
994*288bf522SAndroid Build Coastguard Worker                 }
995*288bf522SAndroid Build Coastguard Worker             }
996*288bf522SAndroid Build Coastguard Worker 
997*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
998*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.trace_instant_for_track_count, 1);
999*288bf522SAndroid Build Coastguard Worker             }
1000*288bf522SAndroid Build Coastguard Worker         }
1001*288bf522SAndroid Build Coastguard Worker 
1002*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
1003*288bf522SAndroid Build Coastguard Worker 
1004*288bf522SAndroid Build Coastguard Worker         atrace_instant_for_track(AtraceTag::App, "Track", "Test Name");
1005*288bf522SAndroid Build Coastguard Worker 
1006*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
1007*288bf522SAndroid Build Coastguard Worker     }
1008*288bf522SAndroid Build Coastguard Worker 
1009*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_int()1010*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_int() {
1011*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
1012*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
1013*288bf522SAndroid Build Coastguard Worker             trace_int_count: u32,
1014*288bf522SAndroid Build Coastguard Worker         }
1015*288bf522SAndroid Build Coastguard Worker 
1016*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
1017*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
1018*288bf522SAndroid Build Coastguard Worker                 1
1019*288bf522SAndroid Build Coastguard Worker             }
1020*288bf522SAndroid Build Coastguard Worker             fn atrace_int_wrap(&mut self, tag: u64, name: *const c_char, value: i32) {
1021*288bf522SAndroid Build Coastguard Worker                 self.trace_int_count += 1;
1022*288bf522SAndroid Build Coastguard Worker                 assert!(self.trace_int_count < 2);
1023*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1024*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
1025*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
1026*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
1027*288bf522SAndroid Build Coastguard Worker                 unsafe {
1028*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
1029*288bf522SAndroid Build Coastguard Worker                 }
1030*288bf522SAndroid Build Coastguard Worker                 assert_eq!(value, 32);
1031*288bf522SAndroid Build Coastguard Worker             }
1032*288bf522SAndroid Build Coastguard Worker 
1033*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
1034*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.trace_int_count, 1);
1035*288bf522SAndroid Build Coastguard Worker             }
1036*288bf522SAndroid Build Coastguard Worker         }
1037*288bf522SAndroid Build Coastguard Worker 
1038*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
1039*288bf522SAndroid Build Coastguard Worker 
1040*288bf522SAndroid Build Coastguard Worker         atrace_int(AtraceTag::App, "Test Name", 32);
1041*288bf522SAndroid Build Coastguard Worker 
1042*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
1043*288bf522SAndroid Build Coastguard Worker     }
1044*288bf522SAndroid Build Coastguard Worker 
1045*288bf522SAndroid Build Coastguard Worker     #[test]
forwards_trace_int64()1046*288bf522SAndroid Build Coastguard Worker     fn forwards_trace_int64() {
1047*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
1048*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
1049*288bf522SAndroid Build Coastguard Worker             trace_int64_count: u32,
1050*288bf522SAndroid Build Coastguard Worker         }
1051*288bf522SAndroid Build Coastguard Worker 
1052*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
1053*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
1054*288bf522SAndroid Build Coastguard Worker                 1
1055*288bf522SAndroid Build Coastguard Worker             }
1056*288bf522SAndroid Build Coastguard Worker             fn atrace_int64_wrap(&mut self, tag: u64, name: *const c_char, value: i64) {
1057*288bf522SAndroid Build Coastguard Worker                 self.trace_int64_count += 1;
1058*288bf522SAndroid Build Coastguard Worker                 assert!(self.trace_int64_count < 2);
1059*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1060*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
1061*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
1062*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
1063*288bf522SAndroid Build Coastguard Worker                 unsafe {
1064*288bf522SAndroid Build Coastguard Worker                     assert_eq!(CStr::from_ptr(name).to_str().expect("to_str failed"), "Test Name");
1065*288bf522SAndroid Build Coastguard Worker                 }
1066*288bf522SAndroid Build Coastguard Worker                 assert_eq!(value, 64);
1067*288bf522SAndroid Build Coastguard Worker             }
1068*288bf522SAndroid Build Coastguard Worker 
1069*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
1070*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.trace_int64_count, 1);
1071*288bf522SAndroid Build Coastguard Worker             }
1072*288bf522SAndroid Build Coastguard Worker         }
1073*288bf522SAndroid Build Coastguard Worker 
1074*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
1075*288bf522SAndroid Build Coastguard Worker 
1076*288bf522SAndroid Build Coastguard Worker         atrace_int64(AtraceTag::App, "Test Name", 64);
1077*288bf522SAndroid Build Coastguard Worker 
1078*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
1079*288bf522SAndroid Build Coastguard Worker     }
1080*288bf522SAndroid Build Coastguard Worker 
1081*288bf522SAndroid Build Coastguard Worker     #[test]
scoped_event_starts_and_ends_in_order()1082*288bf522SAndroid Build Coastguard Worker     fn scoped_event_starts_and_ends_in_order() {
1083*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
1084*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
1085*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
1086*288bf522SAndroid Build Coastguard Worker             end_count: u32,
1087*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
1088*288bf522SAndroid Build Coastguard Worker         }
1089*288bf522SAndroid Build Coastguard Worker 
1090*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
1091*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
1092*288bf522SAndroid Build Coastguard Worker                 1
1093*288bf522SAndroid Build Coastguard Worker             }
1094*288bf522SAndroid Build Coastguard Worker 
1095*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, tag: u64, name: *const c_char) {
1096*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
1097*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 0);
1098*288bf522SAndroid Build Coastguard Worker 
1099*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
1100*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
1101*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1102*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
1103*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
1104*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
1105*288bf522SAndroid Build Coastguard Worker                 unsafe {
1106*288bf522SAndroid Build Coastguard Worker                     assert_eq!(
1107*288bf522SAndroid Build Coastguard Worker                         CStr::from_ptr(name).to_str().expect("to_str failed"),
1108*288bf522SAndroid Build Coastguard Worker                         "Scoped Event"
1109*288bf522SAndroid Build Coastguard Worker                     );
1110*288bf522SAndroid Build Coastguard Worker                 }
1111*288bf522SAndroid Build Coastguard Worker             }
1112*288bf522SAndroid Build Coastguard Worker 
1113*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_wrap(&mut self, _tag: u64, _name: *const c_char) {
1114*288bf522SAndroid Build Coastguard Worker                 // We don't care about the contents of the event, we only use it to check begin/end ordering.
1115*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1116*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
1117*288bf522SAndroid Build Coastguard Worker 
1118*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
1119*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
1120*288bf522SAndroid Build Coastguard Worker             }
1121*288bf522SAndroid Build Coastguard Worker 
1122*288bf522SAndroid Build Coastguard Worker             fn atrace_end_wrap(&mut self, tag: u64) {
1123*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1124*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
1125*288bf522SAndroid Build Coastguard Worker 
1126*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
1127*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
1128*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1129*288bf522SAndroid Build Coastguard Worker             }
1130*288bf522SAndroid Build Coastguard Worker 
1131*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
1132*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1133*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
1134*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
1135*288bf522SAndroid Build Coastguard Worker             }
1136*288bf522SAndroid Build Coastguard Worker         }
1137*288bf522SAndroid Build Coastguard Worker 
1138*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
1139*288bf522SAndroid Build Coastguard Worker 
1140*288bf522SAndroid Build Coastguard Worker         {
1141*288bf522SAndroid Build Coastguard Worker             let _event_guard = begin_scoped_event(AtraceTag::App, "Scoped Event");
1142*288bf522SAndroid Build Coastguard Worker             atrace_instant(AtraceTag::App, "Instant event called within scoped event");
1143*288bf522SAndroid Build Coastguard Worker         }
1144*288bf522SAndroid Build Coastguard Worker 
1145*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
1146*288bf522SAndroid Build Coastguard Worker     }
1147*288bf522SAndroid Build Coastguard Worker 
1148*288bf522SAndroid Build Coastguard Worker     // Need to have this alias to make the macro work, since it calls atrace::begin_scoped_event.
1149*288bf522SAndroid Build Coastguard Worker     use crate as atrace;
traced_method_for_test()1150*288bf522SAndroid Build Coastguard Worker     fn traced_method_for_test() {
1151*288bf522SAndroid Build Coastguard Worker         trace_method!(AtraceTag::App);
1152*288bf522SAndroid Build Coastguard Worker         atrace_instant(AtraceTag::App, "Instant event called within method");
1153*288bf522SAndroid Build Coastguard Worker     }
1154*288bf522SAndroid Build Coastguard Worker 
1155*288bf522SAndroid Build Coastguard Worker     #[test]
method_trace_starts_and_ends_in_order()1156*288bf522SAndroid Build Coastguard Worker     fn method_trace_starts_and_ends_in_order() {
1157*288bf522SAndroid Build Coastguard Worker         #[derive(Default)]
1158*288bf522SAndroid Build Coastguard Worker         struct CallCheck {
1159*288bf522SAndroid Build Coastguard Worker             begin_count: u32,
1160*288bf522SAndroid Build Coastguard Worker             end_count: u32,
1161*288bf522SAndroid Build Coastguard Worker             instant_count: u32,
1162*288bf522SAndroid Build Coastguard Worker         }
1163*288bf522SAndroid Build Coastguard Worker 
1164*288bf522SAndroid Build Coastguard Worker         impl mock_atrace::ATraceMocker for CallCheck {
1165*288bf522SAndroid Build Coastguard Worker             fn atrace_is_tag_enabled_wrap(&mut self, _tag: u64) -> u64 {
1166*288bf522SAndroid Build Coastguard Worker                 1
1167*288bf522SAndroid Build Coastguard Worker             }
1168*288bf522SAndroid Build Coastguard Worker 
1169*288bf522SAndroid Build Coastguard Worker             fn atrace_begin_wrap(&mut self, tag: u64, name: *const c_char) {
1170*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
1171*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 0);
1172*288bf522SAndroid Build Coastguard Worker 
1173*288bf522SAndroid Build Coastguard Worker                 self.begin_count += 1;
1174*288bf522SAndroid Build Coastguard Worker                 assert!(self.begin_count < 2);
1175*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1176*288bf522SAndroid Build Coastguard Worker                 // SAFETY: If the code under test is correct, the pointer is guaranteed to satisfy
1177*288bf522SAndroid Build Coastguard Worker                 // the requirements of `CStr::from_ptr`. If the code is not correct, this section is
1178*288bf522SAndroid Build Coastguard Worker                 // unsafe and will hopefully fail the test.
1179*288bf522SAndroid Build Coastguard Worker                 unsafe {
1180*288bf522SAndroid Build Coastguard Worker                     assert_eq!(
1181*288bf522SAndroid Build Coastguard Worker                         CStr::from_ptr(name).to_str().expect("to_str failed"),
1182*288bf522SAndroid Build Coastguard Worker                         "lib::tests::traced_method_for_test"
1183*288bf522SAndroid Build Coastguard Worker                     );
1184*288bf522SAndroid Build Coastguard Worker                 }
1185*288bf522SAndroid Build Coastguard Worker             }
1186*288bf522SAndroid Build Coastguard Worker 
1187*288bf522SAndroid Build Coastguard Worker             fn atrace_instant_wrap(&mut self, _tag: u64, _name: *const c_char) {
1188*288bf522SAndroid Build Coastguard Worker                 // We don't care about the contents of the event, we only use it to check begin/end ordering.
1189*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1190*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 0);
1191*288bf522SAndroid Build Coastguard Worker 
1192*288bf522SAndroid Build Coastguard Worker                 self.instant_count += 1;
1193*288bf522SAndroid Build Coastguard Worker                 assert!(self.instant_count < 2);
1194*288bf522SAndroid Build Coastguard Worker             }
1195*288bf522SAndroid Build Coastguard Worker 
1196*288bf522SAndroid Build Coastguard Worker             fn atrace_end_wrap(&mut self, tag: u64) {
1197*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1198*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
1199*288bf522SAndroid Build Coastguard Worker 
1200*288bf522SAndroid Build Coastguard Worker                 self.end_count += 1;
1201*288bf522SAndroid Build Coastguard Worker                 assert!(self.end_count < 2);
1202*288bf522SAndroid Build Coastguard Worker                 assert_eq!(tag, cutils_trace_bindgen::ATRACE_TAG_APP as u64);
1203*288bf522SAndroid Build Coastguard Worker             }
1204*288bf522SAndroid Build Coastguard Worker 
1205*288bf522SAndroid Build Coastguard Worker             fn finish(&self) {
1206*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.begin_count, 1);
1207*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.end_count, 1);
1208*288bf522SAndroid Build Coastguard Worker                 assert_eq!(self.instant_count, 1);
1209*288bf522SAndroid Build Coastguard Worker             }
1210*288bf522SAndroid Build Coastguard Worker         }
1211*288bf522SAndroid Build Coastguard Worker 
1212*288bf522SAndroid Build Coastguard Worker         let _guard = mock_atrace::set_scoped_mocker(CallCheck::default());
1213*288bf522SAndroid Build Coastguard Worker 
1214*288bf522SAndroid Build Coastguard Worker         traced_method_for_test();
1215*288bf522SAndroid Build Coastguard Worker 
1216*288bf522SAndroid Build Coastguard Worker         mock_atrace::mocker_finish();
1217*288bf522SAndroid Build Coastguard Worker     }
1218*288bf522SAndroid Build Coastguard Worker }
1219