1 /*
2  * Copyright (C) 2019 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 "WaitCommand.h"
18 
19 #include "Lshal.h"
20 
21 #include <hidl/ServiceManagement.h>
22 #include <hidl-util/FQName.h>
23 
24 namespace android {
25 namespace lshal {
26 
getName() const27 std::string WaitCommand::getName() const {
28     return "wait";
29 }
30 
getSimpleDescription() const31 std::string WaitCommand::getSimpleDescription() const {
32     return "Wait for HAL to start if it is not already started.";
33 }
34 
parseArgs(const Arg & arg)35 Status WaitCommand::parseArgs(const Arg &arg) {
36     if (optind + 1 != arg.argc) {
37         return USAGE;
38     }
39 
40     mInterfaceName = arg.argv[optind];
41     ++optind;
42     return OK;
43 }
44 
main(const Arg & arg)45 Status WaitCommand::main(const Arg &arg) {
46     Status status = parseArgs(arg);
47     if (status != OK) {
48         return status;
49     }
50 
51     auto [interface, instance] = splitFirst(mInterfaceName, '/');
52     instance = instance.empty() ? "default" : instance;
53 
54     FQName fqName;
55     if (!FQName::parse(interface, &fqName) || fqName.isIdentifier() || !fqName.isFullyQualified()) {
56         mLshal.err() << "Invalid fully-qualified name '" << interface << "'\n\n";
57         return USAGE;
58     }
59 
60     using android::hidl::manager::V1_0::IServiceManager;
61 
62     using android::hardware::details::getRawServiceInternal;
63     auto service = getRawServiceInternal(interface, instance, true /*retry*/, false /*getStub*/);
64 
65     if (service == nullptr) {
66         mLshal.err() << "Service not found (missing permissions or not in VINTF manifest?).\n";
67         return NO_INTERFACE;
68     }
69 
70     return OK;
71 }
72 
usage() const73 void WaitCommand::usage() const {
74     static const std::string debug =
75             "wait:\n"
76             "    lshal wait <interface/instance> \n"
77             "        For a HAL that is on the device, wait for the HAL to start.\n"
78             "        This will not start a HAL unless it is configured as a lazy HAL.\n"
79             "        <interface>: Format is `android.hardware.foo@1.0::IFoo/default`.\n"
80             "            If instance name is missing `default` is used.\n";
81 
82     mLshal.err() << debug;
83 }
84 
85 }  // namespace lshal
86 }  // namespace android
87 
88