13bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa/* 23bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Copyright (C) 2017 The Android Open Source Project 33bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 43bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Licensed under the Apache License, Version 2.0 (the "License"); 53bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * you may not use this file except in compliance with the License. 63bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * You may obtain a copy of the License at 73bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 83bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * http://www.apache.org/licenses/LICENSE-2.0 93bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Unless required by applicable law or agreed to in writing, software 113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * distributed under the License is distributed on an "AS IS" BASIS, 123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * See the License for the specific language governing permissions and 143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * limitations under the License. 153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa */ 163bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 173bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#define LOG_TAG "HybridInterface" 183bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 193bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <utils/Log.h> 203bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <hidl/HybridInterface.h> 213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <hidl/HidlSupport.h> 223bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <android/hidl/token/1.0/ITokenManager.h> 233bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 243bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasanamespace android { 253bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 263bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasausing ::android::hidl::token::V1_0::ITokenManager; 273bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 283bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasanamespace { 293bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 303bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasastd::mutex gTokenManagerLock; 313bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasasp<ITokenManager> gTokenManager = nullptr; 323bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 333bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasastruct TokenManagerDeathRecipient : public hardware::hidl_death_recipient { 343bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa void serviceDied(uint64_t, const wp<HInterface>&) { 353bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa std::lock_guard<std::mutex> lock(gTokenManagerLock); 363bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManager = nullptr; 373bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 383bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}; 393bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 403bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasasp<TokenManagerDeathRecipient> gTokenManagerDeathRecipient = 413bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa new TokenManagerDeathRecipient(); 423bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 433bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool isBadTokenManager() { 443bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (gTokenManager != nullptr) { 453bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 463bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 473bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManager = ITokenManager::getService(); 483bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (gTokenManager == nullptr) { 493bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa ALOGE("Cannot retrieve TokenManager."); 503bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return true; 513bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 523bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa auto transaction = gTokenManager->linkToDeath( 533bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManagerDeathRecipient, 0); 543bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (!transaction.isOk()) { 553bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa ALOGE("Cannot observe TokenManager's death."); 563bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManager = nullptr; 573bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return true; 583bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 593bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 603bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} 613bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 623bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <typename ReturnType> 633bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool isBadTransaction(hardware::Return<ReturnType>& transaction) { 643bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (transaction.isOk()) { 653bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 663bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 673bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa ALOGE("TokenManager's transaction error: %s", 683bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa transaction.description().c_str()); 693bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManager->unlinkToDeath(gTokenManagerDeathRecipient).isOk(); 703bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa gTokenManager = nullptr; 713bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return true; 723bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} 733bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 743bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} // unnamed namespace 753bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 763bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasasp<HInterface> retrieveHalInterface(const HalToken& token) { 773bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa hardware::Return<sp<HInterface> > transaction(nullptr); 783bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa { 793bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa std::lock_guard<std::mutex> lock(gTokenManagerLock); 803bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (isBadTokenManager()) { 813bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return nullptr; 823bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 833bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa transaction = gTokenManager->get(token); 843bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (isBadTransaction(transaction)) { 853bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return nullptr; 863bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 873bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 883bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return static_cast<sp<HInterface> >(transaction); 893bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} 903bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 913bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool createHalToken(const sp<HInterface>& interface, HalToken* token) { 9215716d525cff9487897e0841fa47092a30293d92Steven Moreland hardware::Return<void> transaction; 933bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa { 943bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa std::lock_guard<std::mutex> lock(gTokenManagerLock); 953bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (isBadTokenManager()) { 963bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 973bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 9815716d525cff9487897e0841fa47092a30293d92Steven Moreland transaction = gTokenManager->createToken(interface, [&](const HalToken &newToken) { 9915716d525cff9487897e0841fa47092a30293d92Steven Moreland *token = newToken; 10015716d525cff9487897e0841fa47092a30293d92Steven Moreland }); 1013bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 10215716d525cff9487897e0841fa47092a30293d92Steven Moreland return !isBadTransaction(transaction); 1033bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} 1043bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 1053bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool deleteHalToken(const HalToken& token) { 1063bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa hardware::Return<bool> transaction(false); 1073bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa { 1083bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa std::lock_guard<std::mutex> lock(gTokenManagerLock); 1093bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (isBadTokenManager()) { 1103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 1113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 1123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa transaction = gTokenManager->unregister(token); 1133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa if (isBadTransaction(transaction)) { 1143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return false; 1153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 1163bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa } 1173bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa return static_cast<bool>(transaction); 1183bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa} 1193bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 1203bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}; // namespace android 1213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa 122