1 /*
2  * Copyright (C) 2020 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/platform_debug_dump_manager.h"
18 
19 #include "chre/core/event_loop_manager.h"
20 #include "chre/platform/log.h"
21 #include "chre/target_platform/host_link_base.h"
22 #include "chre/target_platform/platform_debug_dump_manager_base.h"
23 
24 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
25 #include "ash/debug.h"
26 #else  // CHRE_ENABLE_ASH_DEBUG_DUMP
27 #include <cstring>
28 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
29 
30 namespace chre {
31 namespace {
32 
33 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
onDebugDumpTriggered(void *,uint32_t handle)34 void onDebugDumpTriggered(void * /*cookie*/, uint32_t handle) {
35   auto &debugDumpManager =
36       EventLoopManagerSingleton::get()->getDebugDumpManager();
37 
38   debugDumpManager.setHandle(handle);
39   debugDumpManager.trigger();
40 }
41 
debugDumpReadyCb(void *,const char * debugStr,size_t debugStrSize,bool complete)42 void debugDumpReadyCb(void * /*cookie*/, const char *debugStr,
43                       size_t debugStrSize, bool complete) {
44   EventLoopManagerSingleton::get()->getDebugDumpManager().sendDebugDumpResult(
45       debugStr, debugStrSize, complete);
46 }
47 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
48 
49 }  // namespace
50 
sendDebugDump(const char * debugStr,bool complete)51 void PlatformDebugDumpManager::sendDebugDump(const char *debugStr,
52                                              bool complete) {
53   // DDM is guaranteed to call complete=true at the end of a debug dump session.
54   // However, sendDebugDumpResult may not get called with complete=true, for
55   // example when ASH times out. Therefore, mDataCount has to be reset here
56   // instead of in sendDebugDumpResult(), to properly start the next debug dump
57   // session.
58   if (mComplete) {
59     mDataCount = 0;
60   }
61   mComplete = complete;
62 
63 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
64   ashCommitDebugDump(mHandle, debugStr, complete);
65 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
66   sendDebugDumpResult(debugStr, strlen(debugStr), complete);
67 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
68 }
69 
logStateToBuffer(DebugDumpWrapper &)70 void PlatformDebugDumpManager::logStateToBuffer(
71     DebugDumpWrapper & /* debugDump */) {}
72 
PlatformDebugDumpManagerBase()73 PlatformDebugDumpManagerBase::PlatformDebugDumpManagerBase() {
74 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
75   if (!ashRegisterDebugDumpCallback("CHRE", onDebugDumpTriggered,
76                                     nullptr /* cookie */)) {
77     LOGE("Failed to register ASH debug dump callback");
78   }
79 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
80 }
81 
~PlatformDebugDumpManagerBase()82 PlatformDebugDumpManagerBase::~PlatformDebugDumpManagerBase() {
83 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
84   ashUnregisterDebugDumpCallback(onDebugDumpTriggered);
85 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
86 }
87 
onDebugDumpRequested(uint16_t hostClientId)88 bool PlatformDebugDumpManagerBase::onDebugDumpRequested(uint16_t hostClientId) {
89   mHostClientId = hostClientId;
90 
91 #ifdef CHRE_ENABLE_ASH_DEBUG_DUMP
92   return ashTriggerDebugDump(debugDumpReadyCb, nullptr /*cookie*/);
93 #else   // CHRE_ENABLE_ASH_DEBUG_DUMP
94   EventLoopManagerSingleton::get()->getDebugDumpManager().trigger();
95   return true;
96 #endif  // CHRE_ENABLE_ASH_DEBUG_DUMP
97 }
98 
sendDebugDumpResult(const char * debugStr,size_t debugStrSize,bool complete)99 void PlatformDebugDumpManagerBase::sendDebugDumpResult(const char *debugStr,
100                                                        size_t debugStrSize,
101                                                        bool complete) {
102   if (debugStrSize > 0) {
103     mDataCount++;
104   }
105   sendDebugDumpResultToHost(mHostClientId, debugStr, debugStrSize, complete,
106                             mDataCount);
107 }
108 
109 }  // namespace chre
110