Merge "fastbootd: Implement the getvar command."
diff --git a/adb/adb.cpp b/adb/adb.cpp
index a8fe736..8e028f4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1044,7 +1044,7 @@
     return 0;
 }
 
-int handle_host_request(const char* service, TransportType type, const char* serial,
+bool 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");
@@ -1070,7 +1070,7 @@
             transport_id = strtoll(service, const_cast<char**>(&service), 10);
             if (*service != '\0') {
                 SendFail(reply_fd, "invalid transport id");
-                return 1;
+                return true;
             }
         } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
             type = kTransportUsb;
@@ -1088,10 +1088,13 @@
         if (t != nullptr) {
             s->transport = t;
             SendOkay(reply_fd);
+
+            // We succesfully handled the device selection, but there's another request coming.
+            return false;
         } else {
             SendFail(reply_fd, error);
+            return true;
         }
-        return 1;
     }
 
     // return a list of all connected devices
@@ -1101,9 +1104,9 @@
             D("Getting device list...");
             std::string device_list = list_transports(long_listing);
             D("Sending device list...");
-            return SendOkay(reply_fd, device_list);
+            SendOkay(reply_fd, device_list);
         }
-        return 1;
+        return true;
     }
 
     if (!strcmp(service, "reconnect-offline")) {
@@ -1119,7 +1122,7 @@
             response.resize(response.size() - 1);
         }
         SendOkay(reply_fd, response);
-        return 0;
+        return true;
     }
 
     if (!strcmp(service, "features")) {
@@ -1130,7 +1133,7 @@
         } else {
             SendFail(reply_fd, error);
         }
-        return 0;
+        return true;
     }
 
     if (!strcmp(service, "host-features")) {
@@ -1141,7 +1144,7 @@
         }
         features.insert(kFeaturePushSync);
         SendOkay(reply_fd, FeatureSetToString(features));
-        return 0;
+        return true;
     }
 
     // remove TCP transport
@@ -1149,7 +1152,8 @@
         const std::string address(service + 11);
         if (address.empty()) {
             kick_all_tcp_devices();
-            return SendOkay(reply_fd, "disconnected everything");
+            SendOkay(reply_fd, "disconnected everything");
+            return true;
         }
 
         std::string serial;
@@ -1157,21 +1161,24 @@
         int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
         std::string error;
         if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
-            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
-                                                                  address.c_str(), error.c_str()));
+            SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
+                                                           address.c_str(), error.c_str()));
+            return true;
         }
         atransport* t = find_transport(serial.c_str());
         if (t == nullptr) {
-            return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'",
-                                                                  serial.c_str()));
+            SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", serial.c_str()));
+            return true;
         }
         kick_transport(t);
-        return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
+        SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str()));
+        return true;
     }
 
     // Returns our value for ADB_SERVER_VERSION.
     if (!strcmp(service, "version")) {
-        return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
+        SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
+        return true;
     }
 
     // These always report "unknown" rather than the actual error, for scripts.
@@ -1179,28 +1186,31 @@
         std::string error;
         atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
-            return SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
+            SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
         } else {
-            return SendFail(reply_fd, error);
+            SendFail(reply_fd, error);
         }
+        return true;
     }
     if (!strcmp(service, "get-devpath")) {
         std::string error;
         atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
-            return SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
+            SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
         } else {
-            return SendFail(reply_fd, error);
+            SendFail(reply_fd, error);
         }
+        return true;
     }
     if (!strcmp(service, "get-state")) {
         std::string error;
         atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
         if (t) {
-            return SendOkay(reply_fd, t->connection_state_name());
+            SendOkay(reply_fd, t->connection_state_name());
         } else {
-            return SendFail(reply_fd, error);
+            SendFail(reply_fd, error);
         }
+        return true;
     }
 
     // Indicates a new emulator instance has started.
@@ -1208,7 +1218,7 @@
         int  port = atoi(service+9);
         local_connect(port);
         /* we don't even need to send a reply */
