blob: f28446e30c012fdd36248edcd47455b62eabb560 [file] [log] [blame]
Pawin Vongmasa155e9d32017-03-09 06:38:22 -08001/*
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#define LOG_TAG "HybridInterface"
18
19#include <utils/Log.h>
20#include <hidl/HybridInterface.h>
21#include <hidl/HidlSupport.h>
22#include <android/hidl/token/1.0/ITokenManager.h>
23
24namespace android {
25
26using ::android::hidl::token::V1_0::ITokenManager;
27
28namespace {
29
30std::mutex gTokenManagerLock;
31sp<ITokenManager> gTokenManager = nullptr;
32
33struct TokenManagerDeathRecipient : public hardware::hidl_death_recipient {
34 void serviceDied(uint64_t, const wp<HInterface>&) {
35 std::lock_guard<std::mutex> lock(gTokenManagerLock);
36 gTokenManager = nullptr;
37 }
38};
39
40sp<TokenManagerDeathRecipient> gTokenManagerDeathRecipient =
41 new TokenManagerDeathRecipient();
42
43bool isBadTokenManager() {
44 if (gTokenManager != nullptr) {
45 return false;
46 }
47 gTokenManager = ITokenManager::getService();
48 if (gTokenManager == nullptr) {
49 ALOGE("Cannot retrieve TokenManager.");
50 return true;
51 }
52 auto transaction = gTokenManager->linkToDeath(
53 gTokenManagerDeathRecipient, 0);
54 if (!transaction.isOk()) {
55 ALOGE("Cannot observe TokenManager's death.");
56 gTokenManager = nullptr;
57 return true;
58 }
59 return false;
60}
61
62template <typename ReturnType>
63bool isBadTransaction(hardware::Return<ReturnType>& transaction) {
64 if (transaction.isOk()) {
65 return false;
66 }
67 ALOGE("TokenManager's transaction error: %s",
68 transaction.description().c_str());
69 gTokenManager->unlinkToDeath(gTokenManagerDeathRecipient).isOk();
70 gTokenManager = nullptr;
71 return true;
72}
73
74} // unnamed namespace
75
76sp<HInterface> retrieveHalInterface(const HalToken& token) {
77 hardware::Return<sp<HInterface> > transaction(nullptr);
78 {
79 std::lock_guard<std::mutex> lock(gTokenManagerLock);
80 if (isBadTokenManager()) {
81 return nullptr;
82 }
83 transaction = gTokenManager->get(token);
84 if (isBadTransaction(transaction)) {
85 return nullptr;
86 }
87 }
88 return static_cast<sp<HInterface> >(transaction);
89}
90
91bool createHalToken(const sp<HInterface>& interface, HalToken* token) {
92 hardware::Return<HalToken> transaction(false);
93 {
94 std::lock_guard<std::mutex> lock(gTokenManagerLock);
95 if (isBadTokenManager()) {
96 return false;
97 }
98 transaction = gTokenManager->createToken(interface);
99 if (isBadTransaction(transaction)) {
100 return false;
101 }
102 }
103 *token = static_cast<HalToken>(transaction);
104 return true;
105}
106
107bool deleteHalToken(const HalToken& token) {
108 hardware::Return<bool> transaction(false);
109 {
110 std::lock_guard<std::mutex> lock(gTokenManagerLock);
111 if (isBadTokenManager()) {
112 return false;
113 }
114 transaction = gTokenManager->unregister(token);
115 if (isBadTransaction(transaction)) {
116 return false;
117 }
118 }
119 return static_cast<bool>(transaction);
120}
121
122}; // namespace android
123