Merge "libmetricslogger: Fix the out-of-sync proto IDs for boot reason." into oc-mr1-dev
diff --git a/adb/adb.cpp b/adb/adb.cpp index ff7b71f..6b30be8 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp
@@ -257,19 +257,6 @@ send_packet(cp, t); } -#if ADB_HOST - -void SendConnectOnHost(atransport* t) { - // Send an empty message before A_CNXN message. This is because the data toggle of the ep_out on - // host and ep_in on device may not be the same. - apacket* p = get_apacket(); - CHECK(p); - send_packet(p, t); - send_connect(t); -} - -#endif - // qual_overwrite is used to overwrite a qualifier string. dst is a // pointer to a char pointer. It is assumed that if *dst is non-NULL, it // was malloc'ed and needs to freed. *dst will be set to a dup of src. @@ -370,7 +357,7 @@ if (p->msg.arg0){ send_packet(p, t); #if ADB_HOST - SendConnectOnHost(t); + send_connect(t); #endif } else { t->SetConnectionState(kCsOffline); @@ -956,8 +943,8 @@ // Try to handle a network forwarding request. // This returns 1 on success, 0 on failure, and -1 to indicate this is not // a forwarding-related request. -int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd) -{ +int handle_forward_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd) { if (!strcmp(service, "list-forward")) { // Create the list of forward redirections. std::string listeners = format_listeners(); @@ -1010,7 +997,8 @@ } std::string error_msg; - atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg); + atransport* transport = + acquire_one_transport(type, serial, transport_id, nullptr, &error_msg); if (!transport) { SendFail(reply_fd, error_msg); return 1; @@ -1068,8 +1056,8 @@ return 0; } -int handle_host_request(const char* service, TransportType type, - const char* serial, int reply_fd, asocket* s) { +int handle_host_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd, asocket* s) { if (strcmp(service, "kill") == 0) { fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); @@ -1089,7 +1077,14 @@ if (!strncmp(service, "transport", strlen("transport"))) { TransportType type = kTransportAny; - if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { + if (!strncmp(service, "transport-id:", strlen("transport-id:"))) { + service += strlen("transport-id:"); + transport_id = strtoll(service, const_cast<char**>(&service), 10); + if (*service != '\0') { + SendFail(reply_fd, "invalid transport id"); + return 1; + } + } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; @@ -1101,7 +1096,7 @@ } std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { s->transport = t; SendOkay(reply_fd); @@ -1144,7 +1139,7 @@ if (!strcmp(service, "features")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { SendOkay(reply_fd, FeatureSetToString(t->features())); } else { @@ -1197,7 +1192,7 @@ // These always report "unknown" rather than the actual error, for scripts. if (!strcmp(service, "get-serialno")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->serial ? t->serial : "unknown"); } else { @@ -1206,7 +1201,7 @@ } if (!strcmp(service, "get-devpath")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown"); } else { @@ -1215,7 +1210,7 @@ } if (!strcmp(service, "get-state")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->connection_state_name()); } else { @@ -1233,7 +1228,7 @@ if (!strcmp(service, "reconnect")) { std::string response; - atransport* t = acquire_one_transport(type, serial, nullptr, &response, true); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true); if (t != nullptr) { kick_transport(t); response = @@ -1242,7 +1237,7 @@ return SendOkay(reply_fd, response); } - int ret = handle_forward_request(service, type, serial, reply_fd); + int ret = handle_forward_request(service, type, serial, transport_id, reply_fd); if (ret >= 0) return ret - 1; return -1;
diff --git a/adb/adb.h b/adb/adb.h index d6b2b81..98e2604 100644 --- a/adb/adb.h +++ b/adb/adb.h
@@ -56,6 +56,7 @@ // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 39 +using TransportId = uint64_t; class atransport; struct amessage { @@ -149,7 +150,7 @@ int service_to_fd(const char* name, const atransport* transport); #if ADB_HOST -asocket *host_service_to_socket(const char* name, const char *serial); +asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id); #endif #if !ADB_HOST @@ -159,7 +160,8 @@ int create_jdwp_connection_fd(int jdwp_pid); #endif -int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd); +int handle_forward_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd); #if !ADB_HOST void framebuffer_service(int fd, void *cookie); @@ -216,15 +218,13 @@ #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) #endif -int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s); +int handle_host_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd, asocket* s); void handle_online(atransport *t); void handle_offline(atransport *t); void send_connect(atransport *t); -#if ADB_HOST -void SendConnectOnHost(atransport* t); -#endif void parse_banner(const std::string&, atransport* t);
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp index e533a00..849a6e7 100644 --- a/adb/adb_client.cpp +++ b/adb/adb_client.cpp
@@ -20,6 +20,7 @@ #include "adb_client.h" #include <errno.h> +#include <inttypes.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> @@ -46,12 +47,20 @@ static TransportType __adb_transport = kTransportAny; static const char* __adb_serial = NULL; +static TransportId __adb_transport_id = 0; static const char* __adb_server_socket_spec; -void adb_set_transport(TransportType type, const char* serial) { +void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) { __adb_transport = type; __adb_serial = serial; + __adb_transport_id = transport_id; +} + +void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) { + if (type) *type = __adb_transport; + if (serial) *serial = __adb_serial; + if (transport_id) *transport_id = __adb_transport_id; } void adb_set_socket_spec(const char* socket_spec) { @@ -63,7 +72,10 @@ static int switch_socket_transport(int fd, std::string* error) { std::string service; - if (__adb_serial) { + if (__adb_transport_id) { + service += "host:transport-id:"; + service += std::to_string(__adb_transport_id); + } else if (__adb_serial) { service += "host:transport:"; service += __adb_serial; } else { @@ -292,15 +304,18 @@ return true; } -std::string format_host_command(const char* command, TransportType type, const char* serial) { - if (serial) { - return android::base::StringPrintf("host-serial:%s:%s", serial, command); +std::string format_host_command(const char* command) { + if (__adb_transport_id) { + return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id, + command); + } else if (__adb_serial) { + return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command); } const char* prefix = "host"; - if (type == kTransportUsb) { + if (__adb_transport == kTransportUsb) { prefix = "host-usb"; - } else if (type == kTransportLocal) { + } else if (__adb_transport == kTransportLocal) { prefix = "host-local"; } return android::base::StringPrintf("%s:%s", prefix, command); @@ -308,7 +323,7 @@ bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) { std::string result; - if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) { + if (adb_query(format_host_command("features"), &result, error)) { *feature_set = StringToFeatureSet(result); return true; }
diff --git a/adb/adb_client.h b/adb/adb_client.h index fabec00..fca435e 100644 --- a/adb/adb_client.h +++ b/adb/adb_client.h
@@ -40,7 +40,9 @@ std::string* _Nonnull error); // Set the preferred transport to connect to. -void adb_set_transport(TransportType type, const char* _Nullable serial); +void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id); +void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial, + TransportId* _Nullable transport_id); // Set the socket specification for the adb server. // This function can only be called once, and the argument must live to the end of the process. @@ -57,8 +59,7 @@ bool adb_status(int fd, std::string* _Nonnull error); // Create a host command corresponding to selected transport type/serial. -std::string format_host_command(const char* _Nonnull command, TransportType type, - const char* _Nullable serial); +std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error);
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp index 372a3b4..abef86a 100644 --- a/adb/bugreport.cpp +++ b/adb/bugreport.cpp
@@ -102,7 +102,7 @@ std::vector<const char*> srcs{src_file_.c_str()}; SetLineMessage("pulling"); status_ = - br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1; + br_->DoSyncPull(srcs, destination.c_str(), false, line_message_.c_str()) ? 0 : 1; if (status_ != 0) { fprintf(stderr, "Bug report finished but could not be copied to '%s'.\n" @@ -195,13 +195,13 @@ DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback); }; -int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) { +int Bugreport::DoIt(int argc, const char** argv) { if (argc > 2) return syntax_error("adb bugreport [PATH]"); // Gets bugreportz version. std::string bugz_stdout, bugz_stderr; DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr); - int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback); + int status = SendShellCommand("bugreportz -v", false, &version_callback); std::string bugz_version = android::base::Trim(bugz_stderr); std::string bugz_output = android::base::Trim(bugz_stdout); @@ -214,7 +214,7 @@ fprintf(stderr, "Failed to get bugreportz version, which is only available on devices " "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n"); - return SendShellCommand(transport_type, serial, "bugreport", false); + return SendShellCommand("bugreport", false); } // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling @@ -265,7 +265,7 @@ bugz_command = "bugreportz"; } BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this); - return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback); + return SendShellCommand(bugz_command, false, &bugz_callback); } void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) { @@ -274,10 +274,9 @@ LinePrinter::INFO); } -int Bugreport::SendShellCommand(TransportType transport_type, const char* serial, - const std::string& command, bool disable_shell_protocol, +int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { - return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback); + return send_shell_command(command, disable_shell_protocol, callback); } bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
diff --git a/adb/bugreport.h b/adb/bugreport.h index d9a4468..413439b 100644 --- a/adb/bugreport.h +++ b/adb/bugreport.h
@@ -29,14 +29,13 @@ public: Bugreport() : line_printer_() { } - int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv); + int DoIt(int argc, const char** argv); protected: // Functions below are abstractions of external functions so they can be // mocked on tests. virtual int SendShellCommand( - TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, + const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK); virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp index d3787b4..72ca59a 100644 --- a/adb/bugreport_test.cpp +++ b/adb/bugreport_test.cpp
@@ -51,8 +51,8 @@ // Empty functions so tests don't need to be linked against commandline.cpp DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr); -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { +int send_shell_command(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback) { ADD_FAILURE() << "send_shell_command() should have been mocked"; return -42; } @@ -62,7 +62,7 @@ kStreamStderr, }; -// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher +// gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*); class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> { @@ -118,9 +118,8 @@ class BugreportMock : public Bugreport { public: - MOCK_METHOD5(SendShellCommand, - int(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback)); + MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback)); MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs, const char* name)); MOCK_METHOD2(UpdateProgress, void(const std::string&, int)); @@ -136,10 +135,9 @@ } void ExpectBugreportzVersion(const std::string& version) { - EXPECT_CALL(br_, - SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())), - WithArg<4>(ReturnCallbackDone(0)))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version.c_str())), + WithArg<2>(ReturnCallbackDone(0)))); } void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") { @@ -153,26 +151,26 @@ // Tests when called with invalid number of arguments TEST_F(BugreportTest, InvalidNumberArgs) { const char* args[] = {"bugreport", "to", "principal"}; - ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args)); + ASSERT_EQ(1, br_.DoIt(3, args)); } // Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back // to the flat-file format ('bugreport' binary on device) TEST_F(BugreportTest, NoArgumentsPreNDevice) { // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStderr("")), + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")), // Write some bogus output on stdout to make sure it's ignored - WithArg<4>(WriteOnStdout("Dude, where is my bugreportz?")), - WithArg<4>(ReturnCallbackDone(0)))); + WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")), + WithArg<2>(ReturnCallbackDone(0)))); // clang-format on std::string bugreport = "Reported the bug was."; CaptureStdout(); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout(bugreport)), Return(0))); + EXPECT_CALL(br_, SendShellCommand("bugreport", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0))); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport)); } @@ -183,15 +181,15 @@ std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); } // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will @@ -201,47 +199,47 @@ std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR); ExpectProgress(50, "da_bugreport.zip"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); } // Tests 'adb bugreport file.zip' when it succeeds and device does not support progress. TEST_F(BugreportTest, OkNDevice) { ExpectBugreportzVersion("1.0"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds but response was sent in // multiple buffer writers and without progress updates. TEST_F(BugreportTest, OkNDeviceSplitBuffer) { ExpectBugreportzVersion("1.0"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")), - WithArg<4>(WriteOnStdout("/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")), + WithArg<2>(WriteOnStdout("/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays progress. @@ -252,32 +250,32 @@ ExpectProgress(50); ExpectProgress(99); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( // Name might change on OK, so make sure the right one is picked. - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")), + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")), // Progress line in one write - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // Add some bogus lines - WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")), + WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")), // Multiple progress lines in one write - WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")), + WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")), // Progress line in multiple writes - WithArg<4>(WriteOnStdout("PROG")), - WithArg<4>(WriteOnStdout("RESS:99")), - WithArg<4>(WriteOnStdout("/100\n")), + WithArg<2>(WriteOnStdout("PROG")), + WithArg<2>(WriteOnStdout("RESS:99")), + WithArg<2>(WriteOnStdout("/100\n")), // Split last message as well, just in case - WithArg<4>(WriteOnStdout("OK:/device/bugreport")), - WithArg<4>(WriteOnStdout(".zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("OK:/device/bugreport")), + WithArg<2>(WriteOnStdout(".zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes. @@ -287,28 +285,28 @@ ExpectProgress(50); ExpectProgress(75); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1% - WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50% + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1% + WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50% // 25% should be ignored becaused it receded. - WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25% - WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75% + WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25% + WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75% // 75% should be ignored becaused it didn't change. - WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75% + WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75% // Try a receeding percentage with a different max progress - WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70% - WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70% + WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0% @@ -317,21 +315,21 @@ ExpectProgress(0); ExpectProgress(1); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100000\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1% - WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1% + WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport dir' when it succeeds and destination is a directory. @@ -341,30 +339,30 @@ std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file' when it succeeds TEST_F(BugreportTest, OkNoExtension) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N. @@ -374,28 +372,28 @@ std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreport itself failed TEST_F(BugreportTest, BugreportzReturnedFail) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) .WillOnce( - DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone()))); + DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!")); } @@ -404,13 +402,13 @@ // multiple buffer writes TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")), + WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!")); } @@ -418,23 +416,22 @@ // response. TEST_F(BugreportTest, BugreportzReturnedUnsupported) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")), + WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?")); } // Tests 'adb bugreport file.zip' when the bugreportz -v command failed TEST_F(BugreportTest, BugreportzVersionFailed) { - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(Return(666)); + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(666, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output. @@ -442,29 +439,28 @@ ExpectBugreportzVersion(""); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the main bugreportz command failed TEST_F(BugreportTest, BugreportzFailed) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(Return(666)); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(666, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreport could not be pulled TEST_F(BugreportTest, PullFails) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, HasSubstr("file.zip"))) + false, HasSubstr("file.zip"))) .WillOnce(Return(false)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(1, br_.DoIt(2, args)); }
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp index e7f44c6..8120199 100644 --- a/adb/client/usb_libusb.cpp +++ b/adb/client/usb_libusb.cpp
@@ -333,6 +333,13 @@ return; } + rc = libusb_set_interface_alt_setting(handle.get(), interface_num, 0); + if (rc != 0) { + LOG(WARNING) << "failed to set interface alt setting for device '" << device_serial + << "'" << libusb_error_name(rc); + return; + } + for (uint8_t endpoint : {bulk_in, bulk_out}) { rc = libusb_clear_halt(handle.get(), endpoint); if (rc != 0) { @@ -412,8 +419,13 @@ if (it != usb_handles.end()) { if (!it->second->device_handle) { // If the handle is null, we were never able to open the device. - unregister_usb_transport(it->second.get()); + + // Temporarily release the usb handles mutex to avoid deadlock. + std::unique_ptr<usb_handle> handle = std::move(it->second); usb_handles.erase(it); + lock.unlock(); + unregister_usb_transport(handle.get()); + lock.lock(); } else { // Closure of the transport will erase the usb_handle. }
diff --git a/adb/commandline.cpp b/adb/commandline.cpp index c9f1ee9..9f23473 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp
@@ -62,11 +62,11 @@ #include "shell_service.h" #include "sysdeps/chrono.h" -static int install_app(TransportType t, const char* serial, int argc, const char** argv); -static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv); -static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv); -static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv); -static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv); +static int install_app(int argc, const char** argv); +static int install_multiple_app(int argc, const char** argv); +static int uninstall_app(int argc, const char** argv); +static int install_app_legacy(int argc, const char** argv); +static int uninstall_app_legacy(int argc, const char** argv); extern int gListenAll; @@ -90,6 +90,7 @@ " -d use USB device (error if multiple devices connected)\n" " -e use TCP/IP device (error if multiple TCP/IP devices available)\n" " -s SERIAL use device with given serial (overrides $ANDROID_SERIAL)\n" + " -t ID use device with given transport id\n" " -H name of adb server host [default=localhost]\n" " -P port of adb server [default=5037]\n" " -L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]\n" @@ -685,6 +686,10 @@ // Parse shell-specific command-line options. argv[0] = "adb shell"; // So getopt(3) error messages start "adb shell". +#ifdef _WIN32 + // fixes "adb shell -l" crash on Windows, b/37284906 + __argv = const_cast<char**>(argv); +#endif optind = 1; // argv[0] is always "shell", so set `optind` appropriately. int opt; while ((opt = getopt(argc, const_cast<char**>(argv), "+e:ntTx")) != -1) { @@ -986,13 +991,16 @@ #endif /* !defined(_WIN32) */ } -static bool wait_for_device(const char* service, TransportType t, const char* serial) { +static bool wait_for_device(const char* service) { std::vector<std::string> components = android::base::Split(service, "-"); if (components.size() < 3 || components.size() > 4) { fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service); return false; } + TransportType t; + adb_get_transport(&t, nullptr, nullptr); + // Was the caller vague about what they'd like us to wait for? // If so, check they weren't more specific in their choice of transport type. if (components.size() == 3) { @@ -1019,7 +1027,7 @@ return false; } - std::string cmd = format_host_command(android::base::Join(components, "-").c_str(), t, serial); + std::string cmd = format_host_command(android::base::Join(components, "-").c_str()); return adb_command(cmd); } @@ -1065,8 +1073,8 @@ return true; } -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { +int send_shell_command(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback) { int fd; bool use_shell_protocol = false; @@ -1097,7 +1105,7 @@ } fprintf(stderr, "- waiting for device -\n"); - if (!wait_for_device("wait-for-device", transport_type, serial)) { + if (!wait_for_device("wait-for-device")) { return 1; } } @@ -1111,7 +1119,7 @@ return exit_code; } -static int logcat(TransportType transport, const char* serial, int argc, const char** argv) { +static int logcat(int argc, const char** argv) { char* log_tags = getenv("ANDROID_LOG_TAGS"); std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags); @@ -1128,7 +1136,7 @@ } // No need for shell protocol with logcat, always disable for simplicity. - return send_shell_command(transport, serial, cmd, true); + return send_shell_command(cmd, true); } static void write_zeros(int bytes, int fd) { @@ -1340,6 +1348,7 @@ // We need to check for -d and -e before we look at $ANDROID_SERIAL. const char* serial = nullptr; + TransportId transport_id = 0; while (argc > 0) { if (!strcmp(argv[0],"server")) { @@ -1359,7 +1368,7 @@ fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str); return 1; } - } else if (argv[0][0]=='-' && argv[0][1]=='s') { + } else if (!strncmp(argv[0], "-s", 2)) { if (isdigit(argv[0][2])) { serial = argv[0] + 2; } else { @@ -1368,6 +1377,19 @@ argc--; argv++; } + } else if (!strncmp(argv[0], "-t", 2)) { + const char* id; + if (isdigit(argv[0][2])) { + id = argv[0] + 2; + } else { + id = argv[1]; + argc--; + argv++; + } + transport_id = strtoll(id, const_cast<char**>(&id), 10); + if (*id != '\0') { + return syntax_error("invalid transport id"); + } } else if (!strcmp(argv[0],"-d")) { transport_type = kTransportUsb; } else if (!strcmp(argv[0],"-e")) { @@ -1451,7 +1473,7 @@ serial = getenv("ANDROID_SERIAL"); } - adb_set_transport(transport_type, serial); + adb_set_transport(transport_type, serial, transport_id); if (is_server) { if (no_daemon || is_daemon) { @@ -1478,7 +1500,7 @@ if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) { const char* service = argv[0]; - if (!wait_for_device(service, transport_type, serial)) { + if (!wait_for_device(service)) { return 1; } @@ -1589,7 +1611,7 @@ return adb_root(argv[0]) ? 0 : 1; } else if (!strcmp(argv[0], "bugreport")) { Bugreport bugreport; - return bugreport.DoIt(transport_type, serial, argc, argv); + return bugreport.DoIt(argc, argv); } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) { bool reverse = !strcmp(argv[0], "reverse"); ++argv; @@ -1685,20 +1707,20 @@ else if (!strcmp(argv[0], "install")) { if (argc < 2) return syntax_error("install requires an argument"); if (_use_legacy_install()) { - return install_app_legacy(transport_type, serial, argc, argv); + return install_app_legacy(argc, argv); } - return install_app(transport_type, serial, argc, argv); + return install_app(argc, argv); } else if (!strcmp(argv[0], "install-multiple")) { if (argc < 2) return syntax_error("install-multiple requires an argument"); - return install_multiple_app(transport_type, serial, argc, argv); + return install_multiple_app(argc, argv); } else if (!strcmp(argv[0], "uninstall")) { if (argc < 2) return syntax_error("uninstall requires an argument"); if (_use_legacy_install()) { - return uninstall_app_legacy(transport_type, serial, argc, argv); + return uninstall_app_legacy(argc, argv); } - return uninstall_app(transport_type, serial, argc, argv); + return uninstall_app(argc, argv); } else if (!strcmp(argv[0], "sync")) { std::string src; @@ -1752,11 +1774,11 @@ !strcmp(argv[0],"get-serialno") || !strcmp(argv[0],"get-devpath")) { - return adb_query_command(format_host_command(argv[0], transport_type, serial)); + return adb_query_command(format_host_command(argv[0])); } /* other commands */ else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) { - return logcat(transport_type, serial, argc, argv); + return logcat(argc, argv); } else if (!strcmp(argv[0],"ppp")) { return ppp(argc, argv); @@ -1819,7 +1841,7 @@ return adb_query_command("host:host-features"); } else if (!strcmp(argv[0], "reconnect")) { if (argc == 1) { - return adb_query_command(format_host_command(argv[0], transport_type, serial)); + return adb_query_command(format_host_command(argv[0])); } else if (argc == 2) { if (!strcmp(argv[1], "device")) { std::string err; @@ -1838,7 +1860,7 @@ return 1; } -static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) { +static int uninstall_app(int argc, const char** argv) { // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device std::string cmd = "cmd package"; while (argc-- > 0) { @@ -1854,10 +1876,10 @@ cmd += " " + escape_arg(*argv++); } - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int install_app(TransportType transport, const char* serial, int argc, const char** argv) { +static int install_app(int argc, const char** argv) { // The last argument must be the APK file const char* file = argv[argc - 1]; if (!android::base::EndsWithIgnoreCase(file, ".apk")) { @@ -1910,9 +1932,7 @@ return 1; } -static int install_multiple_app(TransportType transport, const char* serial, int argc, - const char** argv) -{ +static int install_multiple_app(int argc, const char** argv) { // Find all APK arguments starting at end. // All other arguments passed through verbatim. int first_apk = -1; @@ -2037,17 +2057,17 @@ return EXIT_FAILURE; } -static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) { +static int pm_command(int argc, const char** argv) { std::string cmd = "pm"; while (argc-- > 0) { cmd += " " + escape_arg(*argv++); } - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int uninstall_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) { +static int uninstall_app_legacy(int argc, const char** argv) { /* if the user choose the -k option, we refuse to do it until devices are out with the option to uninstall the remaining data somehow (adb/ui) */ int i; @@ -2063,15 +2083,15 @@ } /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */ - return pm_command(transport, serial, argc, argv); + return pm_command(argc, argv); } -static int delete_file(TransportType transport, const char* serial, const std::string& filename) { +static int delete_file(const std::string& filename) { std::string cmd = "rm -f " + escape_arg(filename); - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int install_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) { +static int install_app_legacy(int argc, const char** argv) { static const char *const DATA_DEST = "/data/local/tmp/%s"; static const char *const SD_DEST = "/sdcard/tmp/%s"; const char* where = DATA_DEST; @@ -2100,9 +2120,9 @@ where, android::base::Basename(argv[last_apk]).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ - result = pm_command(transport, serial, argc, argv); + result = pm_command(argc, argv); cleanup_apk: - delete_file(transport, serial, apk_dest); + delete_file(apk_dest); return result; }
diff --git a/adb/commandline.h b/adb/commandline.h index 9ba69a3..36cd798 100644 --- a/adb/commandline.h +++ b/adb/commandline.h
@@ -91,8 +91,8 @@ // Connects to the device "shell" service with |command| and prints the // resulting output. // if |callback| is non-null, stdout/stderr output will be handled by it. -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback = - &DEFAULT_STANDARD_STREAMS_CALLBACK); +int send_shell_command( + const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK); #endif // COMMANDLINE_H
diff --git a/adb/services.cpp b/adb/services.cpp index 9605e6e..1660846 100644 --- a/adb/services.cpp +++ b/adb/services.cpp
@@ -58,6 +58,7 @@ #include "transport.h" struct stinfo { + const char* service_name; void (*func)(int fd, void *cookie); int fd; void *cookie; @@ -65,7 +66,7 @@ static void service_bootstrap_func(void* x) { stinfo* sti = reinterpret_cast<stinfo*>(x); - adb_thread_setname(android::base::StringPrintf("service %d", sti->fd)); + adb_thread_setname(android::base::StringPrintf("%s svc %d", sti->service_name, sti->fd)); sti->func(sti->fd, sti->cookie); free(sti); } @@ -159,8 +160,7 @@ return true; } -void reboot_service(int fd, void* arg) -{ +void reboot_service(int fd, void* arg) { if (reboot_service_impl(fd, static_cast<const char*>(arg))) { // Don't return early. Give the reboot command time to take effect // to avoid messing up scripts which do "adb reboot && adb wait-for-device" @@ -187,7 +187,7 @@ return -1; } VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1]; - if (handle_forward_request(command, kTransportAny, nullptr, s[1]) < 0) { + if (handle_forward_request(command, kTransportAny, nullptr, 0, s[1]) < 0) { SendFail(s[1], "not a reverse forwarding command"); } adb_close(s[1]); @@ -235,8 +235,7 @@ #endif // !ADB_HOST -static int create_service_thread(void (*func)(int, void *), void *cookie) -{ +static int create_service_thread(const char* service_name, void (*func)(int, void*), void* cookie) { int s[2]; if (adb_socketpair(s)) { printf("cannot create service socket pair\n"); @@ -257,6 +256,7 @@ if (sti == nullptr) { fatal("cannot allocate stinfo"); } + sti->service_name = service_name; sti->func = func; sti->cookie = cookie; sti->fd = s[1]; @@ -280,7 +280,7 @@ } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { - ret = create_service_thread(framebuffer_service, 0); + ret = create_service_thread("fb", framebuffer_service, nullptr); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!strncmp(name, "shell", 5)) { @@ -288,17 +288,17 @@ } else if(!strncmp(name, "exec:", 5)) { ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "sync:", 5)) { - ret = create_service_thread(file_sync_service, NULL); + ret = create_service_thread("sync", file_sync_service, nullptr); } else if(!strncmp(name, "remount:", 8)) { - ret = create_service_thread(remount_service, NULL); + ret = create_service_thread("remount", remount_service, nullptr); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; - ret = create_service_thread(reboot_service, arg); + ret = create_service_thread("reboot", reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { - ret = create_service_thread(restart_root_service, NULL); + ret = create_service_thread("root", restart_root_service, nullptr); } else if(!strncmp(name, "unroot:", 7)) { - ret = create_service_thread(restart_unroot_service, NULL); + ret = create_service_thread("unroot", restart_unroot_service, nullptr); } else if(!strncmp(name, "backup:", 7)) { ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(), @@ -311,17 +311,20 @@ if (sscanf(name + 6, "%d", &port) != 1) { return -1; } - ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); + ret = create_service_thread("tcp", restart_tcp_service, reinterpret_cast<void*>(port)); } else if(!strncmp(name, "usb:", 4)) { - ret = create_service_thread(restart_usb_service, NULL); + ret = create_service_thread("usb", restart_usb_service, nullptr); } else if (!strncmp(name, "reverse:", 8)) { ret = reverse_service(name + 8); } else if(!strncmp(name, "disable-verity:", 15)) { - ret = create_service_thread(set_verity_enabled_state_service, (void*)0); + ret = create_service_thread("verity-on", set_verity_enabled_state_service, + reinterpret_cast<void*>(0)); } else if(!strncmp(name, "enable-verity:", 15)) { - ret = create_service_thread(set_verity_enabled_state_service, (void*)1); + ret = create_service_thread("verity-off", set_verity_enabled_state_service, + reinterpret_cast<void*>(1)); } else if (!strcmp(name, "reconnect")) { - ret = create_service_thread(reconnect_service, const_cast<atransport*>(transport)); + ret = create_service_thread("reconnect", reconnect_service, + const_cast<atransport*>(transport)); #endif } if (ret >= 0) { @@ -334,6 +337,7 @@ struct state_info { TransportType transport_type; std::string serial; + TransportId transport_id; ConnectionState state; }; @@ -346,7 +350,8 @@ bool is_ambiguous = false; std::string error = "unknown error"; const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : NULL; - atransport* t = acquire_one_transport(sinfo->transport_type, serial, &is_ambiguous, &error); + atransport* t = acquire_one_transport(sinfo->transport_type, serial, sinfo->transport_id, + &is_ambiguous, &error); if (t != nullptr && (sinfo->state == kCsAny || sinfo->state == t->GetConnectionState())) { SendOkay(fd); break; @@ -437,7 +442,7 @@ #endif #if ADB_HOST -asocket* host_service_to_socket(const char* name, const char* serial) { +asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id) { if (!strcmp(name,"track-devices")) { return create_device_tracker(); } else if (android::base::StartsWith(name, "wait-for-")) { @@ -450,6 +455,7 @@ } if (serial) sinfo->serial = serial; + sinfo->transport_id = transport_id; if (android::base::StartsWith(name, "local")) { name += strlen("local"); @@ -478,11 +484,17 @@ return nullptr; } - int fd = create_service_thread(wait_for_state, sinfo.release()); + int fd = create_service_thread("wait", wait_for_state, sinfo.get()); + if (fd != -1) { + sinfo.release(); + } return create_local_socket(fd); } else if (!strncmp(name, "connect:", 8)) { char* host = strdup(name + 8); - int fd = create_service_thread(connect_service, host); + int fd = create_service_thread("connect", connect_service, host); + if (fd == -1) { + free(host); + } return create_local_socket(fd); } return NULL;
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp index ee821f8..5b48da0 100644 --- a/adb/shell_service.cpp +++ b/adb/shell_service.cpp
@@ -435,8 +435,7 @@ void Subprocess::ThreadHandler(void* userdata) { Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata); - adb_thread_setname(android::base::StringPrintf( - "shell srvc %d", subprocess->pid())); + adb_thread_setname(android::base::StringPrintf("shell svc %d", subprocess->pid())); D("passing data streams for PID %d", subprocess->pid()); subprocess->PassDataStreams();
diff --git a/adb/socket.h b/adb/socket.h index 4acdf4a..64d05a9 100644 --- a/adb/socket.h +++ b/adb/socket.h
@@ -19,84 +19,83 @@ #include <stddef.h> +#include <memory> + #include "fdevent.h" struct apacket; class atransport; /* An asocket represents one half of a connection between a local and -** remote entity. A local asocket is bound to a file descriptor. A -** remote asocket is bound to the protocol engine. -*/ + * remote entity. A local asocket is bound to a file descriptor. A + * remote asocket is bound to the protocol engine. + */ struct asocket { - /* chain pointers for the local/remote list of - ** asockets that this asocket lives in - */ - asocket *next; - asocket *prev; + /* chain pointers for the local/remote list of + * asockets that this asocket lives in + */ + asocket* next; + asocket* prev; - /* the unique identifier for this asocket - */ + /* the unique identifier for this asocket + */ unsigned id; - /* flag: set when the socket's peer has closed - ** but packets are still queued for delivery - */ - int closing; + /* flag: set when the socket's peer has closed + * but packets are still queued for delivery + */ + int closing; // flag: set when the socket failed to write, so the socket will not wait to // write packets and close directly. bool has_write_error; - /* flag: quit adbd when both ends close the - ** local service socket - */ - int exit_on_close; + /* flag: quit adbd when both ends close the + * local service socket + */ + int exit_on_close; - /* the asocket we are connected to - */ + // the asocket we are connected to + asocket* peer; - asocket *peer; - - /* For local asockets, the fde is used to bind - ** us to our fd event system. For remote asockets - ** these fields are not used. - */ + /* For local asockets, the fde is used to bind + * us to our fd event system. For remote asockets + * these fields are not used. + */ fdevent fde; int fd; - /* queue of apackets waiting to be written - */ - apacket *pkt_first; - apacket *pkt_last; + // queue of apackets waiting to be written + apacket* pkt_first; + apacket* pkt_last; - /* enqueue is called by our peer when it has data - ** for us. It should return 0 if we can accept more - ** data or 1 if not. If we return 1, we must call - ** peer->ready() when we once again are ready to - ** receive data. - */ - int (*enqueue)(asocket *s, apacket *pkt); + /* enqueue is called by our peer when it has data + * for us. It should return 0 if we can accept more + * data or 1 if not. If we return 1, we must call + * peer->ready() when we once again are ready to + * receive data. + */ + int (*enqueue)(asocket* s, apacket* pkt); - /* ready is called by the peer when it is ready for - ** us to send data via enqueue again - */ - void (*ready)(asocket *s); + /* ready is called by the peer when it is ready for + * us to send data via enqueue again + */ + void (*ready)(asocket* s); - /* shutdown is called by the peer before it goes away. - ** the socket should not do any further calls on its peer. - ** Always followed by a call to close. Optional, i.e. can be NULL. - */ - void (*shutdown)(asocket *s); + /* shutdown is called by the peer before it goes away. + * the socket should not do any further calls on its peer. + * Always followed by a call to close. Optional, i.e. can be NULL. + */ + void (*shutdown)(asocket* s); - /* close is called by the peer when it has gone away. - ** we are not allowed to make any further calls on the - ** peer once our close method is called. - */ - void (*close)(asocket *s); + /* close is called by the peer when it has gone away. + * we are not allowed to make any further calls on the + * peer once our close method is called. + */ + void (*close)(asocket* s); - /* A socket is bound to atransport */ - atransport *transport; + /* A socket is bound to atransport */ + atransport* transport; size_t get_max_payload() const; };
diff --git a/adb/sockets.cpp b/adb/sockets.cpp index e0143c6..c53fbb4 100644 --- a/adb/sockets.cpp +++ b/adb/sockets.cpp
@@ -96,7 +96,7 @@ } void remove_socket(asocket* s) { - // socket_list_lock should already be held + std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); if (s->prev && s->next) { s->prev->next = s->next; s->next->prev = s->prev; @@ -430,10 +430,11 @@ } #if ADB_HOST -static asocket* create_host_service_socket(const char* name, const char* serial) { +static asocket* create_host_service_socket(const char* name, const char* serial, + TransportId transport_id) { asocket* s; - s = host_service_to_socket(name, serial); + s = host_service_to_socket(name, serial, transport_id); if (s != NULL) { D("LS(%d) bound to '%s'", s->id, name); @@ -658,6 +659,7 @@ #if ADB_HOST char* service = nullptr; char* serial = nullptr; + TransportId transport_id = 0; TransportType type = kTransportAny; #endif @@ -715,6 +717,14 @@ serial = service; service = serial_end + 1; } + } else if (!strncmp(service, "host-transport-id:", strlen("host-transport-id:"))) { + service += strlen("host-transport-id:"); + transport_id = strtoll(service, &service, 10); + + if (*service != ':') { + return -1; + } + service++; } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { type = kTransportUsb; service += strlen("host-usb:"); @@ -736,7 +746,7 @@ ** the OKAY or FAIL message and all we have to do ** is clean up. */ - if (handle_host_request(service, type, serial, s->peer->fd, s) == 0) { + if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s) == 0) { /* XXX fail message? */ D("SS(%d): handled host service '%s'", s->id, service); goto fail; @@ -751,7 +761,7 @@ ** if no such service exists, we'll fail out ** and tear down here. */ - s2 = create_host_service_socket(service, serial); + s2 = create_host_service_socket(service, serial, transport_id); if (s2 == 0) { D("SS(%d): couldn't create host service '%s'", s->id, service); SendFail(s->peer->fd, "unknown host service"); @@ -783,7 +793,7 @@ #else /* !ADB_HOST */ if (s->transport == nullptr) { std::string error_msg = "unknown failure"; - s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg); + s->transport = acquire_one_transport(kTransportAny, nullptr, 0, nullptr, &error_msg); if (s->transport == nullptr) { SendFail(s->peer->fd, error_msg); goto fail;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h index 49c7847..0abb680 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h
@@ -582,18 +582,12 @@ #ifdef __APPLE__ return pthread_setname_np(name.c_str()); #else - const char *s = name.c_str(); - - // pthread_setname_np fails rather than truncating long strings. - const int max_task_comm_len = 16; // including the null terminator - if (name.length() > (max_task_comm_len - 1)) { - char buf[max_task_comm_len]; - strncpy(buf, name.c_str(), sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - s = buf; - } - - return pthread_setname_np(pthread_self(), s) ; + // Both bionic and glibc's pthread_setname_np fails rather than truncating long strings. + // glibc doesn't have strlcpy, so we have to fake it. + char buf[16]; // MAX_TASK_COMM_LEN, but that's not exported by the kernel headers. + strncpy(buf, name.c_str(), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + return pthread_setname_np(pthread_self(), buf); #endif }
diff --git a/adb/test_device.py b/adb/test_device.py index 9e1a2ec..ddceda9 100644 --- a/adb/test_device.py +++ b/adb/test_device.py
@@ -1237,7 +1237,7 @@ return m.group(2) return None - def test_killed_when_pushing_a_large_file(self): + def disabled_test_killed_when_pushing_a_large_file(self): """ While running adb push with a large file, kill adb server. Occasionally the device becomes offline. Because the device is still @@ -1268,7 +1268,7 @@ # 4. The device should be online self.assertEqual(self._get_device_state(serialno), 'device') - def test_killed_when_pulling_a_large_file(self): + def disabled_test_killed_when_pulling_a_large_file(self): """ While running adb pull with a large file, kill adb server. Occasionally the device can't be connected. Because the device is trying to
diff --git a/adb/transport.cpp b/adb/transport.cpp index 2bbbefd..c644893 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp
@@ -21,6 +21,7 @@ #include <ctype.h> #include <errno.h> +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -36,6 +37,7 @@ #include <android-base/quick_exit.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <android-base/thread_annotations.h> #include "adb.h" #include "adb_auth.h" @@ -46,10 +48,11 @@ static void transport_unref(atransport *t); +// TODO: unordered_map<TransportId, atransport*> static auto& transport_list = *new std::list<atransport*>(); static auto& pending_list = *new std::list<atransport*>(); -static std::mutex& transport_lock = *new std::mutex(); +static auto& transport_lock = *new std::recursive_mutex(); const char* const kFeatureShell2 = "shell_v2"; const char* const kFeatureCmd = "cmd"; @@ -57,6 +60,11 @@ const char* const kFeatureLibusb = "libusb"; const char* const kFeaturePushSync = "push_sync"; +TransportId NextTransportId() { + static std::atomic<TransportId> next(1); + return next++; +} + static std::string dump_packet(const char* name, const char* func, apacket* p) { unsigned command = p->msg.command; int len = p->msg.data_length; @@ -298,9 +306,11 @@ } void kick_transport(atransport* t) { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); // As kick_transport() can be called from threads without guarantee that t is valid, // check if the transport is in transport_list first. + // + // TODO(jmgao): WTF? Is this actually true? if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) { t->Kick(); } @@ -330,7 +340,7 @@ device_tracker** pnode = &device_tracker_list; device_tracker* node = *pnode; - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); while (node) { if (node == tracker) { *pnode = node->next; @@ -403,7 +413,7 @@ // Check if all of the USB transports are connected. bool iterate_transports(std::function<bool(const atransport*)> fn) { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (const auto& t : transport_list) { if (!fn(t)) { return false; @@ -507,7 +517,7 @@ adb_close(t->fd); { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); transport_list.remove(t); } @@ -546,7 +556,7 @@ } { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); pending_list.remove(t); transport_list.push_front(t); } @@ -573,7 +583,7 @@ void kick_all_transports() { // To avoid only writing part of a packet to a transport after exit, kick all transports. - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (auto t : transport_list) { t->Kick(); } @@ -603,15 +613,15 @@ static void transport_unref(atransport* t) { CHECK(t != nullptr); - size_t old_refcount = t->ref_count--; - CHECK_GT(old_refcount, 0u); - - if (old_refcount == 1u) { + std::lock_guard<std::recursive_mutex> lock(transport_lock); + CHECK_GT(t->ref_count, 0u); + t->ref_count--; + if (t->ref_count == 0) { D("transport: %s unref (kicking and closing)", t->serial); t->close(t); remove_transport(t); } else { - D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1); + D("transport: %s unref (count=%zu)", t->serial, t->ref_count); } } @@ -638,11 +648,15 @@ return !*to_test; } -atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous, - std::string* error_out, bool accept_any_state) { +atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id, + bool* is_ambiguous, std::string* error_out, + bool accept_any_state) { atransport* result = nullptr; - if (serial) { + if (transport_id != 0) { + *error_out = + android::base::StringPrintf("no device with transport id '%" PRIu64 "'", transport_id); + } else if (serial) { *error_out = android::base::StringPrintf("device '%s' not found", serial); } else if (type == kTransportLocal) { *error_out = "no emulators found"; @@ -652,7 +666,7 @@ *error_out = "no devices found"; } - std::unique_lock<std::mutex> lock(transport_lock); + std::unique_lock<std::recursive_mutex> lock(transport_lock); for (const auto& t : transport_list) { if (t->GetConnectionState() == kCsNoPerm) { #if ADB_HOST @@ -661,8 +675,12 @@ continue; } - // Check for matching serial number. - if (serial) { + if (transport_id) { + if (t->id == transport_id) { + result = t; + break; + } + } else if (serial) { if (t->MatchesTarget(serial)) { if (result) { *error_out = "more than one device"; @@ -728,9 +746,6 @@ } int atransport::Write(apacket* p) { -#if ADB_HOST - std::lock_guard<std::mutex> lock(write_msg_lock_); -#endif return write_func_(p, this); } @@ -738,11 +753,6 @@ if (!kicked_) { kicked_ = true; CHECK(kick_func_ != nullptr); -#if ADB_HOST - // On host, adb server should avoid writing part of a packet, so don't - // kick a transport whiling writing a packet. - std::lock_guard<std::mutex> lock(write_msg_lock_); -#endif kick_func_(this); } } @@ -889,18 +899,23 @@ #if ADB_HOST +// We use newline as our delimiter, make sure to never output it. +static std::string sanitize(std::string str, bool alphanumeric) { + auto pred = alphanumeric ? [](const char c) { return !isalnum(c); } + : [](const char c) { return c == '\n'; }; + std::replace_if(str.begin(), str.end(), pred, '_'); + return str; +} + static void append_transport_info(std::string* result, const char* key, const char* value, - bool sanitize) { + bool alphanumeric) { if (value == nullptr || *value == '\0') { return; } *result += ' '; *result += key; - - for (const char* p = value; *p; ++p) { - result->push_back((!sanitize || isalnum(*p)) ? *p : '_'); - } + *result += sanitize(value, alphanumeric); } static void append_transport(const atransport* t, std::string* result, bool long_listing) { @@ -920,6 +935,11 @@ append_transport_info(result, "product:", t->product, false); append_transport_info(result, "model:", t->model, true); append_transport_info(result, "device:", t->device, false); + + // Put id at the end, so that anyone parsing the output here can always find it by scanning + // backwards from newlines, even with hypothetical devices named 'transport_id:1'. + *result += " transport_id:"; + *result += std::to_string(t->id); } *result += '\n'; } @@ -927,7 +947,7 @@ std::string list_transports(bool long_listing) { std::string result; - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (const auto& t : transport_list) { append_transport(t, &result, long_listing); } @@ -935,7 +955,7 @@ } void close_usb_devices(std::function<bool(const atransport*)> predicate) { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (auto& t : transport_list) { if (predicate(t)) { t->Kick(); @@ -964,7 +984,7 @@ return -1; } - std::unique_lock<std::mutex> lock(transport_lock); + std::unique_lock<std::recursive_mutex> lock(transport_lock); for (const auto& transport : pending_list) { if (transport->serial && strcmp(serial, transport->serial) == 0) { VLOG(TRANSPORT) << "socket transport " << transport->serial @@ -996,7 +1016,7 @@ atransport* find_transport(const char* serial) { atransport* result = nullptr; - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (auto& t : transport_list) { if (t->serial && strcmp(serial, t->serial) == 0) { result = t; @@ -1008,7 +1028,7 @@ } void kick_all_tcp_devices() { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); for (auto& t : transport_list) { if (t->IsTcpDevice()) { // Kicking breaks the read_transport thread of this transport out of any read, then @@ -1037,7 +1057,7 @@ } { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); pending_list.push_front(t); } @@ -1046,7 +1066,7 @@ // This should only be used for transports with connection_state == kCsNoPerm. void unregister_usb_transport(usb_handle* usb) { - std::lock_guard<std::mutex> lock(transport_lock); + std::lock_guard<std::recursive_mutex> lock(transport_lock); transport_list.remove_if( [usb](atransport* t) { return t->usb == usb && t->GetConnectionState() == kCsNoPerm; }); } @@ -1079,11 +1099,4 @@ keys_.pop_front(); return result; } -bool atransport::SetSendConnectOnError() { - if (has_send_connect_on_error_) { - return false; - } - has_send_connect_on_error_ = true; - return true; -} #endif
diff --git a/adb/transport.h b/adb/transport.h index 4a89ed9..0f1a1d4 100644 --- a/adb/transport.h +++ b/adb/transport.h
@@ -54,14 +54,17 @@ // The server supports `push --sync`. extern const char* const kFeaturePushSync; +TransportId NextTransportId(); + class atransport { -public: + public: // TODO(danalbert): We expose waaaaaaay too much stuff because this was // historically just a struct, but making the whole thing a more idiomatic // class in one go is a very large change. Given how bad our testing is, // it's better to do this piece by piece. - atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) { + atransport(ConnectionState state = kCsOffline) + : id(NextTransportId()), connection_state_(state) { transport_fde = {}; protocol_version = A_VERSION; max_payload = MAX_PAYLOAD; @@ -72,12 +75,8 @@ void (*close)(atransport* t) = nullptr; void SetWriteFunction(int (*write_func)(apacket*, atransport*)) { write_func_ = write_func; } - void SetKickFunction(void (*kick_func)(atransport*)) { - kick_func_ = kick_func; - } - bool IsKicked() { - return kicked_; - } + void SetKickFunction(void (*kick_func)(atransport*)) { kick_func_ = kick_func; } + bool IsKicked() { return kicked_; } int Write(apacket* p); void Kick(); @@ -85,10 +84,11 @@ ConnectionState GetConnectionState() const; void SetConnectionState(ConnectionState state); + const TransportId id; int fd = -1; int transport_socket = -1; fdevent transport_fde; - std::atomic<size_t> ref_count; + size_t ref_count = 0; uint32_t sync_token = 0; bool online = false; TransportType type = kTransportAny; @@ -122,7 +122,6 @@ #if ADB_HOST std::shared_ptr<RSA> NextKey(); - bool SetSendConnectOnError(); #endif char token[TOKEN_SIZE] = {}; @@ -181,8 +180,6 @@ std::atomic<ConnectionState> connection_state_; #if ADB_HOST std::deque<std::shared_ptr<RSA>> keys_; - std::mutex write_msg_lock_; - bool has_send_connect_on_error_ = false; #endif DISALLOW_COPY_AND_ASSIGN(atransport); @@ -191,12 +188,14 @@ /* * Obtain a transport from the available transports. * If serial is non-null then only the device with that serial will be chosen. + * If transport_id is non-zero then only the device with that transport ID will be chosen. * If multiple devices/emulators would match, *is_ambiguous (if non-null) * is set to true and nullptr returned. * If no suitable transport is found, error is set and nullptr returned. */ -atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous, - std::string* error_out, bool accept_any_state = false); +atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id, + bool* is_ambiguous, std::string* error_out, + bool accept_any_state = false); void kick_transport(atransport* t); void update_transports(void);
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp index 7e8ae67..e5845f0 100644 --- a/adb/transport_usb.cpp +++ b/adb/transport_usb.cpp
@@ -103,13 +103,6 @@ err_msg: p->msg.command = 0; - if (t->GetConnectionState() == kCsOffline) { - // If the data toggle of ep_out on device and ep_in on host are not the same, we may receive - // an error message. In this case, resend one A_CNXN message to connect the device. - if (t->SetSendConnectOnError()) { - SendConnectOnHost(t); - } - } return 0; } @@ -162,8 +155,7 @@ return 0; } -static void remote_close(atransport *t) -{ +static void remote_close(atransport* t) { usb_close(t->usb); t->usb = 0; }
diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc index f4756d5..2c48fae 100644 --- a/bootstat/bootstat.rc +++ b/bootstat/bootstat.rc
@@ -1,7 +1,39 @@ # This file is the LOCAL_INIT_RC file for the bootstat command. on post-fs-data - mkdir /data/misc/bootstat 0700 root root + mkdir /data/misc/bootstat 0700 system log + # To deal with ota transition resulting from a change in DAC from + # root.root to system.log, may be deleted after ota has settled. + chown system log /data/misc/bootstat/absolute_boot_time + chown system log /data/misc/bootstat/boot_complete + chown system log /data/misc/bootstat/boot_complete_no_encryption + chown system log /data/misc/bootstat/boot_reason + chown system log /data/misc/bootstat/boottime.bootloader.1BLE + chown system log /data/misc/bootstat/boottime.bootloader.1BLL + chown system log /data/misc/bootstat/boottime.bootloader.2BLE + chown system log /data/misc/bootstat/boottime.bootloader.2BLL + chown system log /data/misc/bootstat/boottime.bootloader.AVB + chown system log /data/misc/bootstat/boottime.bootloader.KD + chown system log /data/misc/bootstat/boottime.bootloader.KL + chown system log /data/misc/bootstat/boottime.bootloader.ODT + chown system log /data/misc/bootstat/boottime.bootloader.SW + chown system log /data/misc/bootstat/boottime.bootloader.total + chown system log /data/misc/bootstat/build_date + chown system log /data/misc/bootstat/factory_reset + chown system log /data/misc/bootstat/factory_reset_boot_complete + chown system log /data/misc/bootstat/factory_reset_boot_complete_no_encryption + chown system log /data/misc/bootstat/factory_reset_current_time + chown system log /data/misc/bootstat/factory_reset_record_value + chown system log /data/misc/bootstat/last_boot_time_utc + chown system log /data/misc/bootstat/ota_boot_complete + chown system log /data/misc/bootstat/ota_boot_complete_no_encryption + chown system log /data/misc/bootstat/post_decrypt_time_elapsed + chown system log /data/misc/bootstat/ro.boottime.init + chown system log /data/misc/bootstat/ro.boottime.init.cold_boot_wait + chown system log /data/misc/bootstat/ro.boottime.init.selinux + chown system log /data/misc/bootstat/time_since_factory_reset + chown system log /data/misc/bootstat/time_since_last_boot + # end ota transitional support # Record the time at which the user has successfully entered the pin to decrypt # the device, /data is decrypted, and the system is entering the main boot phase. @@ -10,7 +42,7 @@ # property:init.svc.bootanim=running: The boot animation is running # property:ro.crypto.type=block: FDE device on post-fs-data && property:init.svc.bootanim=running && property:ro.crypto.type=block - exec - root root -- /system/bin/bootstat -r post_decrypt_time_elapsed + exec - system log -- /system/bin/bootstat -r post_decrypt_time_elapsed # sys.logbootcomplete is a signal to enable the bootstat logging mechanism. # This signaling is necessary to prevent logging boot metrics after a runtime @@ -33,13 +65,13 @@ # Record boot complete metrics. on property:sys.boot_completed=1 && property:sys.logbootcomplete=1 # Record boot_complete and related stats (decryption, etc). - exec - root root -- /system/bin/bootstat --record_boot_complete + exec - system log -- /system/bin/bootstat --record_boot_complete # Record the boot reason. - exec - root root -- /system/bin/bootstat --record_boot_reason + exec - system log -- /system/bin/bootstat --record_boot_reason # Record time since factory reset. - exec - root root -- /system/bin/bootstat --record_time_since_factory_reset + exec - system log -- /system/bin/bootstat --record_time_since_factory_reset # Log all boot events. - exec - root root -- /system/bin/bootstat -l + exec - system log -- /system/bin/bootstat -l
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index 5b6d420..b9a0bc7 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -415,15 +415,17 @@ } ScopedBacktraceMapIteratorLock lock(map); - _LOG(log, logtype::MAPS, "\n"); - if (!print_fault_address_marker) { - _LOG(log, logtype::MAPS, "memory map:\n"); - } else { - _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n"); + _LOG(log, logtype::MAPS, + "\n" + "memory map (%zu entries):\n", + map->size()); + if (print_fault_address_marker) { if (map->begin() != map->end() && addr < map->begin()->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n", get_addr_string(addr).c_str()); print_fault_address_marker = false; + } else { + _LOG(log, logtype::MAPS, "(fault address prefixed with --->)\n"); } }
diff --git a/init/reboot.cpp b/init/reboot.cpp index 17e3576..5c7ddf1 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp
@@ -84,8 +84,8 @@ mnt_type_(entry.mnt_type), mnt_opts_(entry.mnt_opts) {} - bool Umount() { - int r = umount2(mnt_dir_.c_str(), 0); + bool Umount(bool force) { + int r = umount2(mnt_dir_.c_str(), force ? MNT_FORCE : 0); if (r == 0) { LOG(INFO) << "umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_; return true; @@ -287,11 +287,11 @@ } if (emulated_devices.size() > 0 && std::all_of(emulated_devices.begin(), emulated_devices.end(), - [](auto& entry) { return entry.Umount(); })) { + [](auto& entry) { return entry.Umount(false); })) { sync(); } for (auto& entry : block_devices) { - entry.Umount(); + entry.Umount(timeout == 0ms); } retry++; std::this_thread::sleep_for(100ms);
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h index 02a50f7..f7a55b8 100644 --- a/libbacktrace/include/backtrace/BacktraceMap.h +++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -89,6 +89,8 @@ const_iterator begin() const { return maps_.begin(); } const_iterator end() const { return maps_.end(); } + size_t size() const { return maps_.size(); } + virtual bool Build(); static inline bool IsValid(const backtrace_map_t& map) {
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk index 5571ce9..39b52ac 100644 --- a/liblog/tests/Android.mk +++ b/liblog/tests/Android.mk
@@ -54,7 +54,7 @@ -Werror \ -fno-builtin \ -test_src_files := \ +cts_src_files := \ libc_test.cpp \ liblog_test_default.cpp \ liblog_test_local.cpp \ @@ -67,6 +67,9 @@ log_time_test.cpp \ log_wrap_test.cpp +test_src_files := \ + $(cts_src_files) \ + # Build tests for the device (with .so). Run with: # adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests include $(CLEAR_VARS) @@ -82,8 +85,8 @@ include $(CLEAR_VARS) LOCAL_MODULE := $(cts_executable) LOCAL_MODULE_TAGS := tests -LOCAL_CFLAGS += $(test_c_flags) -LOCAL_SRC_FILES := $(test_src_files) +LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE +LOCAL_SRC_FILES := $(cts_src_files) LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 46ec5ef..56dbf1f 100644 --- a/liblog/tests/liblog_test.cpp +++ b/liblog/tests/liblog_test.cpp
@@ -116,6 +116,7 @@ return ret; } +#ifndef NO_PSTORE static bool isPmsgActive() { pid_t pid = getpid(); @@ -125,6 +126,7 @@ return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); } +#endif /* NO_PSTORE */ static bool isLogdwActive() { std::string logdwSignature = @@ -189,22 +191,25 @@ EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); #ifdef USING_LOGGER_DEFAULT // Check that we can close and reopen the logger - bool pmsgActiveAfter__android_log_btwrite; bool logdwActiveAfter__android_log_btwrite; if (getuid() == AID_ROOT) { tested__android_log_close = true; - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); +#ifndef NO_PSTORE + bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); +#endif /* NO_PSTORE */ + logdwActiveAfter__android_log_btwrite = isLogdwActive(); EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); } else if (!tested__android_log_close) { fprintf(stderr, "WARNING: can not test __android_log_close()\n"); } __android_log_close(); if (getuid() == AID_ROOT) { +#ifndef NO_PSTORE bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); EXPECT_FALSE(pmsgActiveAfter__android_log_close); +#endif /* NO_PSTORE */ + bool logdwActiveAfter__android_log_close = isLogdwActive(); EXPECT_FALSE(logdwActiveAfter__android_log_close); } #endif @@ -213,9 +218,11 @@ EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); #ifdef USING_LOGGER_DEFAULT if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); +#ifndef NO_PSTORE + bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); +#endif /* NO_PSTORE */ + logdwActiveAfter__android_log_btwrite = isLogdwActive(); EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); } #endif @@ -3036,12 +3043,15 @@ #ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality #ifdef __ANDROID__ +#ifndef NO_PSTORE static const char __pmsg_file[] = "/data/william-shakespeare/MuchAdoAboutNothing.txt"; +#endif /* NO_PSTORE */ #endif TEST(liblog, __android_log_pmsg_file_write) { #ifdef __ANDROID__ +#ifndef NO_PSTORE __android_log_close(); if (getuid() == AID_ROOT) { tested__android_log_close = true; @@ -3092,12 +3102,16 @@ EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); } +#else /* NO_PSTORE */ + GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; +#endif /* NO_PSTORE */ #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } #ifdef __ANDROID__ +#ifndef NO_PSTORE static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, const char* buf, size_t len, void* arg) { EXPECT_TRUE(NULL == arg); @@ -3118,10 +3132,12 @@ ? -ENOEXEC : 1; } +#endif /* NO_PSTORE */ #endif TEST(liblog, __android_log_pmsg_file_read) { #ifdef __ANDROID__ +#ifndef NO_PSTORE signaled = 0; __android_log_close(); @@ -3155,6 +3171,9 @@ EXPECT_LT(0, ret); EXPECT_EQ(1U, signaled); +#else /* NO_PSTORE */ + GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; +#endif /* NO_PSTORE */ #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp index 15d1ff2..e292403 100644 --- a/libmetricslogger/Android.bp +++ b/libmetricslogger/Android.bp
@@ -20,12 +20,10 @@ "-Wextra", "-Werror", - // The following defines map logtag IDs as represented by: + // The following define maps the sysui_multi_action logtag ID as represented by: // frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags // - // E.g., 524290 corresponds to sysui_count. - "-DCOUNT_LOG_TAG=524290", - "-DHISTOGRAM_LOG_TAG=524292", + // TODO(jhawkins): Query this value at runtime. "-DMULTI_ACTION_LOG_TAG=524292", ], }
diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp index a0dcf09..0ca024d 100644 --- a/libmetricslogger/metrics_logger.cpp +++ b/libmetricslogger/metrics_logger.cpp
@@ -25,14 +25,14 @@ // Mirror com.android.internal.logging.MetricsLogger#histogram(). void LogHistogram(const std::string& event, int32_t data) { - android_log_event_list log(HISTOGRAM_LOG_TAG); + android_log_event_list log(MULTI_ACTION_LOG_TAG); log << LOGBUILDER_CATEGORY << LOGBUILDER_HISTOGRAM << LOGBUILDER_NAME << event << LOGBUILDER_BUCKET << data << LOGBUILDER_VALUE << 1 << LOG_ID_EVENTS; } // Mirror com.android.internal.logging.MetricsLogger#count(). void LogCounter(const std::string& name, int32_t val) { - android_log_event_list log(COUNT_LOG_TAG); + android_log_event_list log(MULTI_ACTION_LOG_TAG); log << LOGBUILDER_CATEGORY << LOGBUILDER_COUNTER << LOGBUILDER_NAME << name << LOGBUILDER_VALUE << val << LOG_ID_EVENTS; }
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp index 4397b14..d242f9b 100644 --- a/logd/tests/logd_test.cpp +++ b/logd/tests/logd_test.cpp
@@ -1091,7 +1091,7 @@ // and dac_read_search on every try to get past the message // de-duper. We will also rotate the file name in the directory // as another measure. - static const char file[] = "/data/backup/cannot_access_directory_%u"; + static const char file[] = "/data/drm/cannot_access_directory_%u"; static const unsigned avc_requests_per_access = 2; rate /= avc_requests_per_access;
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 7f86a95..8aa3369 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt
@@ -7,10 +7,14 @@ dir.system = /system/bin/ dir.system = /system/xbin/ dir.vendor = /vendor/bin/ -dir.test = /data/nativetest/ -dir.test = /data/nativetest64/ -dir.test = /data/benchmarktest/ -dir.test = /data/benchmarktest64/ +dir.vendor = /data/nativetest/vendor +dir.vendor = /data/nativetest64/vendor +dir.vendor = /data/benchmarktest/vendor +dir.vendor = /data/benchmarktest64/vendor +dir.system = /data/nativetest +dir.system = /data/nativetest64 +dir.system = /data/benchmarktest +dir.system = /data/benchmarktest64 [system] additional.namespaces = sphal,vndk,rs @@ -98,6 +102,7 @@ # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true +namespace.vndk.visible = true namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl @@ -121,12 +126,3 @@ namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} - -############################################################################### -# Namespace config for tests. No VNDK restriction is enforced for these tests. -############################################################################### -[test] -namespace.default.isolated = false -namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} - -namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in index af37287..2c73056 100644 --- a/rootdir/etc/ld.config.txt.in +++ b/rootdir/etc/ld.config.txt.in
@@ -132,9 +132,7 @@ namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.links = system -namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%:libmedia.so:libandroid_runtime.so -# libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765) -# libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887) +namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES% ############################################################################### # "system" namespace
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp index e7b8cc2..b27cfad 100644 --- a/run-as/run-as.cpp +++ b/run-as/run-as.cpp
@@ -194,6 +194,7 @@ ScopedMinijail j(minijail_new()); minijail_change_uid(j.get(), uid); minijail_change_gid(j.get(), gid); + minijail_keep_supplementary_gids(j.get()); minijail_enter(j.get()); if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) {