-        return 0;
+        return true;
     }
 
     if (!strcmp(service, "reconnect")) {
@@ -1219,7 +1229,8 @@
             response =
                 "reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
         }
-        return SendOkay(reply_fd, response);
+        SendOkay(reply_fd, response);
+        return true;
     }
 
     if (handle_forward_request(service,
@@ -1228,10 +1239,10 @@
                                                                 error);
                                },
                                reply_fd)) {
-        return 0;
+        return true;
     }
 
-    return -1;
+    return false;
 }
 
 static auto& init_mutex = *new std::mutex();
diff --git a/adb/adb.h b/adb/adb.h
index e6af780..f434e2d 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -210,8 +210,8 @@
 #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
 #endif
 
-int handle_host_request(const char* service, TransportType type, const char* serial,
-                        TransportId transport_id, int reply_fd, asocket* s);
+bool 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);
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 69b5180..1534792 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -685,13 +685,9 @@
     if (service) {
         asocket* s2;
 
-        /* some requests are handled immediately -- in that
-        ** case the handle_host_request() routine has sent
-        ** the OKAY or FAIL message and all we have to do
-        ** is clean up.
-        */
-        if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s) == 0) {
-            /* XXX fail message? */
+        // Some requests are handled immediately -- in that case the handle_host_request() routine
+        // has sent the OKAY or FAIL message and all we have to do is clean up.
+        if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s)) {
             D("SS(%d): handled host service '%s'", s->id, service);
             goto fail;
         }
diff --git a/libsync/Android.bp b/libsync/Android.bp
index dbee596..e56f8ba 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -20,8 +20,9 @@
     cflags: ["-Werror"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libsync",
+    recovery_available: true,
     defaults: ["libsync_defaults"],
 }
 
@@ -31,15 +32,6 @@
     export_include_dirs: ["include"],
 }
 
