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 #include "chre/platform/slpi/debug_dump.h"
18 
19 #include "chre/platform/log.h"
20 #include "chre/util/macros.h"
21 
22 // Some devices don't have ash/debug.h implemented for them so allow swapping
23 // out that implementation with an empty one until an implementation can be
24 // provided for all devices.
25 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
26 #include "ash/debug.h"
27 #else  // CHRE_ENABLE_ASH_DEBUG_DUMP
28 #include <cstring>
29 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
30 
31 namespace chre {
32 namespace {
33 #ifndef CHRE_ENABLE_ASH_DEBUG_DUMP
34 //! State information for the debug dump callback provided by CHRE.
35 struct {
36   //! Provided in registerDebugDumpCallback() and used to request a debug
37   //! dump from CHRE
38   debugDumpCbFunc *callback;
39 
40   //! Arbitrary pointer to pass to the callback
41   void *cookie;
42 } gDumpCallback;
43 
44 //! State information for an in-progress debug dump
45 struct {
46   //! Provided in triggerDebugDump() and used to report the output of the
47   //! CHRE debug dump
48   debugDumpReadyCbFunc *callback;
49 
50   //! Arbitrary pointer to pass to the callback
51   void *cookie;
52 
53   //! Indicates whether the debug dump has completed
54   bool done = true;
55 } gDebugDumpState;
56 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
57 }  // namespace
58 
59 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
60 size_t debugDumpStrMaxSize = ASH_DEBUG_DUMP_STR_MAX_SIZE;
61 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
62 size_t debugDumpStrMaxSize = CHRE_MESSAGE_TO_HOST_MAX_SIZE;
63 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
64 
registerDebugDumpCallback(const char * name,debugDumpCbFunc * callback,void * cookie)65 bool registerDebugDumpCallback(const char *name, debugDumpCbFunc *callback,
66                                void *cookie) {
67 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
68   return ashRegisterDebugDumpCallback(name, callback, cookie);
69 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
70   UNUSED_VAR(name);
71   gDumpCallback.callback = callback;
72   gDumpCallback.cookie = cookie;
73   return true;
74 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
75 }
76 
unregisterDebugDumpCallback(debugDumpCbFunc * callback)77 void unregisterDebugDumpCallback(debugDumpCbFunc *callback) {
78 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
79   ashUnregisterDebugDumpCallback(callback);
80 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
81   UNUSED_VAR(callback);
82   gDumpCallback.callback = nullptr;
83   gDumpCallback.cookie = nullptr;
84 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
85 }
86 
commitDebugDump(uint32_t handle,const char * debugStr,bool done)87 bool commitDebugDump(uint32_t handle, const char *debugStr, bool done) {
88 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
89   return ashCommitDebugDump(handle, debugStr, done);
90 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
91   bool success = false;
92   if (handle != 0) {
93     LOGE("CHRE debug dump only supports a single debug dump callback");
94   } else if (gDebugDumpState.done) {
95     LOGE("CHRE debug dump already finished");
96   } else if (gDebugDumpState.callback != nullptr) {
97     gDebugDumpState.callback(gDebugDumpState.cookie, debugStr, strlen(debugStr),
98                              done);
99     gDebugDumpState.done = done;
100     success = true;
101   }
102   return success;
103 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
104 }
105 
triggerDebugDump(debugDumpReadyCbFunc * readyCb,void * cookie)106 bool triggerDebugDump(debugDumpReadyCbFunc *readyCb, void *cookie) {
107 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
108   return ashTriggerDebugDump(readyCb, cookie);
109 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
110   if (gDumpCallback.callback != nullptr) {
111     gDebugDumpState.callback = readyCb;
112     gDebugDumpState.cookie = cookie;
113     gDebugDumpState.done = false;
114     gDumpCallback.callback(gDumpCallback.cookie, 0 /* handle */);
115   }
116   return true;
117 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
118 }
119 
120 }  // namespace chre
121