1 /*
2  * Copyright (C) 2016 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 <unistd.h>
18 
19 #include <hidl/HidlTransportSupport.h>
20 #include <utils/Errors.h>
21 #include <utils/StrongPointer.h>
22 #include <utils/Log.h>
23 
24 #include "ServiceNames.h"
25 #include "Enumerator.h"
26 
27 
28 // libhidl:
29 using android::hardware::configureRpcThreadpool;
30 using android::hardware::joinRpcThreadpool;
31 
32 // Generated HIDL files
33 using android::hardware::automotive::evs::V1_0::IEvsEnumerator;
34 using android::hardware::automotive::evs::V1_0::IEvsDisplay;
35 
36 // The namespace in which all our implementation code lives
37 using namespace android::automotive::evs::V1_0::implementation;
38 using namespace android;
39 
40 
startService(const char * hardwareServiceName,const char * managerServiceName)41 static void startService(const char *hardwareServiceName, const char * managerServiceName) {
42     ALOGI("EVS managed service connecting to hardware service at %s", hardwareServiceName);
43     android::sp<Enumerator> service = new Enumerator();
44     if (!service->init(hardwareServiceName)) {
45         ALOGE("Failed to connect to hardware service - quitting from registrationThread");
46         exit(1);
47     }
48 
49     // Register our service -- if somebody is already registered by our name,
50     // they will be killed (their thread pool will throw an exception).
51     ALOGI("EVS managed service is starting as %s", managerServiceName);
52     status_t status = service->registerAsService(managerServiceName);
53     if (status != OK) {
54         ALOGE("Could not register service %s (%d) - quitting from registrationThread",
55               managerServiceName, status);
56         exit(2);
57     }
58 
59     ALOGD("Registration complete");
60 }
61 
62 
main(int argc,char ** argv)63 int main(int argc, char** argv) {
64     ALOGI("EVS manager starting\n");
65 
66     // Set up default behavior, then check for command line options
67     bool printHelp = false;
68     const char* evsHardwareServiceName = kHardwareEnumeratorName;
69     for (int i=1; i< argc; i++) {
70         if (strcmp(argv[i], "--mock") == 0) {
71             evsHardwareServiceName = kMockEnumeratorName;
72         } else if (strcmp(argv[i], "--target") == 0) {
73             i++;
74             if (i >= argc) {
75                 ALOGE("--target <service> was not provided with a service name\n");
76             } else {
77                 evsHardwareServiceName = argv[i];
78             }
79         } else if (strcmp(argv[i], "--help") == 0) {
80             printHelp = true;
81         } else {
82             printf("Ignoring unrecognized command line arg '%s'\n", argv[i]);
83             printHelp = true;
84         }
85     }
86     if (printHelp) {
87         printf("Options include:\n");
88         printf("  --mock                   Connect to the mock driver at EvsEnumeratorHw-Mock\n");
89         printf("  --target <service_name>  Connect to the named IEvsEnumerator service");
90     }
91 
92 
93     // Prepare the RPC serving thread pool.  We're configuring it with no additional
94     // threads beyond the main thread which will "join" the pool below.
95     configureRpcThreadpool(1, true /* callerWillJoin */);
96 
97     // The connection to the underlying hardware service must happen on a dedicated thread to ensure
98     // that the hwbinder response can be processed by the thread pool without blocking.
99     std::thread registrationThread(startService, evsHardwareServiceName, kManagedEnumeratorName);
100 
101     // Send this main thread to become a permanent part of the thread pool.
102     // This is not expected to return.
103     ALOGD("Main thread entering thread pool");
104     joinRpcThreadpool();
105 
106     // In normal operation, we don't expect the thread pool to exit
107     ALOGE("EVS Hardware Enumerator is shutting down");
108     return 1;
109 }
110