Merge "Don't start defaultcrypto twice" into nyc-dev
diff --git a/adb/adb.cpp b/adb/adb.cpp
index cb54d04..e0c0503 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1134,6 +1134,13 @@
/* we don't even need to send a reply */
return 0;
}
+
+ if (!strcmp(service, "reconnect")) {
+ if (s->transport != nullptr) {
+ kick_transport(s->transport);
+ }
+ return SendOkay(reply_fd, "done");
+ }
#endif // ADB_HOST
int ret = handle_forward_request(service, type, serial, reply_fd);
diff --git a/adb/adb.h b/adb/adb.h
index 59644d4..ea20800 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -50,7 +50,7 @@
std::string adb_version();
// Increment this when we want to force users to start a new adb server.
-#define ADB_SERVER_VERSION 35
+#define ADB_SERVER_VERSION 36
class atransport;
struct usb_handle;
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index d29c08e..a27dd47 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -158,7 +158,8 @@
}
}
- if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
+ if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
+ switch_socket_transport(fd, error)) {
return -1;
}
@@ -168,9 +169,11 @@
return -1;
}
- if (!adb_status(fd, error)) {
- adb_close(fd);
- return -1;
+ if (service != "reconnect") {
+ if (!adb_status(fd, error)) {
+ adb_close(fd);
+ return -1;
+ }
}
D("_adb_connect: return fd %d", fd);
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index b828c41..0c5be84 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -242,6 +242,9 @@
" - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
" is updated.\n"
"\n"
+ "internal debugging:\n"
+ " adb reconnect Kick current connection from host side and make it reconnect.\n"
+ " adb reconnect device Kick current connection from device side and make it reconnect.\n"
"environment variables:\n"
" ADB_TRACE - Print debug information. A comma separated list of the following values\n"
" 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
@@ -1934,6 +1937,14 @@
}
}
return 0;
+ } else if (!strcmp(argv[0], "reconnect")) {
+ if (argc == 1) {
+ return adb_query_command("host:reconnect");
+ } else if (argc == 2 && !strcmp(argv[1], "device")) {
+ std::string err;
+ adb_connect("reconnect", &err);
+ return 0;
+ }
}
usage();
diff --git a/adb/services.cpp b/adb/services.cpp
index 67e8e41..3b212e9 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -184,6 +184,13 @@
adb_close(fd);
}
+static void reconnect_service(int fd, void* arg) {
+ WriteFdExactly(fd, "done");
+ adb_close(fd);
+ atransport* t = static_cast<atransport*>(arg);
+ kick_transport(t);
+}
+
int reverse_service(const char* command) {
int s[2];
if (adb_socketpair(s)) {
@@ -345,6 +352,8 @@
ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
} else if(!strncmp(name, "enable-verity:", 15)) {
ret = create_service_thread(set_verity_enabled_state_service, (void*)1);
+ } else if (!strcmp(name, "reconnect")) {
+ ret = create_service_thread(reconnect_service, const_cast<atransport*>(transport));
#endif
}
if (ret >= 0) {
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
index 78efea8..f0c334e 100644
--- a/adb/sysdeps_test.cpp
+++ b/adb/sysdeps_test.cpp
@@ -215,3 +215,32 @@
// Linux returns POLLIN | POLLHUP, Windows returns just POLLHUP.
EXPECT_EQ(POLLHUP, pfd.revents & POLLHUP);
}
+
+TEST_F(sysdeps_poll, fd_count) {
+ // https://code.google.com/p/android/issues/detail?id=12141
+ static constexpr int num_sockets = 512;
+ std::vector<int> sockets;
+ std::vector<adb_pollfd> pfds;
+ sockets.resize(num_sockets * 2);
+ for (int32_t i = 0; i < num_sockets; ++i) {
+ ASSERT_EQ(0, adb_socketpair(&sockets[i * 2])) << strerror(errno);
+ ASSERT_TRUE(WriteFdExactly(sockets[i * 2], &i, sizeof(i)));
+ adb_pollfd pfd;
+ pfd.events = POLLIN;
+ pfd.fd = sockets[i * 2 + 1];
+ pfds.push_back(pfd);
+ }
+
+ ASSERT_EQ(num_sockets, adb_poll(pfds.data(), pfds.size(), 0));
+ for (int i = 0; i < num_sockets; ++i) {
+ ASSERT_NE(0, pfds[i].revents & POLLIN);
+
+ int32_t buf[2] = { -1, -1 };
+ ASSERT_EQ(adb_read(pfds[i].fd, buf, sizeof(buf)), static_cast<ssize_t>(sizeof(int32_t)));
+ ASSERT_EQ(i, buf[0]);
+ }
+
+ for (int fd : sockets) {
+ adb_close(fd);
+ }
+}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index a2f34fb..bc09fdc 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -191,7 +191,7 @@
#define fh_socket u.socket
#define WIN32_FH_BASE 2048
-#define WIN32_MAX_FHS 128
+#define WIN32_MAX_FHS 2048
static adb_mutex_t _win32_lock;
static FHRec _win32_fhs[ WIN32_MAX_FHS ];
diff --git a/adb/transport.cpp b/adb/transport.cpp
index f86a222..413b362 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -305,7 +305,11 @@
void kick_transport(atransport* t) {
adb_mutex_lock(&transport_lock);
- kick_transport_locked(t);
+ // As kick_transport() can be called from threads without guarantee that t is valid,
+ // check if the transport is in transport_list first.
+ if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
+ kick_transport_locked(t);
+ }
adb_mutex_unlock(&transport_lock);
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2f027d7..f505faf 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -427,6 +427,7 @@
mkdir /data/system 0775 system system
mkdir /data/system/heapdump 0700 system system
+ mkdir /data/system/users 0775 system system
mkdir /data/system_de 0770 system system
mkdir /data/system_ce 0770 system system