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