1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_PLATFORM_SLPI_DEBUG_DUMP_H_
18 #define CHRE_PLATFORM_SLPI_DEBUG_DUMP_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 
23 namespace chre {
24 
25 //! Size of the buffer used to store the debug dump string, including NULL
26 //! termination. Sets an upper bound on the largest string that can be provided
27 //! in a single call to ashCommitDebugDump(). Currently driven by the maximum
28 //! CHRE transfer size (4KB), minus some space for overhead.
29 extern size_t debugDumpStrMaxSize;
30 
31 //! How long we wait for all clients to commit their debug dump string
32 extern uint16_t debugDumpTimeoutMs;
33 
34 /**
35  * Type signature for a callback that can be registered in
36  * registerDebugDumpCallback(). A call to this function should result in
37  * commitDebugDump() getting called with the given handle and done=true
38  * within debugDumpStrMaxSize.
39  *
40  * This callback will be invoked from an arbitrary thread.
41  *
42  * @param cookie The cookie given to registerDebugDumpCallback() when this
43  *        callback was registered
44  * @param handle A unique handle for this callback, which must be used when
45  *        calling commitDebugDump()
46  *
47  * @see registerDebugDumpCallback()
48  */
49 typedef void (debugDumpCbFunc)(void *cookie, uint32_t handle);
50 
51 /**
52  * Register a function to be invoked when a debug dump has been requested. Upon
53  * receiving this callback, start the process of gathering debugging information
54  * and pass it to commitDebugDump() when ready. This can be done synchronously
55  * and/or asynchronously.
56  *
57  * It is invalid to attempt to register a new callback from the context of a
58  * callback - this will result in a deadlock. Otherwise safe to call from any
59  * thread, including during early initialization.
60  *
61  * A given callback function may only be registered once.
62  *
63  * @param name Human-friendly name for the module associated with this callback
64  * @param callback Function to call when debug dump is requested
65  * @param cookie Opaque data to pass to the callback
66  *
67  * @return true if the callback was successfully registered
68  */
69 bool registerDebugDumpCallback(const char *name, debugDumpCbFunc *callback,
70 	                             void *cookie);
71 
72 /**
73  * Unregisters a debug dump callback. After this function returns, the given
74  * callback is guaranteed to not be invoked again (until it is re-registered),
75  * but note that it may be called from another thread up to and during the
76  * execution of this function.
77  *
78  * It is invalid to attempt to unregister a callback from the context of a
79  * callback - this will result in a deadlock. Otherwise safe to call from any
80  * thread.
81  *
82  * @param callback Callback function previously given to
83  *        registerDebugDumpCallback()
84  */
85 void unregisterDebugDumpCallback(debugDumpCbFunc *callback);
86 
87 /**
88  * Add an ASCII string to appear in the debug dump, which appears in Android bug
89  * reports.
90  *
91  * Strings longer than ASH_DEBUG_DUMP_STR_MAX_SIZE will be truncated.
92  *
93  * While the "done" parameter allows for this function to be called multiple
94  * times for a single handle, no guarantee is made that all strings for a handle
95  * appear contiguously. In other words, if more than one call is made to this
96  * function, another module's debug data could appear in the middle. So modules
97  * are encouraged to make as few calls to this function as are necessary, and
98  * always terminate their strings with a newline.
99  *
100  * Safe to call from within the debug dump callback, or from any thread.
101  *
102  * @param handle The handle supplied in the call to the debug dump callback
103  * @param debugStr A null-terminated string containing debugging information
104  *        from this module (should be prefixed with some human-readable
105  *        identifier). Must be a valid pointer, but can be an empty string.
106  * @param done true if no more data is expected for this handle
107  *
108  * @return true if the string was accepted without truncation
109  */
110 bool commitDebugDump(uint32_t handle, const char *debugStr, bool done);
111 
112 /**
113  * Function signature for the callback given to triggerDebugDump() and used to
114  * pass populated strings back to the entity triggering the dump.
115  *
116  * This callback will be invoked from an arbitrary thread, but is guaranteed to
117  * not be called concurrently from multiple threads.
118  *
119  * @param cookie Opaque data given to triggerDebugDump()
120  * @param debugStr A non-null, null-terminated string containing debugging
121  *        information
122  * @param debugStrSize Size of debugStr (including null termination)
123  * @param complete true if this is the final call to this callback for the
124  *        current dump session
125  */
126 typedef void (debugDumpReadyCbFunc)(void *cookie, const char *debugStr,
127                                     size_t debugStrSize, bool complete);
128 
129 /**
130  * Kick off the debug dump data collection procedure. Synchronously invokes all
131  * callbacks registered via registerDebugDumpCallback() to notify them that the
132  * dump collection process is starting. Once all registered callbacks have
133  * provided their output via commitDebugDump() or a timeout occurs, the supplied
134  * data ready callback will be invoked with complete=true to finalize the dump
135  * process. If the local buffer fills up before the dump is complete, the ready
136  * callback will be invoked with complete=false.
137  *
138  * Only one debug dump can be in progress at a given time.
139  *
140  * Note that ideally this should be handled internally to the ASH
141  * implementation, but we are currently leveraging an outside entity (CHRE) to
142  * handle the debug dump process due to AP-side considerations.
143  *
144  * @param readyCb Callback used to pass debug string data back to the caller.
145  *        May be invoked synchronously from the context of this function, and/or
146  *        asynchronously later on from the context of an arbitrary thread.
147  * @param cookie Opaque data to pass to readyCb
148  *
149  * @return true if the dump process was successfully started
150  */
151 bool triggerDebugDump(debugDumpReadyCbFunc *readyCb, void *cookie);
152 
153 }  // namespace chre
154 
155 #endif  // CHRE_PLATFORM_SLPI_DEBUG_DUMP_H_
156