-// libsync_recovery is only intended for the recovery binary.
-// Future versions of the kernel WILL require an updated libsync, and will break
-// anything statically linked against the current libsync.
-cc_library_static {
-    name: "libsync_recovery",
-    recovery_available: true,
-    defaults: ["libsync_defaults"],
-}
-
 cc_test {
     name: "sync-unit-tests",
     shared_libs: ["libsync"],
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp
index 3d982f6..8ec560c 100644
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -24,6 +24,7 @@
 
 #include <android-base/unique_fd.h>
 
+#include <dex/class_accessor-inl.h>
 #include <dex/code_item_accessors-inl.h>
 #include <dex/compact_dex_file.h>
 #include <dex/dex_file-inl.h>
@@ -98,38 +99,20 @@
 
   // Check the methods we haven't cached.
   for (; class_def_index_ < dex_file_->NumClassDefs(); class_def_index_++) {
-    const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(class_def_index_);
-    const uint8_t* class_data = dex_file_->GetClassData(class_def);
-    if (class_data == nullptr) {
-      continue;
-    }
+    art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(class_def_index_));
 
-    if (class_it_.get() == nullptr || !class_it_->HasNext()) {
-      class_it_.reset(new art::ClassDataItemIterator(*dex_file_.get(), class_data));
-    }
-
-    for (; class_it_->HasNext(); class_it_->Next()) {
-      if (!class_it_->IsAtMethod()) {
-        continue;
-      }
-      const art::DexFile::CodeItem* code_item = class_it_->GetMethodCodeItem();
-      if (code_item == nullptr) {
-        continue;
-      }
-      art::CodeItemInstructionAccessor code(*dex_file_.get(), code_item);
+    for (const art::ClassAccessor::Method& method : accessor.GetMethods()) {
+      art::CodeItemInstructionAccessor code = method.GetInstructions();
       if (!code.HasCodeItem()) {
         continue;
       }
-
       uint32_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
-      uint32_t offset_end = offset + code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
-      uint32_t member_index = class_it_->GetMemberIndex();
+      uint32_t offset_end = offset + code.InsnsSizeInBytes();
+      uint32_t member_index = method.GetIndex();
       method_cache_[offset_end] = std::make_pair(offset, member_index);
       if (offset <= dex_offset && dex_offset < offset_end) {
         *method_name = dex_file_->PrettyMethod(member_index, false);
         *method_offset = dex_offset - offset;
-        // Move past this element.
-        class_it_->Next();
         return true;
       }
     }
diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h
index 508692d..c123158 100644
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -45,7 +45,6 @@
   std::map<uint32_t, std::pair<uint64_t, uint32_t>> method_cache_;  // dex offset to method index.
 
   uint32_t class_def_index_ = 0;
-  std::unique_ptr<art::ClassDataItemIterator> class_it_;
 };
 
 class DexFileFromFile : public DexFile {
diff --git a/libunwindstack/include/unwindstack/RegsGetLocal.h b/libunwindstack/include/unwindstack/RegsGetLocal.h
index 81c0af3..f0b5e3a 100644
--- a/libunwindstack/include/unwindstack/RegsGetLocal.h
+++ b/libunwindstack/include/unwindstack/RegsGetLocal.h
@@ -33,8 +33,7 @@
 
 #if defined(__arm__)
 
-inline __always_inline void RegsGetLocal(Regs* regs) {
-  void* reg_data = regs->RawData();
+inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
   asm volatile(
       ".align 2\n"
       "bx pc\n"
@@ -55,8 +54,7 @@
 
 #elif defined(__aarch64__)
 
-inline __always_inline void RegsGetLocal(Regs* regs) {
-  void* reg_data = regs->RawData();
+inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) {
   asm volatile(
       "1:\n"
       "stp x0, x1, [%[base], #0]\n"
@@ -87,11 +85,12 @@
 
 extern "C" void AsmGetRegs(void* regs);
 
-inline void RegsGetLocal(Regs* regs) {
+#endif
+
+inline __attribute__((__always_inline__)) void RegsGetLocal(Regs* regs) {
   AsmGetRegs(regs->RawData());
 }
 
-#endif
 
 }  // namespace unwindstack
 
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 8fda563..3b45db7 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -82,6 +82,9 @@
 /* Defined as ProcessList.SYSTEM_ADJ in ProcessList.java */
 #define SYSTEM_ADJ (-900)
 
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define STRINGIFY_INTERNAL(x) #x
+
 /* default to old in-kernel interface if no memory pressure events */
 static bool use_inkernel_interface = true;
 static bool has_inkernel_module;
@@ -730,10 +733,10 @@
 
 #ifdef LMKD_LOG_STATS
 static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
-    char key[LINE_MAX];
+    char key[LINE_MAX + 1];
     int64_t value;
 
-    sscanf(line,"%s  %" SCNd64 "", key, &value);
+    sscanf(line, "%" STRINGIFY(LINE_MAX) "s  %" SCNd64 "", key, &value);
 
     if (strcmp(key, "total_") < 0) {
         return;
@@ -752,24 +755,31 @@
 }
 
 static int memory_stat_parse(struct memory_stat *mem_st,  int pid, uid_t uid) {
-   FILE *fp;
-   char buf[PATH_MAX];
+    FILE *fp;
+    char buf[PATH_MAX];
 
-   snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
+    /*
+     * Per-application memory.stat files are available only when
+     * per-application memcgs are enabled.
+     */
+    if (!per_app_memcg)
+        return -1;
 
-   fp = fopen(buf, "r");
+    snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
 
-   if (fp == NULL) {
-       ALOGE("%s open failed: %s", buf, strerror(errno));
-       return -1;
-   }
+    fp = fopen(buf, "r");
 
-   while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
-       memory_stat_parse_line(buf, mem_st);
-   }
-   fclose(fp);
+    if (fp == NULL) {
+        ALOGE("%s open failed: %s", buf, strerror(errno));
+        return -1;
+    }
 
-   return 0;
+    while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
+        memory_stat_parse_line(buf, mem_st);
+    }
+    fclose(fp);
+
+    return 0;
 }
 #endif