Home | History | Annotate | Download | only in hal_generic
      1 /*
      2  * Copyright (C) 2017 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 ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H
     18 #define ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H
     19 
     20 #include <condition_variable>
     21 #include <functional>
     22 #include <mutex>
     23 #include <optional>
     24 
     25 #include <android/hardware/contexthub/1.0/IContexthub.h>
     26 #include <hidl/MQDescriptor.h>
     27 #include <hidl/Status.h>
     28 
     29 #include "chre_host/socket_client.h"
     30 #include "chre_host/host_protocol_host.h"
     31 #include "chre_host/fragmented_load_transaction.h"
     32 
     33 namespace android {
     34 namespace hardware {
     35 namespace contexthub {
     36 namespace V1_0 {
     37 namespace implementation {
     38 
     39 using ::android::chre::FragmentedLoadRequest;
     40 using ::android::chre::FragmentedLoadTransaction;
     41 using ::android::hardware::contexthub::V1_0::ContextHub;
     42 using ::android::hardware::contexthub::V1_0::ContextHubMsg;
     43 using ::android::hardware::contexthub::V1_0::IContexthub;
     44 using ::android::hardware::contexthub::V1_0::IContexthubCallback;
     45 using ::android::hardware::contexthub::V1_0::NanoAppBinary;
     46 using ::android::hardware::contexthub::V1_0::Result;
     47 using ::android::hardware::hidl_handle;
     48 using ::android::hardware::hidl_string;
     49 using ::android::hardware::hidl_vec;
     50 using ::android::hardware::Return;
     51 using ::android::sp;
     52 
     53 class GenericContextHub : public IContexthub {
     54  public:
     55   GenericContextHub();
     56 
     57   Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
     58 
     59   // Methods from ::android::hardware::contexthub::V1_0::IContexthub follow.
     60   Return<void> getHubs(getHubs_cb _hidl_cb) override;
     61   Return<Result> registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) override;
     62   Return<Result> sendMessageToHub(uint32_t hubId, const ContextHubMsg& msg) override;
     63   Return<Result> loadNanoApp(uint32_t hubId, const NanoAppBinary& appBinary, uint32_t transactionId) override;
     64   Return<Result> unloadNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
     65   Return<Result> enableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
     66   Return<Result> disableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
     67   Return<Result> queryApps(uint32_t hubId) override;
     68 
     69  private:
     70   ::android::chre::SocketClient mClient;
     71   sp<IContexthubCallback> mCallbacks;
     72   std::mutex mCallbacksLock;
     73 
     74   class SocketCallbacks : public ::android::chre::SocketClient::ICallbacks,
     75                           public ::android::chre::IChreMessageHandlers {
     76    public:
     77     SocketCallbacks(GenericContextHub& parent);
     78     void onMessageReceived(const void *data, size_t length) override;
     79     void onConnected() override;
     80     void onDisconnected() override;
     81 
     82     void handleNanoappMessage(
     83         const ::chre::fbs::NanoappMessageT& message) override;
     84 
     85     void handleHubInfoResponse(
     86         const ::chre::fbs::HubInfoResponseT& response) override;
     87 
     88     void handleNanoappListResponse(
     89         const ::chre::fbs::NanoappListResponseT& response) override;
     90 
     91     void handleLoadNanoappResponse(
     92       const ::chre::fbs::LoadNanoappResponseT& response) override;
     93 
     94     void handleUnloadNanoappResponse(
     95       const ::chre::fbs::UnloadNanoappResponseT& response) override;
     96 
     97     void handleDebugDumpData(
     98       const ::chre::fbs::DebugDumpDataT& data) override;
     99 
    100     void handleDebugDumpResponse(
    101       const ::chre::fbs::DebugDumpResponseT& response) override;
    102 
    103    private:
    104     GenericContextHub& mParent;
    105     bool mHaveConnected = false;
    106 
    107     /**
    108      * Acquires mParent.mCallbacksLock and invokes the synchronous callback
    109      * argument if mParent.mCallbacks is not null.
    110      */
    111     void invokeClientCallback(std::function<void()> callback);
    112   };
    113 
    114   class DeathRecipient : public hidl_death_recipient {
    115    public:
    116     DeathRecipient(const sp<GenericContextHub> contexthub);
    117     void serviceDied(uint64_t cookie,
    118                      const wp<::android::hidl::base::V1_0::IBase>& who)
    119         override;
    120 
    121    private:
    122     sp<GenericContextHub> mGenericContextHub;
    123   };
    124 
    125   sp<SocketCallbacks> mSocketCallbacks;
    126   sp<DeathRecipient> mDeathRecipient;
    127 
    128   // Cached hub info used for getHubs(), and synchronization primitives to make
    129   // that function call synchronous if we need to query it
    130   ContextHub mHubInfo;
    131   bool mHubInfoValid = false;
    132   std::mutex mHubInfoMutex;
    133   std::condition_variable mHubInfoCond;
    134 
    135   static constexpr int kInvalidFd = -1;
    136   int mDebugFd = kInvalidFd;
    137   bool mDebugDumpPending = false;
    138   std::mutex mDebugDumpMutex;
    139   std::condition_variable mDebugDumpCond;
    140 
    141   // The pending fragmented load request
    142   uint32_t mCurrentFragmentId = 0;
    143   std::optional<FragmentedLoadTransaction> mPendingLoadTransaction;
    144   std::mutex mPendingLoadTransactionMutex;
    145 
    146   // Use 30KB fragment size to fit within 32KB memory fragments at the kernel
    147   static constexpr size_t kLoadFragmentSizeBytes = 30 * 1024;
    148 
    149   // Write a string to mDebugFd
    150   void writeToDebugFile(const char *str);
    151   void writeToDebugFile(const char *str, size_t len);
    152 
    153   // Unregisters callback when context hub service dies
    154   void handleServiceDeath(uint32_t hubId);
    155 
    156   /**
    157    * Checks to see if a load response matches the currently pending
    158    * fragmented load transaction. mPendingLoadTransactionMutex must
    159    * be acquired prior to calling this function.
    160    *
    161    * @param response the received load response
    162    *
    163    * @return true if the response matches a pending load transaction
    164    *         (if any), false otherwise
    165    */
    166   bool isExpectedLoadResponseLocked(
    167       const ::chre::fbs::LoadNanoappResponseT& response);
    168 
    169   /**
    170    * Sends a fragmented load request to CHRE. The caller must ensure that
    171    * transaction.isComplete() returns false prior to invoking this method.
    172    *
    173    * @param transaction the FragmentedLoadTransaction object
    174    *
    175    * @return the result of the request
    176    */
    177   Result sendFragmentedLoadNanoAppRequest(
    178       FragmentedLoadTransaction& transaction);
    179 };
    180 
    181 extern "C" IContexthub* HIDL_FETCH_IContexthub(const char* name);
    182 
    183 }  // namespace implementation
    184 }  // namespace V1_0
    185 }  // namespace contexthub
    186 }  // namespace hardware
    187 }  // namespace android
    188 
    189 #endif  // ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H
    190