xref: /aosp_15_r20/system/chre/host/common/fbs_daemon_base.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include <cstdlib>
18*84e33947SAndroid Build Coastguard Worker #include <fstream>
19*84e33947SAndroid Build Coastguard Worker 
20*84e33947SAndroid Build Coastguard Worker #include "chre_host/fbs_daemon_base.h"
21*84e33947SAndroid Build Coastguard Worker #include "chre_host/log.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre_host/napp_header.h"
23*84e33947SAndroid Build Coastguard Worker 
24*84e33947SAndroid Build Coastguard Worker #include <json/json.h>
25*84e33947SAndroid Build Coastguard Worker 
26*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
27*84e33947SAndroid Build Coastguard Worker #include <aidl/android/frameworks/stats/IStats.h>
28*84e33947SAndroid Build Coastguard Worker #include <android/binder_manager.h>
29*84e33947SAndroid Build Coastguard Worker #include <android_chre_flags.h>
30*84e33947SAndroid Build Coastguard Worker #include <chre_atoms_log.h>
31*84e33947SAndroid Build Coastguard Worker #endif  // CHRE_DAEMON_METRIC_ENABLED
32*84e33947SAndroid Build Coastguard Worker 
33*84e33947SAndroid Build Coastguard Worker // Aliased for consistency with the way these symbols are referenced in
34*84e33947SAndroid Build Coastguard Worker // CHRE-side code
35*84e33947SAndroid Build Coastguard Worker namespace fbs = ::chre::fbs;
36*84e33947SAndroid Build Coastguard Worker 
37*84e33947SAndroid Build Coastguard Worker namespace android {
38*84e33947SAndroid Build Coastguard Worker namespace chre {
39*84e33947SAndroid Build Coastguard Worker 
40*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
41*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::IStats;
42*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::VendorAtom;
43*84e33947SAndroid Build Coastguard Worker using ::aidl::android::frameworks::stats::VendorAtomValue;
44*84e33947SAndroid Build Coastguard Worker using ::android::chre::Atoms::ChreHalNanoappLoadFailed;
45*84e33947SAndroid Build Coastguard Worker #endif  // CHRE_DAEMON_METRIC_ENABLED
46*84e33947SAndroid Build Coastguard Worker 
sendNanoappLoad(uint64_t appId,uint32_t appVersion,uint32_t appTargetApiVersion,const std::string & appBinaryName,uint32_t transactionId)47*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendNanoappLoad(uint64_t appId, uint32_t appVersion,
48*84e33947SAndroid Build Coastguard Worker                                     uint32_t appTargetApiVersion,
49*84e33947SAndroid Build Coastguard Worker                                     const std::string &appBinaryName,
50*84e33947SAndroid Build Coastguard Worker                                     uint32_t transactionId) {
51*84e33947SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder builder;
52*84e33947SAndroid Build Coastguard Worker   HostProtocolHost::encodeLoadNanoappRequestForFile(
53*84e33947SAndroid Build Coastguard Worker       builder, transactionId, appId, appVersion, appTargetApiVersion,
54*84e33947SAndroid Build Coastguard Worker       appBinaryName.c_str());
55*84e33947SAndroid Build Coastguard Worker 
56*84e33947SAndroid Build Coastguard Worker   bool success = sendMessageToChre(
57*84e33947SAndroid Build Coastguard Worker       kHostClientIdDaemon, builder.GetBufferPointer(), builder.GetSize());
58*84e33947SAndroid Build Coastguard Worker 
59*84e33947SAndroid Build Coastguard Worker   if (!success) {
60*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to send nanoapp filename.");
61*84e33947SAndroid Build Coastguard Worker   } else {
62*84e33947SAndroid Build Coastguard Worker     Transaction transaction = {
63*84e33947SAndroid Build Coastguard Worker         .transactionId = transactionId,
64*84e33947SAndroid Build Coastguard Worker         .nanoappId = appId,
65*84e33947SAndroid Build Coastguard Worker     };
66*84e33947SAndroid Build Coastguard Worker     mPreloadedNanoappPendingTransactions.push(transaction);
67*84e33947SAndroid Build Coastguard Worker   }
68*84e33947SAndroid Build Coastguard Worker 
69*84e33947SAndroid Build Coastguard Worker   return success;
70*84e33947SAndroid Build Coastguard Worker }
71*84e33947SAndroid Build Coastguard Worker 
sendTimeSync(bool logOnError)72*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendTimeSync(bool logOnError) {
73*84e33947SAndroid Build Coastguard Worker   bool success = false;
74*84e33947SAndroid Build Coastguard Worker   int64_t timeOffset = getTimeOffset(&success);
75*84e33947SAndroid Build Coastguard Worker 
76*84e33947SAndroid Build Coastguard Worker   if (success) {
77*84e33947SAndroid Build Coastguard Worker     flatbuffers::FlatBufferBuilder builder(64);
78*84e33947SAndroid Build Coastguard Worker     HostProtocolHost::encodeTimeSyncMessage(builder, timeOffset);
79*84e33947SAndroid Build Coastguard Worker     success = sendMessageToChre(kHostClientIdDaemon, builder.GetBufferPointer(),
80*84e33947SAndroid Build Coastguard Worker                                 builder.GetSize());
81*84e33947SAndroid Build Coastguard Worker 
82*84e33947SAndroid Build Coastguard Worker     if (!success && logOnError) {
83*84e33947SAndroid Build Coastguard Worker       LOGE("Failed to deliver time sync message from host to CHRE");
84*84e33947SAndroid Build Coastguard Worker     }
85*84e33947SAndroid Build Coastguard Worker   }
86*84e33947SAndroid Build Coastguard Worker 
87*84e33947SAndroid Build Coastguard Worker   return success;
88*84e33947SAndroid Build Coastguard Worker }
89*84e33947SAndroid Build Coastguard Worker 
sendMessageToChre(uint16_t clientId,void * data,size_t length)90*84e33947SAndroid Build Coastguard Worker bool FbsDaemonBase::sendMessageToChre(uint16_t clientId, void *data,
91*84e33947SAndroid Build Coastguard Worker                                       size_t length) {
92*84e33947SAndroid Build Coastguard Worker   bool success = false;
93*84e33947SAndroid Build Coastguard Worker   if (!HostProtocolHost::mutateHostClientId(data, length, clientId)) {
94*84e33947SAndroid Build Coastguard Worker     LOGE("Couldn't set host client ID in message container!");
95*84e33947SAndroid Build Coastguard Worker   } else {
96*84e33947SAndroid Build Coastguard Worker     LOGV("Delivering message from host (size %zu)", length);
97*84e33947SAndroid Build Coastguard Worker     getLogger().dump(static_cast<const uint8_t *>(data), length);
98*84e33947SAndroid Build Coastguard Worker     success = doSendMessage(data, length);
99*84e33947SAndroid Build Coastguard Worker   }
100*84e33947SAndroid Build Coastguard Worker 
101*84e33947SAndroid Build Coastguard Worker   return success;
102*84e33947SAndroid Build Coastguard Worker }
103*84e33947SAndroid Build Coastguard Worker 
onMessageReceived(const unsigned char * messageBuffer,size_t messageLen)104*84e33947SAndroid Build Coastguard Worker void FbsDaemonBase::onMessageReceived(const unsigned char *messageBuffer,
105*84e33947SAndroid Build Coastguard Worker                                       size_t messageLen) {
106*84e33947SAndroid Build Coastguard Worker   getLogger().dump(messageBuffer, messageLen);
107*84e33947SAndroid Build Coastguard Worker 
108*84e33947SAndroid Build Coastguard Worker   uint16_t hostClientId;
109*84e33947SAndroid Build Coastguard Worker   fbs::ChreMessage messageType;
110*84e33947SAndroid Build Coastguard Worker   if (!HostProtocolHost::extractHostClientIdAndType(
111*84e33947SAndroid Build Coastguard Worker           messageBuffer, messageLen, &hostClientId, &messageType)) {
112*84e33947SAndroid Build Coastguard Worker     LOGW("Failed to extract host client ID from message - sending broadcast");
113*84e33947SAndroid Build Coastguard Worker     hostClientId = ::chre::kHostClientIdUnspecified;
114*84e33947SAndroid Build Coastguard Worker   }
115*84e33947SAndroid Build Coastguard Worker 
116*84e33947SAndroid Build Coastguard Worker   std::unique_ptr<fbs::MessageContainerT> container =
117*84e33947SAndroid Build Coastguard Worker       fbs::UnPackMessageContainer(messageBuffer);
118*84e33947SAndroid Build Coastguard Worker 
119*84e33947SAndroid Build Coastguard Worker   if (messageType == fbs::ChreMessage::LogMessage) {
120*84e33947SAndroid Build Coastguard Worker     const auto *logMessage = container->message.AsLogMessage();
121*84e33947SAndroid Build Coastguard Worker     const std::vector<int8_t> &logData = logMessage->buffer;
122*84e33947SAndroid Build Coastguard Worker 
123*84e33947SAndroid Build Coastguard Worker     getLogger().log(reinterpret_cast<const uint8_t *>(logData.data()),
124*84e33947SAndroid Build Coastguard Worker                     logData.size());
125*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::LogMessageV2) {
126*84e33947SAndroid Build Coastguard Worker     const auto *logMessage = container->message.AsLogMessageV2();
127*84e33947SAndroid Build Coastguard Worker     const std::vector<int8_t> &logDataBuffer = logMessage->buffer;
128*84e33947SAndroid Build Coastguard Worker     const auto *logData =
129*84e33947SAndroid Build Coastguard Worker         reinterpret_cast<const uint8_t *>(logDataBuffer.data());
130*84e33947SAndroid Build Coastguard Worker     uint32_t numLogsDropped = logMessage->num_logs_dropped;
131*84e33947SAndroid Build Coastguard Worker     getLogger().logV2(logData, logDataBuffer.size(), numLogsDropped);
132*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::TimeSyncRequest) {
133*84e33947SAndroid Build Coastguard Worker     sendTimeSync(true /* logOnError */);
134*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::LowPowerMicAccessRequest) {
135*84e33947SAndroid Build Coastguard Worker     configureLpma(true /* enabled */);
136*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::LowPowerMicAccessRelease) {
137*84e33947SAndroid Build Coastguard Worker     configureLpma(false /* enabled */);
138*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::MetricLog) {
139*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
140*84e33947SAndroid Build Coastguard Worker     const auto *metricMsg = container->message.AsMetricLog();
141*84e33947SAndroid Build Coastguard Worker     handleMetricLog(metricMsg);
142*84e33947SAndroid Build Coastguard Worker #endif  // CHRE_DAEMON_METRIC_ENABLED
143*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::NanConfigurationRequest) {
144*84e33947SAndroid Build Coastguard Worker     handleNanConfigurationRequest(
145*84e33947SAndroid Build Coastguard Worker         container->message.AsNanConfigurationRequest());
146*84e33947SAndroid Build Coastguard Worker   } else if (messageType == fbs::ChreMessage::NanoappTokenDatabaseInfo) {
147*84e33947SAndroid Build Coastguard Worker     // TODO(b/242760291): Use this info to map nanoapp log detokenizers with
148*84e33947SAndroid Build Coastguard Worker     // instance ID in log message parser.
149*84e33947SAndroid Build Coastguard Worker   } else if (hostClientId == kHostClientIdDaemon) {
150*84e33947SAndroid Build Coastguard Worker     handleDaemonMessage(messageBuffer);
151*84e33947SAndroid Build Coastguard Worker   } else if (hostClientId == ::chre::kHostClientIdUnspecified) {
152*84e33947SAndroid Build Coastguard Worker     mServer.sendToAllClients(messageBuffer, static_cast<size_t>(messageLen));
153*84e33947SAndroid Build Coastguard Worker   } else {
154*84e33947SAndroid Build Coastguard Worker     mServer.sendToClientById(messageBuffer, static_cast<size_t>(messageLen),
155*84e33947SAndroid Build Coastguard Worker                              hostClientId);
156*84e33947SAndroid Build Coastguard Worker   }
157*84e33947SAndroid Build Coastguard Worker }
158*84e33947SAndroid Build Coastguard Worker 
handleDaemonMessage(const uint8_t * message)159*84e33947SAndroid Build Coastguard Worker void FbsDaemonBase::handleDaemonMessage(const uint8_t *message) {
160*84e33947SAndroid Build Coastguard Worker   std::unique_ptr<fbs::MessageContainerT> container =
161*84e33947SAndroid Build Coastguard Worker       fbs::UnPackMessageContainer(message);
162*84e33947SAndroid Build Coastguard Worker   if (container->message.type != fbs::ChreMessage::LoadNanoappResponse) {
163*84e33947SAndroid Build Coastguard Worker     LOGE("Invalid message from CHRE directed to daemon");
164*84e33947SAndroid Build Coastguard Worker   } else {
165*84e33947SAndroid Build Coastguard Worker     const auto *response = container->message.AsLoadNanoappResponse();
166*84e33947SAndroid Build Coastguard Worker     if (mPreloadedNanoappPendingTransactions.empty()) {
167*84e33947SAndroid Build Coastguard Worker       LOGE("Received nanoapp load response with no pending load");
168*84e33947SAndroid Build Coastguard Worker     } else if (mPreloadedNanoappPendingTransactions.front().transactionId !=
169*84e33947SAndroid Build Coastguard Worker                response->transaction_id) {
170*84e33947SAndroid Build Coastguard Worker       LOGE("Received nanoapp load response with ID %" PRIu32
171*84e33947SAndroid Build Coastguard Worker            " expected transaction id %" PRIu32,
172*84e33947SAndroid Build Coastguard Worker            response->transaction_id,
173*84e33947SAndroid Build Coastguard Worker            mPreloadedNanoappPendingTransactions.front().transactionId);
174*84e33947SAndroid Build Coastguard Worker     } else {
175*84e33947SAndroid Build Coastguard Worker       if (!response->success) {
176*84e33947SAndroid Build Coastguard Worker         LOGE("Received unsuccessful nanoapp load response with ID %" PRIu32,
177*84e33947SAndroid Build Coastguard Worker              mPreloadedNanoappPendingTransactions.front().transactionId);
178*84e33947SAndroid Build Coastguard Worker 
179*84e33947SAndroid Build Coastguard Worker #ifdef CHRE_DAEMON_METRIC_ENABLED
180*84e33947SAndroid Build Coastguard Worker         if (!mMetricsReporter.logNanoappLoadFailed(
181*84e33947SAndroid Build Coastguard Worker                 mPreloadedNanoappPendingTransactions.front().nanoappId,
182*84e33947SAndroid Build Coastguard Worker                 ChreHalNanoappLoadFailed::TYPE_PRELOADED,
183*84e33947SAndroid Build Coastguard Worker                 ChreHalNanoappLoadFailed::REASON_ERROR_GENERIC)) {
184*84e33947SAndroid Build Coastguard Worker           LOGE("Could not log the nanoapp load failed metric");
185*84e33947SAndroid Build Coastguard Worker         }
186*84e33947SAndroid Build Coastguard Worker #endif  // CHRE_DAEMON_METRIC_ENABLED
187*84e33947SAndroid Build Coastguard Worker       }
188*84e33947SAndroid Build Coastguard Worker       mPreloadedNanoappPendingTransactions.pop();
189*84e33947SAndroid Build Coastguard Worker     }
190*84e33947SAndroid Build Coastguard Worker   }
191*84e33947SAndroid Build Coastguard Worker }
192*84e33947SAndroid Build Coastguard Worker 
193*84e33947SAndroid Build Coastguard Worker }  // namespace chre
194*84e33947SAndroid Build Coastguard Worker }  // namespace android
195