blob: 106ad4e2112c52ee0d50830af400ea69b213ba36 [file] [log] [blame]
Pawin Vongmasa3bfdaf12017-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) {
Steven Moreland15716d52017-03-16 02:01:22 -070092 hardware::Return<void> transaction;
Pawin Vongmasa3bfdaf12017-03-09 06:38:22 -080093 {
94 std::lock_guard<std::mutex> lock(gTokenManagerLock);
95 if (isBadTokenManager()) {
96 return false;
97 }
Steven Moreland15716d52017-03-16 02:01:22 -070098 transaction = gTokenManager->createToken(interface, [&](const HalToken &newToken) {
99 *token = newToken;
100 });
Pawin Vongmasa3bfdaf12017-03-09 06:38:22 -0800101 }
Steven Moreland15716d52017-03-16 02:01:22 -0700102 return !isBadTransaction(transaction);
Pawin Vongmasa3bfdaf12017-03-09 06:38:22 -0800103}
104
105bool deleteHalToken(const HalToken& token) {
106 hardware::Return<bool> transaction(false);
107 {
108 std::lock_guard<std::mutex> lock(gTokenManagerLock);
109 if (isBadTokenManager()) {
110 return false;
111 }
112 transaction = gTokenManager->unregister(token);
113 if (isBadTransaction(transaction)) {
114 return false;
115 }
116 }
117 return static_cast<bool>(transaction);
118}
119
120}; // namespace android
121