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