/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CHRE_EXYNOS_DAEMON_H_ #define CHRE_EXYNOS_DAEMON_H_ #include #include #include "chre_host/fbs_daemon_base.h" #include "chre_host/st_hal_lpma_handler.h" namespace android { namespace chre { class ExynosDaemon : public FbsDaemonBase { public: ExynosDaemon(); ~ExynosDaemon() { deinit(); } //! EXYNOS's shared memory size for CHRE <-> AP is 4KB. static constexpr size_t kIpcMsgSizeMax = 4096; /** * Initializes the CHRE daemon. * * @return true on successful init */ bool init(); /** * Starts a socket server receive loop for inbound messages. */ void run(); void processIncomingMsgs(); int64_t getTimeOffset(bool *success) override; protected: void loadPreloadedNanoapp(const std::string &directory, const std::string &name, uint32_t transactionId) override; void handleDaemonMessage(const uint8_t *message) override; bool doSendMessage(void *data, size_t length) override; void configureLpma(bool enabled) override { mLpmaHandler.enable(enabled); } private: static constexpr char kCommsDeviceFilename[] = "/dev/nanohub_comms"; static constexpr int kInvalidFd = -1; int mCommsReadFd = kInvalidFd; int mCommsWriteFd = kInvalidFd; std::thread mIncomingMsgProcessThread; std::thread::native_handle_type mNativeThreadHandle; std::atomic mProcessThreadRunning = false; StHalLpmaHandler mLpmaHandler; //! Set to the expected transaction, fragment, app ID for loading a nanoapp. struct Transaction { uint32_t transactionId; uint32_t fragmentId; uint64_t nanoappId; }; Transaction mPreloadedNanoappPendingTransaction; //! The mutex used to guard state between the nanoapp messaging thread //! and loading preloaded nanoapps. std::mutex mPreloadedNanoappsMutex; //! The condition variable used to wait for a nanoapp to finish loading. std::condition_variable mPreloadedNanoappsCond; //! Set to true when a preloaded nanoapp is pending load. bool mPreloadedNanoappPending; /** * Perform a graceful shutdown of the daemon */ void deinit(); /** * Stops the inbound message processing thread (forcibly). * Since the message read mechanism uses blocking system calls (poll, read), * and since there's no timeout on the system calls (to avoid waking the AP * up to handle timeouts), we forcibly terminate the thread on a daemon * deinit. POSIX semantics are used since the C++20 threading interface does * not provide an API to accomplish this. */ void stopMsgProcessingThread(); /** * Sends a preloaded nanoapp to CHRE. * * @param header The nanoapp header binary blob. * @param nanoapp The nanoapp binary blob. * @param transactionId The transaction ID to use when loading the app. * @return true if successful, false otherwise. */ bool loadNanoapp(const std::vector &header, const std::vector &nanoapp, uint32_t transactionId); /** * Loads a nanoapp using fragments. * * @param appId The ID of the nanoapp to load. * @param appVersion The version of the nanoapp to load. * @param appFlags The flags specified by the nanoapp to be loaded. * @param appTargetApiVersion The version of the CHRE API that the app * targets. * @param appBinary The application binary code. * @param appSize The size of the appBinary. * @param transactionId The transaction ID to use when loading. * @return true if successful, false otherwise. */ bool sendFragmentedNanoappLoad(uint64_t appId, uint32_t appVersion, uint32_t appFlags, uint32_t appTargetApiVersion, const uint8_t *appBinary, size_t appSize, uint32_t transactionId); bool sendFragmentAndWaitOnResponse(uint32_t transactionId, flatbuffers::FlatBufferBuilder &builder, uint32_t fragmentId, uint64_t appId); /** * Empty signal handler to handle SIGINT */ static void signalHandler(int /*signal*/) {} }; } // namespace chre } // namespace android #endif // CHRE_EXYNOS_DAEMON_H_