Merge "Fix ScopedSignalHandler"
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp
index 523e1f1..e51a06d 100644
--- a/healthd/BatteryPropertiesRegistrar.cpp
+++ b/healthd/BatteryPropertiesRegistrar.cpp
@@ -36,9 +36,19 @@
 }
 
 void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) {
-    Mutex::Autolock _l(mRegistrationLock);
-    for (size_t i = 0; i < mListeners.size(); i++) {
-        mListeners[i]->batteryPropertiesChanged(props);
+    Vector<sp<IBatteryPropertiesListener> > listenersCopy;
+
+    // Binder currently may service an incoming oneway transaction whenever an
+    // outbound oneway call is made (if there is already a pending incoming
+    // oneway call waiting).  This is considered a bug and may change in the
+    // future.  For now, avoid recursive mutex lock while making outbound
+    // calls by making a local copy of the current list of listeners.
+    {
+        Mutex::Autolock _l(mRegistrationLock);
+        listenersCopy = mListeners;
+    }
+    for (size_t i = 0; i < listenersCopy.size(); i++) {
+        listenersCopy[i]->batteryPropertiesChanged(props);
     }
 }
 
diff --git a/init/capabilities.cpp b/init/capabilities.cpp
index 53832a4..642a364 100644
--- a/init/capabilities.cpp
+++ b/init/capabilities.cpp
@@ -107,17 +107,15 @@
 }
 
 static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
-    cap_t caps = cap_init();
-    auto deleter = [](cap_t* p) { cap_free(*p); };
-    std::unique_ptr<cap_t, decltype(deleter)> ptr_caps(&caps, deleter);
+    ScopedCaps caps(cap_init());
 
