blob: e769cb559efbd65370506a9adaced0b5a56b9001 [file] [log] [blame]
Steven Morelandff189a02017-09-15 16:22:48 -07001/*
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#include <hidladapter/HidlBinderAdapter.h>
18
19#include <android/hidl/base/1.0/IBase.h>
20#include <android/hidl/manager/1.0/IServiceManager.h>
21#include <hidl/HidlTransportSupport.h>
22
23#include <iostream>
24#include <map>
25#include <string>
26
27namespace android {
28namespace hardware {
29namespace details {
30
31int adapterMain(const std::string& package, int argc, char** argv,
32 const AdaptersFactory& adapters) {
33 using android::hardware::configureRpcThreadpool;
34 using android::hidl::base::V1_0::IBase;
35 using android::hidl::manager::V1_0::IServiceManager;
36
37 if (argc != 4) {
38 std::cerr << "usage: " << argv[0] << " interface-name instance-name number-of-threads."
39 << std::endl;
40 return 1;
41 }
42
43 std::string interfaceName = package + "::" + argv[1];
44 std::string instanceName = argv[2];
45 int threadNumber = std::stoi(argv[3]);
46
47 if (threadNumber <= 0) {
48 std::cerr << "ERROR: invalid thread number " << threadNumber
49 << " must be a positive integer.";
50 }
51
52 auto it = adapters.find(interfaceName);
53 if (it == adapters.end()) {
54 std::cerr << "ERROR: could not resolve " << interfaceName << "." << std::endl;
55 return 1;
56 }
57
58 std::cout << "Trying to adapt down " << interfaceName << "/" << instanceName << std::endl;
59
60 configureRpcThreadpool(threadNumber, false /* callerWillJoin */);
61
62 sp<IServiceManager> manager = IServiceManager::getService();
63 if (manager == nullptr) {
64 std::cerr << "ERROR: could not retrieve service manager." << std::endl;
65 return 1;
66 }
67
68 sp<IBase> implementation = manager->get(interfaceName, instanceName).withDefault(nullptr);
69 if (implementation == nullptr) {
70 std::cerr << "ERROR: could not retrieve desired implementation" << std::endl;
71 return 1;
72 }
73
74 sp<IBase> adapter = it->second(implementation);
75 if (adapter == nullptr) {
76 std::cerr << "ERROR: could not create adapter." << std::endl;
77 return 1;
78 }
79
80 bool replaced = manager->add(instanceName, adapter).withDefault(false);
81 if (!replaced) {
82 std::cerr << "ERROR: could not register the service with the service manager." << std::endl;
83 return 1;
84 }
85
86 std::cout << "Press any key to disassociate adapter." << std::endl;
87 getchar();
88
89 bool restored = manager->add(instanceName, implementation).withDefault(false);
90 if (!restored) {
91 std::cerr << "ERROR: could not re-register interface with the service manager."
92 << std::endl;
93 return 1;
94 }
95
96 std::cout << "Success." << std::endl;
97
98 return 0;
99}
100
101// If an interface is adapted to 1.0, it can then not be adapted to 1.1 in the same process.
102// This poses a problem in the following scenario:
103// auto interface = new V1_1::implementation::IFoo;
104// hidlObject1_0->foo(interface) // adaptation set at 1.0
105// hidlObject1_1->bar(interface) // adaptation still is 1.0
106// This could be solved by keeping a map of IBase,fqName -> IBase, but then you end up
107// with multiple names for the same interface.
108sp<IBase> adaptWithDefault(const sp<IBase>& something,
109 const std::function<sp<IBase>()>& makeDefault) {
110 static std::map<sp<IBase>, sp<IBase>> sAdapterMap;
111
112 auto it = sAdapterMap.find(something);
113 if (it == sAdapterMap.end()) {
114 it = sAdapterMap.insert(it, {something, makeDefault()});
115 }
116
117 return it->second;
118}
119
120} // namespace details
121} // namespace hardware
122} // namespace android