Merge "rootdir: Execute update_verifier for A/B update."
diff --git a/adb/adb.h b/adb/adb.h
index be29f29..774215e 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -214,18 +214,23 @@
 void local_connect(int port);
 int  local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error);
 
-/* usb host/client interface */
+// USB host/client interface.
 void usb_init();
 int usb_write(usb_handle *h, const void *data, int len);
 int usb_read(usb_handle *h, void *data, int len);
 int usb_close(usb_handle *h);
 void usb_kick(usb_handle *h);
 
-/* used for USB device detection */
+// USB device detection.
 #if ADB_HOST
 int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
 #endif
 
+// USB permission error help text. The short version will be one line, long may be multi-line.
+// Returns a string message to print, or an empty string if no problems could be found.
+std::string UsbNoPermissionsShortHelpText();
+std::string UsbNoPermissionsLongHelpText();
+
 int adb_commandline(int argc, const char **argv);
 
 ConnectionState connection_state(atransport *t);
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index 463b496..c4ffc85 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -228,13 +228,13 @@
 
 static void adb_auth_listener(int fd, unsigned events, void *data)
 {
-    struct sockaddr addr;
+    sockaddr_storage addr;
     socklen_t alen;
     int s;
 
     alen = sizeof(addr);
 
-    s = adb_socket_accept(fd, &addr, &alen);
+    s = adb_socket_accept(fd, reinterpret_cast<sockaddr*>(&addr), &alen);
     if (s < 0) {
         D("Failed to accept: errno=%d", errno);
         return;
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index d7b892c..e8c2338 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -34,9 +34,10 @@
 
 static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
     if (ev & FDE_READ) {
-        struct sockaddr addr;
-        socklen_t alen = sizeof(addr);
-        int fd = adb_socket_accept(_fd, &addr, &alen);
+        sockaddr_storage ss;
+        sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
+        socklen_t alen = sizeof(ss);
+        int fd = adb_socket_accept(_fd, addrp, &alen);
         if (fd < 0) return;
 
         int rcv_buf_size = CHUNK_SIZE;
@@ -58,12 +59,13 @@
     asocket *s;
 
     if (ev & FDE_READ) {
-        struct sockaddr addr;
+        sockaddr_storage ss;
+        sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
         socklen_t alen;
         int fd;
 
-        alen = sizeof(addr);
-        fd = adb_socket_accept(_fd, &addr, &alen);
+        alen = sizeof(ss);
+        fd = adb_socket_accept(_fd, addrp, &alen);
         if (fd < 0) {
             return;
         }
@@ -79,7 +81,7 @@
     }
 }
 
-static void  free_listener(alistener*  l)
+static void free_listener(alistener*  l)
 {
     if (l->next) {
         l->next->prev = l->prev;
diff --git a/adb/jdwp_service.cpp b/adb/jdwp_service.cpp
index cc2d44e..3c812cc 100644
--- a/adb/jdwp_service.cpp
+++ b/adb/jdwp_service.cpp
@@ -460,11 +460,11 @@
                    const char*   sockname,
                    int           socknamelen )
 {
-    struct sockaddr_un   addr;
-    socklen_t            addrlen;
-    int                  s;
-    int                  maxpath = sizeof(addr.sun_path);
-    int                  pathlen = socknamelen;
+    sockaddr_un   addr;
+    socklen_t     addrlen;
+    int           s;
+    int           maxpath = sizeof(addr.sun_path);
+    int           pathlen = socknamelen;
 
     if (pathlen >= maxpath) {
         D( "vm debug control socket name too long (%d extra chars)",
@@ -485,7 +485,7 @@
 
     addrlen = (pathlen + sizeof(addr.sun_family));
 
-    if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) {
+    if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
         D( "could not bind vm debug control socket: %d: %s",
            errno, strerror(errno) );
         adb_close(s);
@@ -523,13 +523,14 @@
     JdwpControl*  control = (JdwpControl*) _control;
 
     if (events & FDE_READ) {
-        struct sockaddr   addr;
-        socklen_t         addrlen = sizeof(addr);
-        int               s = -1;
-        JdwpProcess*      proc;
+        sockaddr_storage   ss;
+        sockaddr*          addrp = reinterpret_cast<sockaddr*>(&ss);
+        socklen_t          addrlen = sizeof(ss);
+        int                s = -1;
+        JdwpProcess*       proc;
 
         do {
-            s = adb_socket_accept( control->listen_socket, &addr, &addrlen );
+            s = adb_socket_accept(control->listen_socket, addrp, &addrlen);
             if (s < 0) {
                 if (errno == EINTR)
                     continue;
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index 3fc70b0..6c06669 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -289,7 +289,6 @@
         // TODO: $HOSTNAME? Normally bash automatically sets that, but mksh doesn't.
         passwd* pw = getpwuid(getuid());
         if (pw != nullptr) {
-            setenv("HOME", pw->pw_dir, 1);
             setenv("LOGNAME", pw->pw_name, 1);
             setenv("SHELL", pw->pw_shell, 1);
             setenv("USER", pw->pw_name, 1);
@@ -298,6 +297,8 @@
             setenv("TERM", terminal_type_.c_str(), 1);
         }
 
+        setenv("HOME", "/data/local/tmp", 1);
+        chdir(getenv("HOME"));
         if (is_interactive()) {
             execl(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr);
         } else {
diff --git a/adb/transport.cpp b/adb/transport.cpp
index d20eaff..d4f60ec 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -674,7 +674,11 @@
     adb_mutex_lock(&transport_lock);
     for (const auto& t : transport_list) {
         if (t->connection_state == kCsNoPerm) {
-            *error_out = "insufficient permissions for device";
+            *error_out = UsbNoPermissionsLongHelpText();
+            // If we couldn't figure out a reasonable help message default to something generic.
+            if (error_out->empty()) {
+                *error_out = "insufficient permissions for device";
+            }
             continue;
         }
 
@@ -748,17 +752,20 @@
     return result;
 }
 
-const char* atransport::connection_state_name() const {
+const std::string atransport::connection_state_name() const {
     switch (connection_state) {
-    case kCsOffline: return "offline";
-    case kCsBootloader: return "bootloader";
-    case kCsDevice: return "device";
-    case kCsHost: return "host";
-    case kCsRecovery: return "recovery";
-    case kCsNoPerm: return "no permissions";
-    case kCsSideload: return "sideload";
-    case kCsUnauthorized: return "unauthorized";
-    default: return "unknown";
+        case kCsOffline: return "offline";
+        case kCsBootloader: return "bootloader";
+        case kCsDevice: return "device";
+        case kCsHost: return "host";
+        case kCsRecovery: return "recovery";
+        case kCsNoPerm: {
+            std::string message = UsbNoPermissionsShortHelpText();
+            return message.empty() ? "no permissions" : message;
+        }
+        case kCsSideload: return "sideload";
+        case kCsUnauthorized: return "unauthorized";
+        default: return "unknown";
     }
 }
 
@@ -866,7 +873,8 @@
         *result += '\t';
         *result += t->connection_state_name();
     } else {
-        android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name());
+        android::base::StringAppendF(result, "%-22s %s", serial,
+                                     t->connection_state_name().c_str());
 
         append_transport_info(result, "", t->devpath, false);
         append_transport_info(result, "product:", t->product, false);
diff --git a/adb/transport.h b/adb/transport.h
index d9845b6..76d6afa 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -90,7 +90,7 @@
     fdevent auth_fde;
     size_t failed_auth_attempts = 0;
 
-    const char* connection_state_name() const;
+    const std::string connection_state_name() const;
 
     void update_version(int version, size_t payload);
     int get_protocol_version() const;
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 2c1a71d..d2a375a 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -143,7 +143,8 @@
 static void *server_socket_thread(void * arg)
 {
     int serverfd, fd;
-    struct sockaddr addr;
+    sockaddr_storage ss;
+    sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss);
     socklen_t alen;
     int port = (int) (uintptr_t) arg;
 
@@ -162,9 +163,9 @@
             close_on_exec(serverfd);
         }
 
-        alen = sizeof(addr);
+        alen = sizeof(ss);
         D("server: trying to get new connection from %d", port);
-        fd = adb_socket_accept(serverfd, &addr, &alen);
+        fd = adb_socket_accept(serverfd, addrp, &alen);
         if(fd >= 0) {
             D("server: new connection on fd %d", fd);
             close_on_exec(fd);
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index ed5d2d67..e887a94 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -22,6 +22,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <linux/usb/ch9.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/version.h>
@@ -595,3 +596,54 @@
         fatal_errno("cannot create device_poll thread");
     }
 }
+
+static const char kPermissionsHelpUrl[] = "developer.android.com/tools/device.html";
+
+// Returns a message describing any potential problems we find with udev, or nullptr if we can't
+// find plugdev information (i.e. udev is not installed).
+static const char* GetUdevProblem() {
+    errno = 0;
+    group* plugdev_group = getgrnam("plugdev");
+
+    if (plugdev_group == nullptr) {
+        if (errno != 0) {
+            D("failed to read plugdev group info: %s", strerror(errno));
+        }
+        // We can't give any generally useful advice here, just let the caller print the help URL.
+        return nullptr;
+    }
+
+    // getgroups(2) indicates that the group_member() may not check the egid so we check it
+    // additionally just to be sure.
+    if (group_member(plugdev_group->gr_gid) || getegid() == plugdev_group->gr_gid) {
+        // The user is in plugdev so the problem is likely with the udev rules.
+        return "verify udev rules";
+    }
+    return "udev requires plugdev group membership";
+}
+
+// Short help text must be a single line, and will look something like:
+//   no permissions (reason); see <URL>
+std::string UsbNoPermissionsShortHelpText() {
+    std::string help_text = "no permissions";
+
+    const char* problem = GetUdevProblem();
+    if (problem != nullptr) {
+        help_text += android::base::StringPrintf(" (%s)", problem);
+    }
+
+    return android::base::StringPrintf("%s; see [%s]", help_text.c_str(), kPermissionsHelpUrl);
+}
+
+// Long help text can span multiple lines and should provide more detailed information.
+std::string UsbNoPermissionsLongHelpText() {
+    std::string header = "USB permission failure";
+
+    const char* problem = GetUdevProblem();
+    if (problem != nullptr) {
+        header += android::base::StringPrintf(": %s", problem);
+    }
+
+    return android::base::StringPrintf("%s.\nSee [%s] for more information.",
+                                       header.c_str(), kPermissionsHelpUrl);
+}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index ceed8fa..c5e7452 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -571,3 +571,12 @@
 {
     h->kick(h);
 }
+
+// kCsNoPerm is a host-side issue, we can just ignore it here.
+std::string UsbNoPermissionsShortHelpText() {
+    return "";
+}
+
+std::string UsbNoPermissionsLongHelpText() {
+    return "";
+}
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 148be1d..f494795 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -552,3 +552,12 @@
         handle->interface = 0;
     }
 }
+
+// kCsNoPerm is Linux-only.
+std::string UsbNoPermissionsShortHelpText() {
+    return "";
+}
+
+std::string UsbNoPermissionsLongHelpText() {
+    return "";
+}
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index 8d3501e..9124685 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -659,3 +659,12 @@
   }
   adb_mutex_unlock(&usb_lock);
 }
+
+// kCsNoPerm is Linux-only.
+std::string UsbNoPermissionsShortHelpText() {
+    return "";
+}
+
+std::string UsbNoPermissionsLongHelpText() {
+    return "";
+}
diff --git a/base/include/android-base b/base/include/android-base
deleted file mode 120000
index 8681f8b..0000000
--- a/base/include/android-base
+++ /dev/null
@@ -1 +0,0 @@
-base
\ No newline at end of file
diff --git a/base/include/base/file.h b/base/include/android-base/file.h
similarity index 100%
rename from base/include/base/file.h
rename to base/include/android-base/file.h
diff --git a/base/include/base/logging.h b/base/include/android-base/logging.h
similarity index 100%
rename from base/include/base/logging.h
rename to base/include/android-base/logging.h
diff --git a/base/include/base/macros.h b/base/include/android-base/macros.h
similarity index 100%
rename from base/include/base/macros.h
rename to base/include/android-base/macros.h
diff --git a/base/include/base/memory.h b/base/include/android-base/memory.h
similarity index 100%
rename from base/include/base/memory.h
rename to base/include/android-base/memory.h
diff --git a/base/include/base/parseint.h b/base/include/android-base/parseint.h
similarity index 100%
rename from base/include/base/parseint.h
rename to base/include/android-base/parseint.h
diff --git a/base/include/base/stringprintf.h b/base/include/android-base/stringprintf.h
similarity index 100%
rename from base/include/base/stringprintf.h
rename to base/include/android-base/stringprintf.h
diff --git a/base/include/base/strings.h b/base/include/android-base/strings.h
similarity index 100%
rename from base/include/base/strings.h
rename to base/include/android-base/strings.h
diff --git a/base/include/base/test_utils.h b/base/include/android-base/test_utils.h
similarity index 100%
rename from base/include/base/test_utils.h
rename to base/include/android-base/test_utils.h
diff --git a/base/include/base/unique_fd.h b/base/include/android-base/unique_fd.h
similarity index 100%
rename from base/include/base/unique_fd.h
rename to base/include/android-base/unique_fd.h
diff --git a/base/include/base/utf8.h b/base/include/android-base/utf8.h
similarity index 100%
rename from base/include/base/utf8.h
rename to base/include/android-base/utf8.h
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index 2a9d1d3..b3fdcb4 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -47,7 +47,6 @@
 const char kDefaultLogConfig[] = "/etc/crash_reporter_logs.conf";
 const char kDefaultUserName[] = "chronos";
 const char kLeaveCoreFile[] = "/data/misc/crash_reporter/.leave_core";
-const char kLsbRelease[] = "/etc/lsb-release";
 const char kShellPath[] = "/system/bin/sh";
 const char kSystemCrashPath[] = "/data/misc/crash_reporter/crash";
 const char kUploadVarPrefix[] = "upload_var_";
@@ -90,8 +89,7 @@
 using base::StringPrintf;
 
 CrashCollector::CrashCollector()
-    : lsb_release_(kLsbRelease),
-      log_config_path_(kDefaultLogConfig) {
+    : log_config_path_(kDefaultLogConfig) {
 }
 
 CrashCollector::~CrashCollector() {
diff --git a/crash_reporter/crash_collector.h b/crash_reporter/crash_collector.h
index cfd76fd..24cbfb3 100644
--- a/crash_reporter/crash_collector.h
+++ b/crash_reporter/crash_collector.h
@@ -158,7 +158,6 @@
   IsFeedbackAllowedFunction is_feedback_allowed_function_;
   std::string extra_metadata_;
   base::FilePath forced_crash_directory_;
-  std::string lsb_release_;
   base::FilePath log_config_path_;
 
  private:
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index d00a5b5..b55c324 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -177,15 +177,8 @@
 TEST_F(CrashCollectorTest, MetaData) {
   const char kMetaFileBasename[] = "generated.meta";
   FilePath meta_file = test_dir_.Append(kMetaFileBasename);
-  FilePath lsb_release = test_dir_.Append("lsb-release");
   FilePath payload_file = test_dir_.Append("payload-file");
   std::string contents;
-  collector_.lsb_release_ = lsb_release.value();
-  const char kLsbContents[] =
-      "CHROMEOS_RELEASE_BOARD=lumpy\n"
-      "CHROMEOS_RELEASE_VERSION=6727.0.2015_01_26_0853\n"
-      "CHROMEOS_RELEASE_NAME=Chromium OS\n";
-  ASSERT_TRUE(base::WriteFile(lsb_release, kLsbContents, strlen(kLsbContents)));
   const char kPayload[] = "foo";
   ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
   collector_.AddCrashMetaData("foo", "bar");
@@ -194,7 +187,6 @@
   const char kExpectedMeta[] =
       "foo=bar\n"
       "exec_name=kernel\n"
-      "ver=6727.0.2015_01_26_0853\n"
       "payload=test/payload-file\n"
       "payload_size=3\n"
       "done=1\n";
diff --git a/crash_reporter/crash_reporter_logs_test.cc b/crash_reporter/crash_reporter_logs_test.cc
index e778002..77f5a7f 100644
--- a/crash_reporter/crash_reporter_logs_test.cc
+++ b/crash_reporter/crash_reporter_logs_test.cc
@@ -23,10 +23,11 @@
 namespace {
 
 // Name of the checked-in configuration file containing log-collection commands.
-const char kConfigFile[] = "crash_reporter_logs.conf";
+const char kConfigFile[] = "/system/etc/crash_reporter_logs.conf";
 
-// Executable name for Chrome. kConfigFile is expected to contain this entry.
-const char kChromeExecName[] = "chrome";
+// Signature name for crash_reporter user collection.
+// kConfigFile is expected to contain this entry.
+const char kUserCollectorSignature[] = "crash_reporter-user-collection";
 
 }  // namespace
 
@@ -35,6 +36,6 @@
   brillo::KeyValueStore store;
   ASSERT_TRUE(store.Load(base::FilePath(kConfigFile)));
   std::string command;
-  EXPECT_TRUE(store.GetString(kChromeExecName, &command));
+  EXPECT_TRUE(store.GetString(kUserCollectorSignature, &command));
   EXPECT_FALSE(command.empty());
 }
diff --git a/crash_reporter/kernel_collector_test.cc b/crash_reporter/kernel_collector_test.cc
index cdb0ae7..015f624 100644
--- a/crash_reporter/kernel_collector_test.cc
+++ b/crash_reporter/kernel_collector_test.cc
@@ -253,15 +253,6 @@
   ASSERT_EQ(0, s_crashes);
 }
 
-TEST_F(KernelCollectorTest, CollectBadDirectory) {
-  WriteStringToFile(kcrash_file(), "====1.1\nsomething");
-  ASSERT_TRUE(collector_.Collect());
-  ASSERT_TRUE(FindLog("Unable to create appropriate crash directory"))
-      << "Did not find expected error string in log: {\n"
-      << GetLog() << "}";
-  ASSERT_EQ(1, s_crashes);
-}
-
 void KernelCollectorTest::SetUpSuccessfulCollect() {
   collector_.ForceCrashDirectory(test_crash_directory());
   WriteStringToFile(kcrash_file(), "====1.1\nsomething");
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index 72e61e6..638ea34 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -37,11 +37,6 @@
 
 const char kFilePath[] = "/my/path";
 
-// Keep in sync with UserCollector::ShouldDump.
-const char kChromeIgnoreMsg[] =
-    "ignoring call by kernel - chrome crash; "
-    "waiting for chrome to call us directly";
-
 void CountCrash() {
   ++s_crashes;
 }
@@ -167,24 +162,6 @@
   ASSERT_EQ(s_crashes, 1);
 }
 
-TEST_F(UserCollectorTest, HandleChromeCrashWithConsent) {
-  s_metrics = true;
-  collector_.HandleCrash("5:2:ignored", "chrome");
-  EXPECT_TRUE(FindLog(
-      "Received crash notification for chrome[5] sig 2"));
-  EXPECT_TRUE(FindLog(kChromeIgnoreMsg));
-  ASSERT_EQ(s_crashes, 0);
-}
-
-TEST_F(UserCollectorTest, HandleSuppliedChromeCrashWithConsent) {
-  s_metrics = true;
-  collector_.HandleCrash("0:2:chrome", nullptr);
-  EXPECT_TRUE(FindLog(
-      "Received crash notification for supplied_chrome[0] sig 2"));
-  EXPECT_TRUE(FindLog(kChromeIgnoreMsg));
-  ASSERT_EQ(s_crashes, 0);
-}
-
 TEST_F(UserCollectorTest, GetProcessPath) {
   FilePath path = collector_.GetProcessPath(100);
   ASSERT_EQ("/proc/100", path.value());
@@ -226,7 +203,7 @@
   pid_t my_pid = getpid();
   EXPECT_TRUE(collector_.GetExecutableBaseNameFromPid(my_pid, &base_name));
   EXPECT_FALSE(FindLog("Readlink failed"));
-  EXPECT_EQ("crash_reporter_test", base_name);
+  EXPECT_EQ("crash_reporter_tests", base_name);
 }
 
 TEST_F(UserCollectorTest, GetFirstLineWithPrefix) {
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 884d4d5..0afa895 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -518,11 +518,12 @@
   ALOGI("debuggerd: starting\n");
 
   for (;;) {
-    sockaddr addr;
-    socklen_t alen = sizeof(addr);
+    sockaddr_storage ss;
+    sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
+    socklen_t alen = sizeof(ss);
 
     ALOGV("waiting for connection\n");
-    int fd = accept(s, &addr, &alen);
+    int fd = accept(s, addrp, &alen);
     if (fd < 0) {
       ALOGV("accept failed: %s\n", strerror(errno));
       continue;
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 63904b6..0085a07 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -39,6 +39,7 @@
 #define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
 #define FAKE_BATTERY_CAPACITY 42
 #define FAKE_BATTERY_TEMPERATURE 424
+#define ALWAYS_PLUGGED_CAPACITY 100
 
 namespace android {
 
@@ -211,6 +212,15 @@
         mBatteryFixedTemperature :
         getIntField(mHealthdConfig->batteryTemperaturePath);
 
+    // For devices which do not have battery and are always plugged
+    // into power souce.
+    if (mAlwaysPluggedDevice) {
+        props.chargerAcOnline = true;
+        props.batteryPresent = true;
+        props.batteryStatus = BATTERY_STATUS_CHARGING;
+        props.batteryHealth = BATTERY_HEALTH_GOOD;
+    }
+
     const int SIZE = 128;
     char buf[SIZE];
     String8 btech;
@@ -593,8 +603,15 @@
         closedir(dir);
     }
 
-    if (!mChargerNames.size())
+    // This indicates that there is no charger driver registered.
+    // Typically the case for devices which do not have a battery and
+    // and are always plugged into AC mains.
+    if (!mChargerNames.size()) {
         KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
+        mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
+        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
+        mAlwaysPluggedDevice = true;
+    }
     if (!mBatteryDevicePresent) {
         KLOG_WARNING(LOG_TAG, "No battery devices found\n");
         hc->periodic_chores_interval_fast = -1;
diff --git a/healthd/BatteryMonitor.h b/healthd/BatteryMonitor.h
index 3425f27..a61171f 100644
--- a/healthd/BatteryMonitor.h
+++ b/healthd/BatteryMonitor.h
@@ -46,6 +46,7 @@
     struct healthd_config *mHealthdConfig;
     Vector<String8> mChargerNames;
     bool mBatteryDevicePresent;
+    bool mAlwaysPluggedDevice;
     int mBatteryFixedCapacity;
     int mBatteryFixedTemperature;
     struct BatteryProperties props;
diff --git a/include/log/log.h b/include/log/log.h
index 086d742..619bf23 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -620,6 +620,8 @@
  */
 int __android_log_is_loggable(int prio, const char *tag, int default_prio);
 
+int __android_log_security(); /* Device Owner is present */
+
 int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,
                               uint32_t dataLen);
 
diff --git a/init/init.cpp b/init/init.cpp
index 9f4f625..4aef823 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -350,6 +350,18 @@
     }
 }
 
+static void export_oem_lock_status() {
+    if (property_get("ro.oem_unlock_supported") != "1") {
+        return;
+    }
+
+    std::string value = property_get("ro.boot.verifiedbootstate");
+
+    if (!value.empty()) {
+        property_set("ro.boot.flash.locked", value == "orange" ? "0" : "1");
+    }
+}
+
 static void export_kernel_boot_props() {
     struct {
         const char *src_prop;
@@ -614,6 +626,7 @@
     signal_handler_init();
 
     property_load_boot_defaults();
+    export_oem_lock_status();
     start_property_service();
 
     const BuiltinFunctionMap function_map;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 6e58233..806608e 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -60,35 +60,14 @@
 #define RECOVERY_MOUNT_POINT "/recovery"
 
 static int persistent_properties_loaded = 0;
-static bool property_area_initialized = false;
 
 static int property_set_fd = -1;
 
-struct workspace {
-    size_t size;
-    int fd;
-};
-
-static workspace pa_workspace;
-
 void property_init() {
-    if (property_area_initialized) {
-        return;
-    }
-
-    property_area_initialized = true;
-
     if (__system_property_area_init()) {
         ERROR("Failed to initialize property area\n");
         exit(1);
     }
-
-    pa_workspace.size = 0;
-    pa_workspace.fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
-    if (pa_workspace.fd == -1) {
-        ERROR("Failed to open %s: %s\n", PROP_FILENAME, strerror(errno));
-        return;
-    }
 }
 
 static int check_mac_perms(const char *name, char *sctx, struct ucred *cr)
@@ -354,12 +333,6 @@
     }
 }
 
-void get_property_workspace(int *fd, int *sz)
-{
-    *fd = pa_workspace.fd;
-    *sz = pa_workspace.size;
-}
-
 static void load_properties_from_file(const char *, const char *);
 
 /*
@@ -498,10 +471,6 @@
     load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL);
 }
 
-bool properties_initialized() {
-    return property_area_initialized;
-}
-
 static void load_override_properties() {
     if (ALLOW_LOCAL_PROP_OVERRIDE) {
         std::string debuggable = property_get("ro.debuggable");
diff --git a/init/property_service.h b/init/property_service.h
index 8b76d2b..dbaed34 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -32,10 +32,8 @@
 extern void load_persist_props(void);
 extern void load_system_props(void);
 extern void start_property_service(void);
-void get_property_workspace(int *fd, int *sz);
 std::string property_get(const char* name);
 extern int property_set(const char *name, const char *value);
-extern bool properties_initialized();
 
 
-#endif	/* _INIT_PROPERTY_H */
+#endif  /* _INIT_PROPERTY_H */
diff --git a/init/service.cpp b/init/service.cpp
index 1af3e60..40a4bc7 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -76,11 +76,6 @@
 }
 
 void Service::NotifyStateChange(const std::string& new_state) const {
-    if (!properties_initialized()) {
-        // If properties aren't available yet, we can't set them.
-        return;
-    }
-
     if ((flags_ & SVC_EXEC) != 0) {
         // 'exec' commands don't have properties tracking their state.
         return;
@@ -400,14 +395,7 @@
 
     pid_t pid = fork();
     if (pid == 0) {
-        int fd, sz;
-
         umask(077);
-        if (properties_initialized()) {
-            get_property_workspace(&fd, &sz);
-            std::string tmp = StringPrintf("%d,%d", dup(fd), sz);
-            add_environment("ANDROID_PROPERTY_WORKSPACE", tmp.c_str());
-        }
 
         for (const auto& ei : envvars_) {
             add_environment(ei.name.c_str(), ei.value.c_str());
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index 9c6742e..5d3dd86 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -68,6 +68,7 @@
 # Use static llvm libraries on host to remove dependency on 32-bit llvm shared library
 # which is not included in the prebuilt.
 libbacktrace_static_libraries_host := \
+	libcutils \
 	libLLVMObject \
 	libLLVMBitReader \
 	libLLVMMC \
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index df94280..3c8f879 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -27,8 +27,6 @@
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
 
-#include <cutils/threads.h>
-
 #include "BacktraceLog.h"
 #include "BacktraceOffline.h"
 #include "thread_utils.h"
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index d339550..8e22366 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -29,8 +29,6 @@
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
 
-#include <cutils/threads.h>
-
 #include "BacktraceCurrent.h"
 #include "BacktraceLog.h"
 #include "ThreadEntry.h"
diff --git a/libbacktrace/BacktraceOffline.cpp b/libbacktrace/BacktraceOffline.cpp
index 27dfb83..abc186b 100644
--- a/libbacktrace/BacktraceOffline.cpp
+++ b/libbacktrace/BacktraceOffline.cpp
@@ -22,7 +22,9 @@
 }
 
 #include <stdint.h>
+#include <stdio.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <ucontext.h>
 #include <unistd.h>
@@ -616,7 +618,30 @@
   return debug_frame;
 }
 
+static bool IsValidElfPath(const std::string& filename) {
+  static const char elf_magic[] = {0x7f, 'E', 'L', 'F'};
+
+  struct stat st;
+  if (stat(filename.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) {
+    return false;
+  }
+  FILE* fp = fopen(filename.c_str(), "reb");
+  if (fp == nullptr) {
+    return false;
+  }
+  char buf[4];
+  if (fread(buf, 4, 1, fp) != 1) {
+    fclose(fp);
+    return false;
+  }
+  fclose(fp);
+  return memcmp(buf, elf_magic, 4) == 0;
+}
+
 static DebugFrameInfo* ReadDebugFrameFromFile(const std::string& filename) {
+  if (!IsValidElfPath(filename)) {
+    return nullptr;
+  }
   auto owning_binary = llvm::object::createBinary(llvm::StringRef(filename));
   if (owning_binary.getError()) {
     return nullptr;
diff --git a/libbacktrace/thread_utils.h b/libbacktrace/thread_utils.h
index df83581..9590657 100644
--- a/libbacktrace/thread_utils.h
+++ b/libbacktrace/thread_utils.h
@@ -19,6 +19,10 @@
 
 #include <unistd.h>
 
+#if !defined(__ANDROID__)
+#include <cutils/threads.h>
+#endif
+
 __BEGIN_DECLS
 
 int tgkill(int tgid, int tid, int sig);
diff --git a/libcutils/socket_inaddr_any_server.c b/libcutils/socket_inaddr_any_server.c
index 7f0ccb8..e1b7d84 100644
--- a/libcutils/socket_inaddr_any_server.c
+++ b/libcutils/socket_inaddr_any_server.c
@@ -34,21 +34,21 @@
 /* open listen() port on any interface */
 int socket_inaddr_any_server(int port, int type)
 {
-    struct sockaddr_in addr;
+    struct sockaddr_in6 addr;
     int s, n;
 
     memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    addr.sin6_family = AF_INET6;
+    addr.sin6_port = htons(port);
+    addr.sin6_addr = in6addr_any;
 
-    s = socket(AF_INET, type, 0);
-    if(s < 0) return -1;
+    s = socket(AF_INET6, type, 0);
+    if (s < 0) return -1;
 
     n = 1;
     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
 
-    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
         close(s);
         return -1;
     }
diff --git a/liblog/log_is_loggable.c b/liblog/log_is_loggable.c
index 7fc01d9..b4711d2 100644
--- a/liblog/log_is_loggable.c
+++ b/liblog/log_is_loggable.c
@@ -42,9 +42,12 @@
 struct cache {
     const prop_info *pinfo;
     uint32_t serial;
-    char c;
+    unsigned char c;
 };
 
+#define BOOLEAN_TRUE 0xFF
+#define BOOLEAN_FALSE 0xFE
+
 static void refresh_cache(struct cache *cache, const char *key)
 {
     uint32_t serial;
@@ -62,7 +65,16 @@
     }
     cache->serial = serial;
     __system_property_read(cache->pinfo, 0, buf);
-    cache->c = buf[0];
+    switch(buf[0]) {
+    case 't': case 'T':
+        cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE;
+        break;
+    case 'f': case 'F':
+        cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE;
+        break;
+    default:
+        cache->c = buf[0];
+    }
 }
 
 static int __android_log_level(const char *tag, int default_prio)
@@ -147,6 +159,7 @@
     case 'F': /* Not officially supported */
     case 'A':
     case 'S':
+    case BOOLEAN_FALSE: /* Not officially supported */
         break;
     default:
         /* clear '.' after log.tag */
@@ -180,6 +193,7 @@
     case 'E': return ANDROID_LOG_ERROR;
     case 'F': /* FALLTHRU */ /* Not officially supported */
     case 'A': return ANDROID_LOG_FATAL;
+    case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */
     case 'S': return -1; /* ANDROID_LOG_SUPPRESS */
     }
     return default_prio;
@@ -226,3 +240,36 @@
 
     return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME;
 }
+
+/*
+ * security state generally remains constant, since a change is
+ * rare, we can accept a trylock failure gracefully.
+ */
+static pthread_mutex_t lock_security = PTHREAD_MUTEX_INITIALIZER;
+
+int __android_log_security()
+{
+    static struct cache r_do_cache = { NULL, -1, BOOLEAN_FALSE };
+    static struct cache p_security_cache = { NULL, -1, BOOLEAN_FALSE };
+    int retval;
+
+    if (pthread_mutex_trylock(&lock_security)) {
+        /* We are willing to accept some race in this context */
+        retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c &&
+                 (p_security_cache.c == BOOLEAN_TRUE);
+    } else {
+        static uint32_t serial;
+        uint32_t current_serial = __system_property_area_serial();
+        if (current_serial != serial) {
+            refresh_cache(&r_do_cache, "ro.device_owner");
+            refresh_cache(&p_security_cache, "persist.logd.security");
+            serial = current_serial;
+        }
+        retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c &&
+                 (p_security_cache.c == BOOLEAN_TRUE);
+
+        pthread_mutex_unlock(&lock_security);
+    }
+
+    return retval;
+}
diff --git a/liblog/logprint.c b/liblog/logprint.c
index ad52a81..40e13f4 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -500,14 +500,14 @@
     }
     if (msgEnd == -1) {
         /* incoming message not null-terminated; force it */
-        msgEnd = buf->len - 1;
+        msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */
         msg[msgEnd] = '\0';
     }
 
     entry->priority = msg[0];
     entry->tag = msg + 1;
     entry->message = msg + msgStart;
-    entry->messageLen = msgEnd - msgStart;
+    entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart);
 
     return 0;
 }
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 110f1eb..597d8f6 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -164,6 +164,43 @@
     android_logger_list_close(logger_list);
 }
 
+TEST(liblog, __security) {
+    static const char persist_key[] = "persist.logd.security";
+    static const char readonly_key[] = "ro.device_owner";
+    static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
+    char persist[PROP_VALUE_MAX];
+    char readonly[PROP_VALUE_MAX];
+
+    property_get(persist_key, persist, "");
+    property_get(readonly_key, readonly, nothing_val);
+
+    if (!strcmp(readonly, nothing_val)) {
+        EXPECT_FALSE(__android_log_security());
+        fprintf(stderr, "Warning, setting ro.device_owner to a domain\n");
+        property_set(readonly_key, "com.google.android.SecOps.DeviceOwner");
+    } else if (!strcasecmp(readonly, "false") || !readonly[0]) {
+        EXPECT_FALSE(__android_log_security());
+        return;
+    }
+
+    if (!strcasecmp(persist, "true")) {
+        EXPECT_TRUE(__android_log_security());
+    } else {
+        EXPECT_FALSE(__android_log_security());
+    }
+    property_set(persist_key, "TRUE");
+    EXPECT_TRUE(__android_log_security());
+    property_set(persist_key, "FALSE");
+    EXPECT_FALSE(__android_log_security());
+    property_set(persist_key, "true");
+    EXPECT_TRUE(__android_log_security());
+    property_set(persist_key, "false");
+    EXPECT_FALSE(__android_log_security());
+    property_set(persist_key, "");
+    EXPECT_FALSE(__android_log_security());
+    property_set(persist_key, persist);
+}
+
 static unsigned signaled;
 log_time signal_time;
 
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 33870e2..654bcb8 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -28,8 +28,8 @@
 #include <string>
 #include <mutex>
 
-#include "base/macros.h"
-#include "base/strings.h"
+#include "android-base/macros.h"
+#include "android-base/strings.h"
 
 namespace android {
 
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 3011ed7..168899c 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -199,13 +199,14 @@
             continue;
         }
         if (mListen && FD_ISSET(mSock, &read_fds)) {
-            struct sockaddr addr;
+            sockaddr_storage ss;
+            sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
             socklen_t alen;
             int c;
 
             do {
-                alen = sizeof(addr);
-                c = accept(mSock, &addr, &alen);
+                alen = sizeof(ss);
+                c = accept(mSock, addrp, &alen);
                 SLOGV("%s got %d from accept", mSocketName, c);
             } while (c < 0 && errno == EINTR);
             if (c < 0) {
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 7bbc811..50bf6a4 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -410,7 +410,8 @@
 }
 
 static void ctrl_connect_handler(uint32_t events __unused) {
-    struct sockaddr addr;
+    struct sockaddr_storage ss;
+    struct sockaddr *addrp = (struct sockaddr *)&ss;
     socklen_t alen;
     struct epoll_event epev;
 
@@ -419,8 +420,8 @@
         ctrl_dfd_reopened = 1;
     }
 
-    alen = sizeof(addr);
-    ctrl_dfd = accept(ctrl_lfd, &addr, &alen);
+    alen = sizeof(ss);
+    ctrl_dfd = accept(ctrl_lfd, addrp, &alen);
 
     if (ctrl_dfd < 0) {
         ALOGE("lmkd control socket accept failed; errno=%d", errno);
diff --git a/metricsd/metrics_collector.cc b/metricsd/metrics_collector.cc
index 28f9ad3..f3871e4 100644
--- a/metricsd/metrics_collector.cc
+++ b/metricsd/metrics_collector.cc
@@ -40,8 +40,6 @@
 using base::TimeDelta;
 using base::TimeTicks;
 using chromeos_metrics::PersistentInteger;
-using com::android::Weave::CommandProxy;
-using com::android::Weave::ManagerProxy;
 using std::map;
 using std::string;
 using std::vector;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 99c5526..011defb 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -138,23 +138,27 @@
     # sets up initial cpusets for ActivityManager
     mkdir /dev/cpuset
     mount cpuset none /dev/cpuset
-    mkdir /dev/cpuset/foreground
-    mkdir /dev/cpuset/foreground/boost
-    mkdir /dev/cpuset/background
-    # system-background is for system tasks that should only run on
-    # little cores, not on bigs
-    # to be used only by init, so don't change the permissions
-    mkdir /dev/cpuset/system-background
+
     # this ensures that the cpusets are present and usable, but the device's
     # init.rc must actually set the correct cpus
+    mkdir /dev/cpuset/foreground
     write /dev/cpuset/foreground/cpus 0
-    write /dev/cpuset/foreground/boost/cpus 0
-    write /dev/cpuset/background/cpus 0
-    write /dev/cpuset/system-background/cpus 0
     write /dev/cpuset/foreground/mems 0
+    mkdir /dev/cpuset/foreground/boost
+    write /dev/cpuset/foreground/boost/cpus 0
     write /dev/cpuset/foreground/boost/mems 0
+    mkdir /dev/cpuset/background
+    write /dev/cpuset/background/cpus 0
     write /dev/cpuset/background/mems 0
+
+    # system-background is for system tasks that should only run on
+    # little cores, not on bigs
+    # to be used only by init, so don't change system-bg permissions
+    mkdir /dev/cpuset/system-background
+    write /dev/cpuset/system-background/cpus 0
     write /dev/cpuset/system-background/mems 0
+
+    # change permissions for all cpusets we'll touch at runtime
     chown system system /dev/cpuset
     chown system system /dev/cpuset/foreground
     chown system system /dev/cpuset/foreground/boost
@@ -244,6 +248,9 @@
     # Mount default storage into root namespace
     mount none /mnt/runtime/default /storage slave bind rec
 
+    # Make sure /sys/kernel/debug (if present) is labeled properly
+    restorecon_recursive /sys/kernel/debug
+
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
     chmod 0770 /cache