13d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie/* 23d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * Copyright (C) 2017 The Android Open Source Project 33d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * 43d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * Licensed under the Apache License, Version 2.0 (the "License"); 53d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * you may not use this file except in compliance with the License. 63d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * You may obtain a copy of the License at 73d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * 83d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * http://www.apache.org/licenses/LICENSE-2.0 93d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * 103d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * Unless required by applicable law or agreed to in writing, software 113d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * distributed under the License is distributed on an "AS IS" BASIS, 123d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * See the License for the specific language governing permissions and 143d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie * limitations under the License. 153d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie */ 163d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 173d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie#define LOG_TAG "ContextHubHal" 1847a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie#define LOG_NDEBUG 0 193d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 203d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie#include "generic_context_hub.h" 213d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 223d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie#include <chrono> 23a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie#include <cinttypes> 24a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie#include <vector> 253d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2658276308709e5568ba2976e93b37211a52589166Brian Duddie#include <unistd.h> 273d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie#include <utils/Log.h> 283d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 293d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace android { 303d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace hardware { 313d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace contexthub { 323d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace V1_0 { 333d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace implementation { 343d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 353d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieusing ::android::hardware::Return; 36a413add0b3504b1e8576235cea52b6738829feccBrian Duddieusing ::android::hardware::contexthub::V1_0::AsyncEventType; 373d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieusing ::android::hardware::contexthub::V1_0::Result; 3847a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddieusing ::android::hardware::contexthub::V1_0::TransactionResult; 393d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieusing ::android::chre::HostProtocolHost; 403d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieusing ::flatbuffers::FlatBufferBuilder; 413d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 4207da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie// Aliased for consistency with the way these symbols are referenced in 4307da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie// CHRE-side code 4407da7d6425058577d477074f99bafd4b8e81bb83Brian Duddienamespace fbs = ::chre::fbs; 4507da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie 463d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddienamespace { 473d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 483d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieconstexpr uint32_t kDefaultHubId = 0; 493d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 503d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieconstexpr uint8_t extractChreApiMajorVersion(uint32_t chreVersion) { 513d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return static_cast<uint8_t>(chreVersion >> 24); 523d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 533d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 543d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieconstexpr uint8_t extractChreApiMinorVersion(uint32_t chreVersion) { 553d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return static_cast<uint8_t>(chreVersion >> 16); 563d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 573d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 583d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddieconstexpr uint16_t extractChrePatchVersion(uint32_t chreVersion) { 593d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return static_cast<uint16_t>(chreVersion); 603d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 613d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 6258276308709e5568ba2976e93b37211a52589166Brian Duddie/** 6358276308709e5568ba2976e93b37211a52589166Brian Duddie * @return file descriptor contained in the hidl_handle, or -1 if there is none 6458276308709e5568ba2976e93b37211a52589166Brian Duddie */ 6558276308709e5568ba2976e93b37211a52589166Brian Duddieint hidlHandleToFileDescriptor(const hidl_handle& hh) { 6658276308709e5568ba2976e93b37211a52589166Brian Duddie const native_handle_t *handle = hh.getNativeHandle(); 6758276308709e5568ba2976e93b37211a52589166Brian Duddie return (handle->numFds >= 1) ? handle->data[0] : -1; 6858276308709e5568ba2976e93b37211a52589166Brian Duddie} 6958276308709e5568ba2976e93b37211a52589166Brian Duddie 703d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // anonymous namespace 713d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 72d38c43ca921506be8c6e310ffff5408e03cea848Arthur IshiguroGenericContextHub::DeathRecipient::DeathRecipient( 73d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro sp<GenericContextHub> contexthub) : mGenericContextHub(contexthub){} 74d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro 75d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishigurovoid GenericContextHub::DeathRecipient::serviceDied( 76d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& /* who */) { 77d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro uint32_t hubId = static_cast<uint32_t>(cookie); 78d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro mGenericContextHub->handleServiceDeath(hubId); 79d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro} 80d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro 813d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieGenericContextHub::GenericContextHub() { 823d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie constexpr char kChreSocketName[] = "chre"; 833d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 843d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mSocketCallbacks = new SocketCallbacks(*this); 853d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (!mClient.connectInBackground(kChreSocketName, mSocketCallbacks)) { 863d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGE("Couldn't start socket client"); 873d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 88d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro 89d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro mDeathRecipient = new DeathRecipient(this); 903d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 913d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 9258276308709e5568ba2976e93b37211a52589166Brian DuddieReturn<void> GenericContextHub::debug( 9358276308709e5568ba2976e93b37211a52589166Brian Duddie const hidl_handle& hh_fd, const hidl_vec<hidl_string>& /*options*/) { 9458276308709e5568ba2976e93b37211a52589166Brian Duddie // Timeout inside CHRE is typically 5 seconds, grant 500ms extra here to let 9558276308709e5568ba2976e93b37211a52589166Brian Duddie // the data reach us 9658276308709e5568ba2976e93b37211a52589166Brian Duddie constexpr auto kDebugDumpTimeout = std::chrono::milliseconds(5500); 9758276308709e5568ba2976e93b37211a52589166Brian Duddie 9858276308709e5568ba2976e93b37211a52589166Brian Duddie mDebugFd = hidlHandleToFileDescriptor(hh_fd); 9958276308709e5568ba2976e93b37211a52589166Brian Duddie if (mDebugFd < 0) { 10058276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGW("Can't dump debug info to invalid fd"); 10158276308709e5568ba2976e93b37211a52589166Brian Duddie } else { 10258276308709e5568ba2976e93b37211a52589166Brian Duddie writeToDebugFile("-- Dumping CHRE/ASH debug info --\n"); 10358276308709e5568ba2976e93b37211a52589166Brian Duddie 10458276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGV("Sending debug dump request"); 10558276308709e5568ba2976e93b37211a52589166Brian Duddie FlatBufferBuilder builder; 10658276308709e5568ba2976e93b37211a52589166Brian Duddie HostProtocolHost::encodeDebugDumpRequest(builder); 10758276308709e5568ba2976e93b37211a52589166Brian Duddie std::unique_lock<std::mutex> lock(mDebugDumpMutex); 10858276308709e5568ba2976e93b37211a52589166Brian Duddie mDebugDumpPending = true; 10958276308709e5568ba2976e93b37211a52589166Brian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 11058276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGW("Couldn't send debug dump request"); 11158276308709e5568ba2976e93b37211a52589166Brian Duddie } else { 11258276308709e5568ba2976e93b37211a52589166Brian Duddie mDebugDumpCond.wait_for(lock, kDebugDumpTimeout, 11358276308709e5568ba2976e93b37211a52589166Brian Duddie [this]() { return !mDebugDumpPending; }); 11458276308709e5568ba2976e93b37211a52589166Brian Duddie if (mDebugDumpPending) { 11558276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGI("Timed out waiting on debug dump data"); 11658276308709e5568ba2976e93b37211a52589166Brian Duddie mDebugDumpPending = false; 11758276308709e5568ba2976e93b37211a52589166Brian Duddie } 11858276308709e5568ba2976e93b37211a52589166Brian Duddie } 11958276308709e5568ba2976e93b37211a52589166Brian Duddie writeToDebugFile("\n-- End of CHRE/ASH debug info --\n"); 12058276308709e5568ba2976e93b37211a52589166Brian Duddie 12158276308709e5568ba2976e93b37211a52589166Brian Duddie mDebugFd = kInvalidFd; 12258276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGV("Debug dump complete"); 12358276308709e5568ba2976e93b37211a52589166Brian Duddie } 12458276308709e5568ba2976e93b37211a52589166Brian Duddie 12558276308709e5568ba2976e93b37211a52589166Brian Duddie return Void(); 12658276308709e5568ba2976e93b37211a52589166Brian Duddie} 12758276308709e5568ba2976e93b37211a52589166Brian Duddie 1283d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<void> GenericContextHub::getHubs(getHubs_cb _hidl_cb) { 1293d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie constexpr auto kHubInfoQueryTimeout = std::chrono::seconds(5); 1303d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie std::vector<ContextHub> hubs; 1313d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 1323d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1333d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // If we're not connected yet, give it some time 13488b885ff8b460d3b17053aae954a13720237a9b7Wei Wang // TODO refactor from polling into conditional wait 13588b885ff8b460d3b17053aae954a13720237a9b7Wei Wang int maxSleepIterations = 250; 1363d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie while (!mHubInfoValid && !mClient.isConnected() && --maxSleepIterations > 0) { 13788b885ff8b460d3b17053aae954a13720237a9b7Wei Wang std::this_thread::sleep_for(std::chrono::milliseconds(20)); 1383d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 1393d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1403d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (!mClient.isConnected()) { 1413d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGE("Couldn't connect to hub daemon"); 1423d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else if (!mHubInfoValid) { 1433d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // We haven't cached the hub details yet, so send a request and block 1443d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // waiting on a response 1453d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie std::unique_lock<std::mutex> lock(mHubInfoMutex); 1463d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie FlatBufferBuilder builder; 1473d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie HostProtocolHost::encodeHubInfoRequest(builder); 1483d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1493d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGD("Sending hub info request"); 1503d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 1513d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGE("Couldn't send hub info request"); 1523d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 1533d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mHubInfoCond.wait_for(lock, kHubInfoQueryTimeout, 1543d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie [this]() { return mHubInfoValid; }); 1553d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 1563d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 1573d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1583d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (mHubInfoValid) { 1593d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie hubs.push_back(mHubInfo); 1603d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 1613d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGE("Unable to get hub info from CHRE"); 1623d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 1633d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1643d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie _hidl_cb(hubs); 1653d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return Void(); 1663d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 1673d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1683d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::registerCallback( 1693d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint32_t hubId, const sp<IContexthubCallback>& cb) { 1703d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie Result result; 1713d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 1723d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1733d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // TODO: currently we only support 1 hub behind this HAL implementation 1743d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (hubId == kDefaultHubId) { 1756c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie std::lock_guard<std::mutex> lock(mCallbacksLock); 176d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro 177d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro if (cb != nullptr) { 178d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro if (mCallbacks != nullptr) { 179d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro ALOGD("Modifying callback for hubId %" PRIu32, hubId); 180d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro mCallbacks->unlinkToDeath(mDeathRecipient); 181d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro } 182d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro Return<bool> linkReturn = cb->linkToDeath(mDeathRecipient, hubId); 183d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro if (!linkReturn.withDefault(false)) { 184d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro ALOGW("Could not link death recipient to hubId %" PRIu32, hubId); 185d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro } 186d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro } 187d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro 1886c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie mCallbacks = cb; 1893d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie result = Result::OK; 1903d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 1913d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie result = Result::BAD_PARAMS; 1923d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 1933d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1943d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return result; 1953d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 1963d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 1973d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::sendMessageToHub(uint32_t hubId, 1983d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie const ContextHubMsg& msg) { 1993d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie Result result; 2003d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 2013d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2023d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (hubId != kDefaultHubId) { 2033d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie result = Result::BAD_PARAMS; 2043d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 2053d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie FlatBufferBuilder builder(1024); 2063d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie HostProtocolHost::encodeNanoappMessage( 2073d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie builder, msg.appName, msg.msgType, msg.hostEndPoint, msg.msg.data(), 2083d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie msg.msg.size()); 2093d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2103d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 2113d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie result = Result::UNKNOWN_FAILURE; 2123d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 2133d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie result = Result::OK; 2143d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 2153d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 2163d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2173d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return result; 2183d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 2193d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2203d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::loadNanoApp( 2213d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint32_t hubId, const NanoAppBinary& appBinary, uint32_t transactionId) { 22247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie Result result; 2233d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 22447a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 22547a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie if (hubId != kDefaultHubId) { 22647a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::BAD_PARAMS; 22747a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } else { 22847a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie FlatBufferBuilder builder(128 + appBinary.customBinary.size()); 22947a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie uint32_t targetApiVersion = (appBinary.targetChreApiMajorVersion << 24) | 23047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie (appBinary.targetChreApiMinorVersion << 16); 23147a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie HostProtocolHost::encodeLoadNanoappRequest( 23247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie builder, transactionId, appBinary.appId, appBinary.appVersion, 23347a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie targetApiVersion, appBinary.customBinary); 23447a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 23547a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::UNKNOWN_FAILURE; 23647a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } else { 23747a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::OK; 23847a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } 23947a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } 24047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 24147a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie ALOGD("Attempted to send load nanoapp request for app of size %zu with ID " 24247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie "0x%016" PRIx64 " as transaction ID %" PRIu32 ": result %" PRIu32, 24347a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie appBinary.customBinary.size(), appBinary.appId, transactionId, result); 24447a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 24547a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie return result; 2463d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 2473d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2483d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::unloadNanoApp( 2493d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint32_t hubId, uint64_t appId, uint32_t transactionId) { 25099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie Result result; 2513d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 25299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 25399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie if (hubId != kDefaultHubId) { 25499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie result = Result::BAD_PARAMS; 25599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie } else { 25699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie FlatBufferBuilder builder(64); 25799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie HostProtocolHost::encodeUnloadNanoappRequest( 25899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie builder, transactionId, appId, false /* allowSystemNanoappUnload */); 25999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 26099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie result = Result::UNKNOWN_FAILURE; 26199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie } else { 26299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie result = Result::OK; 26399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie } 26499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie } 26599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 26699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie ALOGD("Attempted to send unload nanoapp request for app ID 0x%016" PRIx64 26799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie " as transaction ID %" PRIu32 ": result %" PRIu32, appId, transactionId, 26899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie result); 26999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 27099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie return result; 2713d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 2723d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2733d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::enableNanoApp( 27499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie uint32_t /* hubId */, uint64_t appId, uint32_t /* transactionId */) { 2753d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // TODO 27699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie ALOGW("Attempted to enable app ID 0x%016" PRIx64 ", but not supported", 27799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie appId); 2786c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie return Result::TRANSACTION_FAILED; 2793d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 2803d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2813d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::disableNanoApp( 28299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie uint32_t /* hubId */, uint64_t appId, uint32_t /* transactionId */) { 2833d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie // TODO 28499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie ALOGW("Attempted to disable app ID 0x%016" PRIx64 ", but not supported", 28599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie appId); 2866c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie return Result::TRANSACTION_FAILED; 2873d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 2883d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 2893d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieReturn<Result> GenericContextHub::queryApps(uint32_t hubId) { 29047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie Result result; 2913d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGV("%s", __func__); 29247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 29347a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie if (hubId != kDefaultHubId) { 29447a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::BAD_PARAMS; 29547a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } else { 29647a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie FlatBufferBuilder builder(64); 29747a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie HostProtocolHost::encodeNanoappListRequest(builder); 29847a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { 29947a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::UNKNOWN_FAILURE; 30047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } else { 30147a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie result = Result::OK; 30247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } 30347a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie } 30447a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 3056c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie return result; 3063d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 3073d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3083d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieGenericContextHub::SocketCallbacks::SocketCallbacks(GenericContextHub& parent) 3093d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie : mParent(parent) {} 3103d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3113d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddievoid GenericContextHub::SocketCallbacks::onMessageReceived(const void *data, 3123d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie size_t length) { 3133d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (!HostProtocolHost::decodeMessageFromChre(data, length, *this)) { 3143d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGE("Failed to decode message"); 3153d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 3163d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 3173d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 318a413add0b3504b1e8576235cea52b6738829feccBrian Duddievoid GenericContextHub::SocketCallbacks::onConnected() { 319a413add0b3504b1e8576235cea52b6738829feccBrian Duddie if (mHaveConnected) { 320a413add0b3504b1e8576235cea52b6738829feccBrian Duddie ALOGI("Reconnected to CHRE daemon"); 3216c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie invokeClientCallback([&]() { 322a413add0b3504b1e8576235cea52b6738829feccBrian Duddie mParent.mCallbacks->handleHubEvent(AsyncEventType::RESTARTED); 3236c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie }); 324a413add0b3504b1e8576235cea52b6738829feccBrian Duddie } 325a413add0b3504b1e8576235cea52b6738829feccBrian Duddie mHaveConnected = true; 326a413add0b3504b1e8576235cea52b6738829feccBrian Duddie} 327a413add0b3504b1e8576235cea52b6738829feccBrian Duddie 328a413add0b3504b1e8576235cea52b6738829feccBrian Duddievoid GenericContextHub::SocketCallbacks::onDisconnected() { 329a413add0b3504b1e8576235cea52b6738829feccBrian Duddie ALOGW("Lost connection to CHRE daemon"); 330a413add0b3504b1e8576235cea52b6738829feccBrian Duddie} 331a413add0b3504b1e8576235cea52b6738829feccBrian Duddie 3323d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddievoid GenericContextHub::SocketCallbacks::handleNanoappMessage( 3333d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint64_t appId, uint32_t messageType, uint16_t hostEndpoint, 3343d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie const void *messageData, size_t messageDataLen) { 3356c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie ContextHubMsg msg; 3366c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie msg.appName = appId; 3376c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie msg.hostEndPoint = hostEndpoint; 3386c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie msg.msgType = messageType; 3396c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie 3406c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie // Dropping const from messageData when we wrap it in hidl_vec here. This is 3416c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie // safe because we won't modify it here, and the ContextHubMsg we pass to 3426c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie // the callback is const. 3436c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie msg.msg.setToExternal( 3446c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie const_cast<uint8_t *>(static_cast<const uint8_t *>(messageData)), 3456c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie messageDataLen, false /* shouldOwn */); 3466c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie invokeClientCallback([&]() { 3473d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mCallbacks->handleClientMsg(msg); 3486c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie }); 3493d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 3503d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3513d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddievoid GenericContextHub::SocketCallbacks::handleHubInfoResponse( 3523d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie const char *name, const char *vendor, 3533d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie const char *toolchain, uint32_t legacyPlatformVersion, 3543d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint32_t legacyToolchainVersion, float peakMips, float stoppedPower, 3553d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie float sleepPower, float peakPower, uint32_t maxMessageLen, 3563d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie uint64_t platformId, uint32_t version) { 3573d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGD("Got hub info response"); 3583d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3593d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie std::lock_guard<std::mutex> lock(mParent.mHubInfoMutex); 3603d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie if (mParent.mHubInfoValid) { 3613d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie ALOGI("Ignoring duplicate/unsolicited hub info response"); 3623d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } else { 3633d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.name = name; 3643d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.vendor = vendor; 3653d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.toolchain = toolchain; 3663d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.platformVersion = legacyPlatformVersion; 3673d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.toolchainVersion = legacyToolchainVersion; 3683d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.hubId = kDefaultHubId; 3693d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3703d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.peakMips = peakMips; 3713d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.stoppedPowerDrawMw = stoppedPower; 3723d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.sleepPowerDrawMw = sleepPower; 3733d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.peakPowerDrawMw = peakPower; 3743d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3753d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.maxSupportedMsgLen = maxMessageLen; 3763d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.chrePlatformId = platformId; 3773d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3783d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.chreApiMajorVersion = extractChreApiMajorVersion(version); 3793d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.chreApiMinorVersion = extractChreApiMinorVersion(version); 3803d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfo.chrePatchVersion = extractChrePatchVersion(version); 3813d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 3823d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfoValid = true; 3833d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie mParent.mHubInfoCond.notify_all(); 3843d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie } 3853d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 3863d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 387a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddievoid GenericContextHub::SocketCallbacks::handleNanoappListResponse( 38807da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie const fbs::NanoappListResponseT& response) { 389a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie std::vector<HubAppInfo> appInfoList; 390a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 39107da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie ALOGV("Got nanoapp list response with %zu apps", response.nanoapps.size()); 39207da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie for (const std::unique_ptr<fbs::NanoappListEntryT>& nanoapp 39307da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie : response.nanoapps) { 39407da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie // TODO: determine if this is really required, and if so, have 39507da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie // HostProtocolHost strip out null entries as part of decode 39607da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie if (nanoapp == nullptr) { 39707da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie continue; 39807da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie } 39907da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie 400a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie ALOGV("App 0x%016" PRIx64 " ver 0x%" PRIx32 " enabled %d system %d", 40107da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie nanoapp->app_id, nanoapp->version, nanoapp->enabled, 40207da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie nanoapp->is_system); 40307da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie if (!nanoapp->is_system) { 404a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie HubAppInfo appInfo; 405a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 40607da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie appInfo.appId = nanoapp->app_id; 40707da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie appInfo.version = nanoapp->version; 40807da7d6425058577d477074f99bafd4b8e81bb83Brian Duddie appInfo.enabled = nanoapp->enabled; 409a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 410a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie appInfoList.push_back(appInfo); 411a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie } 412a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie } 413a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 4146c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie invokeClientCallback([&]() { 4156c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie mParent.mCallbacks->handleAppsInfo(appInfoList); 4166c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie }); 417a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie} 418a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie 41947a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddievoid GenericContextHub::SocketCallbacks::handleLoadNanoappResponse( 42047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie const ::chre::fbs::LoadNanoappResponseT& response) { 42147a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie ALOGV("Got load nanoapp response for transaction %" PRIu32 " with result %d", 42247a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie response.transaction_id, response.success); 42347a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 4246c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie invokeClientCallback([&]() { 4256c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie TransactionResult result = (response.success) ? 4266c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie TransactionResult::SUCCESS : TransactionResult::FAILURE; 4276c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie mParent.mCallbacks->handleTxnResult(response.transaction_id, result); 4286c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie }); 42947a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie} 43047a99dc3cacacb0418548609c0e2d3b2b70d821eBrian Duddie 43199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddievoid GenericContextHub::SocketCallbacks::handleUnloadNanoappResponse( 43299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie const ::chre::fbs::UnloadNanoappResponseT& response) { 43399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie ALOGV("Got unload nanoapp response for transaction %" PRIu32 " with result " 43499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie "%d", response.transaction_id, response.success); 43599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 43699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie invokeClientCallback([&]() { 43799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie TransactionResult result = (response.success) ? 43899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie TransactionResult::SUCCESS : TransactionResult::FAILURE; 43999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie mParent.mCallbacks->handleTxnResult(response.transaction_id, result); 44099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie }); 44199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie} 44299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie 44358276308709e5568ba2976e93b37211a52589166Brian Duddievoid GenericContextHub::SocketCallbacks::handleDebugDumpData( 44458276308709e5568ba2976e93b37211a52589166Brian Duddie const ::chre::fbs::DebugDumpDataT& data) { 44558276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGV("Got debug dump data, size %zu", data.debug_str.size()); 44658276308709e5568ba2976e93b37211a52589166Brian Duddie if (mParent.mDebugFd == kInvalidFd) { 44758276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGW("Got unexpected debug dump data message"); 44858276308709e5568ba2976e93b37211a52589166Brian Duddie } else { 44958276308709e5568ba2976e93b37211a52589166Brian Duddie mParent.writeToDebugFile( 45058276308709e5568ba2976e93b37211a52589166Brian Duddie reinterpret_cast<const char *>(data.debug_str.data()), 45158276308709e5568ba2976e93b37211a52589166Brian Duddie data.debug_str.size()); 45258276308709e5568ba2976e93b37211a52589166Brian Duddie } 45358276308709e5568ba2976e93b37211a52589166Brian Duddie} 45458276308709e5568ba2976e93b37211a52589166Brian Duddie 45558276308709e5568ba2976e93b37211a52589166Brian Duddievoid GenericContextHub::SocketCallbacks::handleDebugDumpResponse( 45658276308709e5568ba2976e93b37211a52589166Brian Duddie const ::chre::fbs::DebugDumpResponseT& response) { 45758276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGV("Got debug dump response, success %d, data count %" PRIu32, 45858276308709e5568ba2976e93b37211a52589166Brian Duddie response.success, response.data_count); 45958276308709e5568ba2976e93b37211a52589166Brian Duddie std::lock_guard<std::mutex> lock(mParent.mDebugDumpMutex); 46058276308709e5568ba2976e93b37211a52589166Brian Duddie if (!mParent.mDebugDumpPending) { 46158276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGI("Ignoring duplicate/unsolicited debug dump response"); 46258276308709e5568ba2976e93b37211a52589166Brian Duddie } else { 46358276308709e5568ba2976e93b37211a52589166Brian Duddie mParent.mDebugDumpPending = false; 46458276308709e5568ba2976e93b37211a52589166Brian Duddie mParent.mDebugDumpCond.notify_all(); 46558276308709e5568ba2976e93b37211a52589166Brian Duddie } 46658276308709e5568ba2976e93b37211a52589166Brian Duddie} 46758276308709e5568ba2976e93b37211a52589166Brian Duddie 4686c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddievoid GenericContextHub::SocketCallbacks::invokeClientCallback( 4696c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie std::function<void()> callback) { 4706c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie std::lock_guard<std::mutex> lock(mParent.mCallbacksLock); 4716c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie if (mParent.mCallbacks != nullptr) { 4726c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie callback(); 4736c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie } 4746c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie} 4756c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie 47658276308709e5568ba2976e93b37211a52589166Brian Duddievoid GenericContextHub::writeToDebugFile(const char *str) { 47758276308709e5568ba2976e93b37211a52589166Brian Duddie writeToDebugFile(str, strlen(str)); 47858276308709e5568ba2976e93b37211a52589166Brian Duddie} 47958276308709e5568ba2976e93b37211a52589166Brian Duddie 48058276308709e5568ba2976e93b37211a52589166Brian Duddievoid GenericContextHub::writeToDebugFile(const char *str, size_t len) { 48158276308709e5568ba2976e93b37211a52589166Brian Duddie ssize_t written = write(mDebugFd, str, len); 48258276308709e5568ba2976e93b37211a52589166Brian Duddie if (written != (ssize_t) len) { 48358276308709e5568ba2976e93b37211a52589166Brian Duddie ALOGW("Couldn't write to debug header: returned %zd, expected %zu " 48458276308709e5568ba2976e93b37211a52589166Brian Duddie "(errno %d)", written, len, errno); 48558276308709e5568ba2976e93b37211a52589166Brian Duddie } 48658276308709e5568ba2976e93b37211a52589166Brian Duddie} 48758276308709e5568ba2976e93b37211a52589166Brian Duddie 488d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishigurovoid GenericContextHub::handleServiceDeath(uint32_t hubId) { 489d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro std::lock_guard<std::mutex> lock(mCallbacksLock); 490d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro ALOGI("Context hub service died for hubId %" PRIu32, hubId); 491d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro mCallbacks.clear(); 492d38c43ca921506be8c6e310ffff5408e03cea848Arthur Ishiguro} 4936c90e539c79a443c18adbf9f77238b3828ac2bf4Brian Duddie 4943d891e3fa75ff638c03d5083a47161c044cbfad8Brian DuddieIContexthub* HIDL_FETCH_IContexthub(const char* /* name */) { 4953d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie return new GenericContextHub(); 4963d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} 4973d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie 4983d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // namespace implementation 4993d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // namespace V1_0 5003d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // namespace contexthub 5013d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // namespace hardware 5023d891e3fa75ff638c03d5083a47161c044cbfad8Brian Duddie} // namespace android 503