1 /*
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
24 namespace android {
25
26 using ::android::hidl::token::V1_0::ITokenManager;
27
28 namespace {
29
30 std::mutex gTokenManagerLock;
31 sp<ITokenManager> gTokenManager = nullptr;
32
33 struct TokenManagerDeathRecipient : public hardware::hidl_death_recipient {
serviceDiedandroid::__anoncf14cfe80111::TokenManagerDeathRecipient34 void serviceDied(uint64_t, const wp<HInterface>&) {
35 std::lock_guard<std::mutex> lock(gTokenManagerLock);
36 gTokenManager = nullptr;
37 }
38 };
39
40 sp<TokenManagerDeathRecipient> gTokenManagerDeathRecipient =
41 new TokenManagerDeathRecipient();
42
isBadTokenManager()43 bool 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
62 template <typename ReturnType>
isBadTransaction(hardware::Return<ReturnType> & transaction)63 bool 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
retrieveHalInterface(const HalToken & token)76 sp<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
createHalToken(const sp<HInterface> & interface,HalToken * token)91 bool createHalToken(const sp<HInterface>& interface, HalToken* token) {
92 hardware::Return<void> transaction;
93 {
94 std::lock_guard<std::mutex> lock(gTokenManagerLock);
95 if (isBadTokenManager()) {
96 return false;
97 }
98 transaction = gTokenManager->createToken(interface, [&](const HalToken &newToken) {
99 *token = newToken;
100 });
101 }
102 return !isBadTransaction(transaction);
103 }
104
deleteHalToken(const HalToken & token)105 bool 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