-    cap_clear(caps);
+    cap_clear(caps.get());
     cap_value_t value[1];
     for (size_t cap = 0; cap < to_keep.size(); ++cap) {
         if (to_keep.test(cap)) {
             value[0] = cap;
-            if (cap_set_flag(caps, CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
-                cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
+            if (cap_set_flag(caps.get(), CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
+                cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
                 PLOG(ERROR) << "cap_set_flag(INHERITABLE|PERMITTED, " << cap << ") failed";
                 return false;
             }
@@ -126,14 +124,14 @@
 
     if (add_setpcap) {
         value[0] = CAP_SETPCAP;
-        if (cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
-            cap_set_flag(caps, CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
+        if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
+            cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
             PLOG(ERROR) << "cap_set_flag(PERMITTED|EFFECTIVE, " << CAP_SETPCAP << ") failed";
             return false;
         }
     }
 
-    if (cap_set_proc(caps) != 0) {
+    if (cap_set_proc(caps.get()) != 0) {
         PLOG(ERROR) << "cap_set_proc(" << to_keep.to_ulong() << ") failed";
         return false;
     }
diff --git a/init/capabilities.h b/init/capabilities.h
index ef507a6..ede85c3 100644
--- a/init/capabilities.h
+++ b/init/capabilities.h
@@ -15,15 +15,21 @@
 #ifndef _INIT_CAPABILITIES_H
 #define _INIT_CAPABILITIES_H
 
-#include <linux/capability.h>
+#include <sys/capability.h>
 
 #include <bitset>
 #include <string>
+#include <type_traits>
 
 namespace android {
 namespace init {
 
+struct CapDeleter {
+    void operator()(cap_t caps) const { cap_free(caps); }
+};
+
 using CapSet = std::bitset<CAP_LAST_CAP + 1>;
+using ScopedCaps = std::unique_ptr<std::remove_pointer<cap_t>::type, CapDeleter>;
 
 int LookupCap(const std::string& cap_name);
 bool CapAmbientSupported();
diff --git a/init/reboot.cpp b/init/reboot.cpp
index df7912f..c8bb98b 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <mntent.h>
 #include <selinux/selinux.h>
+#include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
@@ -48,6 +49,7 @@
 #include <logwrap/logwrap.h>
 #include <private/android_filesystem_config.h>
 
+#include "capabilities.h"
 #include "property_service.h"
 #include "service.h"
 
@@ -162,9 +164,38 @@
     LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration_ms()) << ":" << stat;
 }
 
+// Determines whether the system is capable of rebooting. This is conservative,
+// so if any of the attempts to determine this fail, it will still return true.
+static bool IsRebootCapable() {
+    if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
+        PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
+        return true;
+    }
+
+    ScopedCaps caps(cap_get_proc());
+    if (!caps) {
+        PLOG(WARNING) << "cap_get_proc() failed";
+        return true;
+    }
+
+    cap_flag_value_t value = CAP_SET;
+    if (cap_get_flag(caps.get(), CAP_SYS_BOOT, CAP_EFFECTIVE, &value) != 0) {
+        PLOG(WARNING) << "cap_get_flag(CAP_SYS_BOOT, EFFECTIVE) failed";
+        return true;
+    }
+    return value == CAP_SET;
+}
+
 static void __attribute__((noreturn))
 RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
     LOG(INFO) << "Reboot ending, jumping to kernel";
+
+    if (!IsRebootCapable()) {
+        // On systems where init does not have the capability of rebooting the
+        // device, just exit cleanly.
+        exit(0);
+    }
+
     switch (cmd) {
         case ANDROID_RB_POWEROFF:
             reboot(RB_POWER_OFF);
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index bc40ba9..f733e90 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -118,7 +118,6 @@
 
     In older releases, this was controlled by build-time configuration.
  */
-
 bool cpusets_enabled() {
     static bool enabled = (access("/dev/cpuset/tasks", F_OK) == 0);
 
@@ -130,12 +129,8 @@
     CONFIG_CGROUP_SCHEDTUNE that's in Android common Linux kernel and Linaro
     Stable Kernel (LSK), but not in mainline Linux as of v4.9.
 
-    With runtime check using the following function, build time
-    variables like ENABLE_SCHEDBOOST (used in Android.mk) or schedboost
-    (used in Android.bp) are not needed.
-
+    In older releases, this was controlled by build-time configuration.
  */
-
 bool schedboost_enabled() {
     static bool enabled = (access("/dev/stune/tasks", F_OK) == 0);
 
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index f5d4e1c..9b8248e 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -43,9 +43,6 @@
 
 using namespace std::chrono_literals;
 
-// Uncomment line below use memory cgroups for keeping track of (forked) PIDs
-// #define USE_MEMCG 1
-
 #define MEM_CGROUP_PATH "/dev/memcg/apps"
 #define MEM_CGROUP_TASKS "/dev/memcg/apps/tasks"
 #define ACCT_CGROUP_PATH "/acct"
@@ -91,7 +88,6 @@
 };
 
 static const char* getCgroupRootPath() {
-#ifdef USE_MEMCG
     static const char* cgroup_root_path = NULL;
     std::call_once(init_path_flag, [&]() {
             // Check if mem cgroup is mounted, only then check for write-access to avoid
@@ -100,9 +96,6 @@
                     ACCT_CGROUP_PATH : MEM_CGROUP_PATH;
             });
     return cgroup_root_path;
-#else
-    return ACCT_CGROUP_PATH;
-#endif
 }
 
 static int convertUidToPath(char *path, size_t size, uid_t uid)
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 621d14c..8776db7 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -76,17 +76,6 @@
     defaults: ["libunwindstack_common"],
 }
 
-cc_library {
-    name: "libunwindstack_debug",
-    defaults: ["libunwindstack_common"],
-
-    cflags: [
-        "-UNDEBUG",
-        "-O0",
-        "-g",
-    ],
-}
-
 //-------------------------------------------------------------------------
 // Unit Tests
 //-------------------------------------------------------------------------
@@ -160,21 +149,6 @@
     ],
 }
 
-// These unit tests run against the static debug library.
-cc_test {
-    name: "libunwindstack_test_debug",
-    defaults: ["libunwindstack_test_common"],
-
-    static_libs: [
-        "libunwindstack_debug",
-    ],
-
-    data: [
-        "tests/elf32.xz",
-        "tests/elf64.xz",
-    ],
-}
-
 //-------------------------------------------------------------------------
 // Utility Executables
 //-------------------------------------------------------------------------
diff --git a/libunwindstack/ArmExidx.cpp b/libunwindstack/ArmExidx.cpp
index 12adf57..5c7caca 100644
--- a/libunwindstack/ArmExidx.cpp
+++ b/libunwindstack/ArmExidx.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <assert.h>
 #include <stdint.h>
 
 #include <deque>
@@ -23,6 +22,7 @@
 #include <android-base/stringprintf.h>
 
 #include "ArmExidx.h"
+#include "Check.h"
 #include "Log.h"
 #include "Machine.h"
 #include "Memory.h"
@@ -173,7 +173,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_10_00(uint8_t byte) {
-  assert((byte >> 4) == 0x8);
+  CHECK((byte >> 4) == 0x8);
 
   uint16_t registers = (byte & 0xf) << 8;
   if (!GetByte(&byte)) {
@@ -232,7 +232,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_10_01(uint8_t byte) {
-  assert((byte >> 4) == 0x9);
+  CHECK((byte >> 4) == 0x9);
 
   uint8_t bits = byte & 0xf;
   if (bits == 13 || bits == 15) {
@@ -258,7 +258,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_10_10(uint8_t byte) {
-  assert((byte >> 4) == 0xa);
+  CHECK((byte >> 4) == 0xa);
 
   // 10100nnn: Pop r4-r[4+nnn]
   // 10101nnn: Pop r4-r[4+nnn], r14
@@ -419,7 +419,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_10_11_1nnn(uint8_t byte) {
-  assert((byte & ~0x07) == 0xb8);
+  CHECK((byte & ~0x07) == 0xb8);
 
   // 10111nnn: Pop VFP double-precision registers D[8]-D[8+nnn] by FSTMFDX
   if (log_) {
@@ -439,7 +439,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_10(uint8_t byte) {
-  assert((byte >> 6) == 0x2);
+  CHECK((byte >> 6) == 0x2);
 
   switch ((byte >> 4) & 0x3) {
   case 0:
@@ -469,7 +469,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_11_000(uint8_t byte) {
-  assert((byte & ~0x07) == 0xc0);
+  CHECK((byte & ~0x07) == 0xc0);
 
   uint8_t bits = byte & 0x7;
   if (bits == 6) {
@@ -550,7 +550,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_11_001(uint8_t byte) {
-  assert((byte & ~0x07) == 0xc8);
+  CHECK((byte & ~0x07) == 0xc8);
 
   uint8_t bits = byte & 0x7;
   if (bits == 0) {
@@ -605,7 +605,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_11_010(uint8_t byte) {
-  assert((byte & ~0x07) == 0xd0);
+  CHECK((byte & ~0x07) == 0xd0);
 
   // 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
   if (log_) {
@@ -624,7 +624,7 @@
 }
 
 inline bool ArmExidx::DecodePrefix_11(uint8_t byte) {
-  assert((byte >> 6) == 0x3);
+  CHECK((byte >> 6) == 0x3);
 
   switch ((byte >> 3) & 0x7) {
   case 0:
diff --git a/libunwindstack/Check.h b/libunwindstack/Check.h
new file mode 100644
index 0000000..e0c48c7
--- /dev/null
+++ b/libunwindstack/Check.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBUNWINDSTACK_ERROR_H
+#define _LIBUNWINDSTACK_ERROR_H
+
+#include <stdlib.h>
+
+#include "Log.h"
+
+#define CHECK(assertion)                                   \
+  if (__builtin_expect(!(assertion), false)) {             \
+    log(0, "%s:%d: %s\n", __FILE__, __LINE__, #assertion); \
+    abort();                                               \
+  }
+
+#endif  // _LIBUNWINDSTACK_ERROR_H
diff --git a/libunwindstack/DwarfEhFrame.cpp b/libunwindstack/DwarfEhFrame.cpp
index 045fb36..937b6bd 100644
--- a/libunwindstack/DwarfEhFrame.cpp
+++ b/libunwindstack/DwarfEhFrame.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include <assert.h>
 #include <stdint.h>
 
+#include "Check.h"
 #include "DwarfEhFrame.h"
 #include "DwarfMemory.h"
 #include "DwarfSection.h"
@@ -105,8 +105,8 @@
 template <typename AddressType>
 bool DwarfEhFrame<AddressType>::GetFdeOffsetBinary(uint64_t pc, uint64_t* fde_offset,
                                                    uint64_t total_entries) {
-  assert(fde_count_ > 0);
-  assert(total_entries <= fde_count_);
+  CHECK(fde_count_ > 0);
+  CHECK(total_entries <= fde_count_);
 
   size_t first = 0;
   size_t last = total_entries;
@@ -133,7 +133,7 @@
 
 template <typename AddressType>
 bool DwarfEhFrame<AddressType>::GetFdeOffsetSequential(uint64_t pc, uint64_t* fde_offset) {
-  assert(fde_count_ != 0);
+  CHECK(fde_count_ != 0);
   last_error_ = DWARF_ERROR_NONE;
   // We can do a binary search if the pc is in the range of the elements
   // that have already been cached.
diff --git a/libunwindstack/DwarfMemory.cpp b/libunwindstack/DwarfMemory.cpp
index 11806ea..a984fc6 100644
--- a/libunwindstack/DwarfMemory.cpp
+++ b/libunwindstack/DwarfMemory.cpp
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-#include <assert.h>
 #include <stdint.h>
 
 #include <string>
 
+#include "Check.h"
 #include "DwarfEncoding.h"
 #include "DwarfMemory.h"
 #include "Memory.h"
@@ -100,8 +100,8 @@
 }
 
 bool DwarfMemory::AdjustEncodedValue(uint8_t encoding, uint64_t* value) {
-  assert((encoding & 0x0f) == 0);
-  assert(encoding != DW_EH_PE_aligned);
+  CHECK((encoding & 0x0f) == 0);
+  CHECK(encoding != DW_EH_PE_aligned);
 
   // Handle the encoding.
   switch (encoding) {
diff --git a/libunwindstack/Memory.h b/libunwindstack/Memory.h
index f9f6d56..e353cab 100644
--- a/libunwindstack/Memory.h
+++ b/libunwindstack/Memory.h
@@ -17,7 +17,6 @@
 #ifndef _LIBUNWINDSTACK_MEMORY_H
 #define _LIBUNWINDSTACK_MEMORY_H
 
-#include <assert.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -25,6 +24,8 @@
 #include <string>
 #include <vector>
 
+#include "Check.h"
+
 class Memory {
  public:
   Memory() = default;
@@ -130,7 +131,7 @@
  public:
   MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
       : memory_(memory), begin_(begin), length_(end - begin) {
-    assert(end > begin);
+    CHECK(end > begin);
   }
   virtual ~MemoryRange() { delete memory_; }
 
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index e7d10b2..da22b07 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <assert.h>
 #include <elf.h>
 #include <stdint.h>
 #include <sys/ptrace.h>
@@ -22,6 +21,7 @@
 
 #include <vector>
 
+#include "Check.h"
 #include "Elf.h"
 #include "ElfInterface.h"
 #include "Machine.h"
@@ -43,7 +43,7 @@
 bool RegsImpl<AddressType>::GetReturnAddressFromDefault(Memory* memory, uint64_t* value) {
   switch (return_loc_.type) {
   case LOCATION_REGISTER:
-    assert(return_loc_.value < total_regs_);
+    CHECK(return_loc_.value < total_regs_);
     *value = regs_[return_loc_.value];
     return true;
   case LOCATION_SP_OFFSET:
diff --git a/libunwindstack/Symbols.cpp b/libunwindstack/Symbols.cpp
index 86c1233..edc2187 100644
--- a/libunwindstack/Symbols.cpp
+++ b/libunwindstack/Symbols.cpp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#include <assert.h>
 #include <elf.h>
 #include <stdint.h>
 
 #include <string>
 
+#include "Check.h"
 #include "Memory.h"
 #include "Symbols.h"
 
@@ -58,7 +58,7 @@
   if (symbols_.size() != 0) {
     const Info* info = GetInfoFromCache(addr);
     if (info) {
-      assert(addr >= info->start_offset && addr <= info->end_offset);
+      CHECK(addr >= info->start_offset && addr <= info->end_offset);
       *func_offset = addr - info->start_offset;
       return elf_memory->ReadString(info->str_offset, name, str_end_ - info->str_offset);
     }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d9fe090..ebbec35 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -36,6 +36,8 @@
     mount cgroup none /dev/memcg memory
     # app mem cgroups, used by activity manager, lmkd and zygote
     mkdir /dev/memcg/apps/ 0755 system system
+    # cgroup for system_server and surfaceflinger
+    mkdir /dev/memcg/system 0755 system system
 
     start ueventd