summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2017-05-09 19:33:08 -0700
committerYifan Hong <elsk@google.com>2017-05-12 12:47:43 -0700
commit48dc9f8586c288e152bdd5e14423281764f8db5f (patch)
treefd168878fff560b5b8d4e3cd69408cf91ebea743
parent443df7932cedd88d523164ac7175fa19ec553c7b (diff)
downloadnative-48dc9f8586c288e152bdd5e14423281764f8db5f.tar.gz
Add `lshal debug` command.
Supported command: lshal debug android.hardware.foo@1.0::IFoo option option Test: adb unroot && lshal --debug ; echo $? Test: adb unroot && lshal debug android.hardware.nfc@1.0::INfc ; echo $? Test: adb root && lshal --debug ; echo $? Test: adb root && lshal debug android.hardware.nfc@1.0::INfc ; echo $? Bug: 37954458 Change-Id: Ia2f4c9c0d3fb0a7bb26e76f01d02f49dc426e7f8
-rw-r--r--cmds/lshal/Android.bp1
-rw-r--r--cmds/lshal/DebugCommand.cpp54
-rw-r--r--cmds/lshal/DebugCommand.h49
-rw-r--r--cmds/lshal/ListCommand.cpp18
-rw-r--r--cmds/lshal/Lshal.cpp54
-rw-r--r--cmds/lshal/Lshal.h6
-rw-r--r--cmds/lshal/utils.h2
7 files changed, 152 insertions, 32 deletions
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 6489ea0415..74f78650a8 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -24,6 +24,7 @@ cc_binary {
"libvintf",
],
srcs: [
+ "DebugCommand.cpp",
"Lshal.cpp",
"ListCommand.cpp",
"PipeRelay.cpp",
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
new file mode 100644
index 0000000000..672cad67cb
--- /dev/null
+++ b/cmds/lshal/DebugCommand.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DebugCommand.h"
+
+#include "Lshal.h"
+
+namespace android {
+namespace lshal {
+
+DebugCommand::DebugCommand(Lshal &lshal) : mLshal(lshal) {
+}
+
+Status DebugCommand::parseArgs(const std::string &command, const Arg &arg) {
+ if (optind >= arg.argc) {
+ mLshal.usage(command);
+ return USAGE;
+ }
+ mInterfaceName = arg.argv[optind];
+ ++optind;
+ for (; optind < arg.argc; ++optind) {
+ mOptions.push_back(arg.argv[optind]);
+ }
+ return OK;
+}
+
+Status DebugCommand::main(const std::string &command, const Arg &arg) {
+ Status status = parseArgs(command, arg);
+ if (status != OK) {
+ return status;
+ }
+ auto pair = splitFirst(mInterfaceName, '/');
+ return mLshal.emitDebugInfo(
+ pair.first, pair.second.empty() ? "default" : pair.second, mOptions,
+ mLshal.out().buf(),
+ mLshal.err());
+}
+
+} // namespace lshal
+} // namespace android
+
diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h
new file mode 100644
index 0000000000..fa0f0faafb
--- /dev/null
+++ b/cmds/lshal/DebugCommand.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FRAMEWORK_NATIVE_CMDS_LSHAL_DEBUG_COMMAND_H_
+#define FRAMEWORK_NATIVE_CMDS_LSHAL_DEBUG_COMMAND_H_
+
+#include <string>
+
+#include <android-base/macros.h>
+
+#include "utils.h"
+
+namespace android {
+namespace lshal {
+
+class Lshal;
+
+class DebugCommand {
+public:
+ DebugCommand(Lshal &lshal);
+ Status main(const std::string &command, const Arg &arg);
+private:
+ Status parseArgs(const std::string &command, const Arg &arg);
+
+ Lshal &mLshal;
+ std::string mInterfaceName;
+ std::vector<std::string> mOptions;
+
+ DISALLOW_COPY_AND_ASSIGN(DebugCommand);
+};
+
+
+} // namespace lshal
+} // namespace android
+
+#endif // FRAMEWORK_NATIVE_CMDS_LSHAL_DEBUG_COMMAND_H_
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 5696843336..a0ed7a346f 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -350,15 +350,6 @@ void ListCommand::dumpTable() {
printLine("Interface", "Transport", "Arch", "Server", "Server CMD",
"PTR", "Clients", "Clients CMD");
- // We're only interested in dumping debug info for already
- // instantiated services. There's little value in dumping the
- // debug info for a service we create on the fly, so we only operate
- // on the "mServicesTable".
- sp<IServiceManager> serviceManager;
- if (mEmitDebugInfo && &table == &mServicesTable) {
- serviceManager = ::android::hardware::defaultServiceManager();
- }
-
for (const auto &entry : table) {
printLine(entry.interfaceName,
entry.transport,
@@ -369,9 +360,14 @@ void ListCommand::dumpTable() {
join(entry.clientPids, " "),
join(entry.clientCmdlines, ";"));
- if (serviceManager != nullptr) {
+ // We're only interested in dumping debug info for already
+ // instantiated services. There's little value in dumping the
+ // debug info for a service we create on the fly, so we only operate
+ // on the "mServicesTable".
+ if (mEmitDebugInfo && &table == &mServicesTable) {
auto pair = splitFirst(entry.interfaceName, '/');
- mLshal.emitDebugInfo(serviceManager, pair.first, pair.second, {}, mOut.buf());
+ mLshal.emitDebugInfo(pair.first, pair.second, {}, mOut.buf(),
+ NullableOStream<std::ostream>(nullptr));
}
}
mOut << std::endl;
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 43108b7925..bf4ba2c2d6 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -14,11 +14,17 @@
* limitations under the License.
*/
+#define LOG_TAG "lshal"
+#include <android-base/logging.h>
+
#include "Lshal.h"
#include <set>
#include <string>
+#include <hidl/ServiceManagement.h>
+
+#include "DebugCommand.h"
#include "ListCommand.h"
#include "PipeRelay.h"
@@ -111,29 +117,41 @@ static hardware::hidl_vec<hardware::hidl_string> convert(const std::vector<std::
return hv;
}
-// static
-void Lshal::emitDebugInfo(
- const sp<IServiceManager> &serviceManager,
+Status Lshal::emitDebugInfo(
const std::string &interfaceName,
const std::string &instanceName,
const std::vector<std::string> &options,
- std::ostream &out) {
+ std::ostream &out,
+ NullableOStream<std::ostream> err) const {
using android::hidl::base::V1_0::IBase;
hardware::Return<sp<IBase>> retBase =
- serviceManager->get(interfaceName, instanceName);
+ ::android::hardware::defaultServiceManager()->get(interfaceName, instanceName);
+
+ if (!retBase.isOk()) {
+ std::string msg = "Cannot get " + interfaceName + "/" + instanceName + ": "
+ + retBase.description();
+ err << msg << std::endl;
+ LOG(ERROR) << msg;
+ return TRANSACTION_ERROR;
+ }
- sp<IBase> base;
- if (!retBase.isOk() || (base = retBase) == nullptr) {
- mErr << interfaceName << "/" << instanceName << " does not exist." << std::endl;
- return;
+ sp<IBase> base = retBase;
+ if (base == nullptr) {
+ std::string msg = interfaceName + "/" + instanceName + " does not exist, or "
+ + "no permission to connect.";
+ err << msg << std::endl;
+ LOG(ERROR) << msg;
+ return NO_INTERFACE;
}
PipeRelay relay(out);
if (relay.initCheck() != OK) {
- mErr << "PipeRelay::initCheck() FAILED w/ " << relay.initCheck() << std::endl;
- return;
+ std::string msg = "PipeRelay::initCheck() FAILED w/ " + std::to_string(relay.initCheck());
+ err << msg << std::endl;
+ LOG(ERROR) << msg;
+ return IO_ERROR;
}
deleted_unique_ptr<native_handle_t> fdHandle(
@@ -145,12 +163,13 @@ void Lshal::emitDebugInfo(
hardware::Return<void> ret = base->debug(fdHandle.get(), convert(options));
if (!ret.isOk()) {
- LOG(ERROR)
- << interfaceName
- << "::debug(...) FAILED. (instance "
- << instanceName
- << ")";
+ std::string msg = "debug() FAILED on " + interfaceName + "/" + instanceName + ": "
+ + ret.description();
+ err << msg << std::endl;
+ LOG(ERROR) << msg;
+ return TRANSACTION_ERROR;
}
+ return OK;
}
Status Lshal::parseArgs(const Arg &arg) {
@@ -191,8 +210,7 @@ Status Lshal::main(const Arg &arg) {
return ListCommand{*this}.main(mCommand, arg);
}
if (mCommand == "debug") {
- // TODO(b/37725279) implement this
- return OK;
+ return DebugCommand{*this}.main(mCommand, arg);
}
usage();
return USAGE;
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index cabf50399c..cf77b6ba53 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -38,12 +38,12 @@ public:
NullableOStream<std::ostream> err() const;
NullableOStream<std::ostream> out() const;
- static void emitDebugInfo(
- const sp<hidl::manager::V1_0::IServiceManager> &serviceManager,
+ Status emitDebugInfo(
const std::string &interfaceName,
const std::string &instanceName,
const std::vector<std::string> &options,
- std::ostream &out);
+ std::ostream &out,
+ NullableOStream<std::ostream> err) const;
private:
Status parseArgs(const Arg &arg);
std::string mCommand;
diff --git a/cmds/lshal/utils.h b/cmds/lshal/utils.h
index 972009453f..45b922cc03 100644
--- a/cmds/lshal/utils.h
+++ b/cmds/lshal/utils.h
@@ -36,6 +36,8 @@ enum : unsigned int {
DUMP_PASSTHROUGH_ERROR = 1 << 4,
DUMP_ALL_LIBS_ERROR = 1 << 5,
IO_ERROR = 1 << 6,
+ NO_INTERFACE = 1 << 7,
+ TRANSACTION_ERROR = 1 << 8,
};
using Status = unsigned int;