Merge "Add "require partition-exists=" support."
diff --git a/adb/Android.bp b/adb/Android.bp
index bbf7cb4..d81bb4b 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -72,8 +72,17 @@
                 "-DUNICODE=1",
                 "-D_UNICODE=1",
 
-                // -std=gnu++14 doesn't set _GNU_SOURCE on Windows.
+                // -std=gnu++11 doesn't set _GNU_SOURCE on Windows.
                 "-D_GNU_SOURCE",
+
+                // MinGW hides some things behind _POSIX_SOURCE.
+                "-D_POSIX_SOURCE",
+            ],
+
+            host_ldlibs: [
+                "-lws2_32",
+                "-lgdi32",
+                "-luserenv",
             ],
         },
     },
@@ -173,6 +182,13 @@
         "libdiagnose_usb",
         "libusb",
     ],
+
+    target: {
+        windows: {
+            enabled: true,
+            shared_libs: ["AdbWinApi"],
+        },
+    },
 }
 
 cc_binary_host {
@@ -220,11 +236,6 @@
         windows: {
             enabled: true,
             ldflags: ["-municode"],
-            host_ldlibs: [
-                "-lws2_32",
-                "-lgdi32",
-            ],
-
             shared_libs: ["AdbWinApi"],
             required: [
                 "AdbWinUsbApi",
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index c58c67a..ab11bdd 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -269,7 +269,7 @@
 
     if (h->control < 0) { // might have already done this before
         LOG(INFO) << "opening control endpoint " << USB_FFS_ADB_EP0;
-        h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
+        h->control = adb_open(USB_FFS_ADB_EP0, O_WRONLY);
         if (h->control < 0) {
             PLOG(ERROR) << "cannot open control endpoint " << USB_FFS_ADB_EP0;
             goto err;
@@ -300,13 +300,13 @@
         android::base::SetProperty("sys.usb.ffs.ready", "1");
     }
 
-    h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
+    h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDONLY);
     if (h->bulk_out < 0) {
         PLOG(ERROR) << "cannot open bulk-out endpoint " << USB_FFS_ADB_OUT;
         goto err;
     }
 
-    h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
+    h->bulk_in = adb_open(USB_FFS_ADB_IN, O_WRONLY);
     if (h->bulk_in < 0) {
         PLOG(ERROR) << "cannot open bulk-in endpoint " << USB_FFS_ADB_IN;
         goto err;
diff --git a/adb/fdevent_test.cpp b/adb/fdevent_test.cpp
index 95dc4c2..e3d5a35 100644
--- a/adb/fdevent_test.cpp
+++ b/adb/fdevent_test.cpp
@@ -26,6 +26,7 @@
 
 #include "adb_io.h"
 #include "fdevent_test.h"
+#include "sysdeps/memory.h"
 
 class FdHandler {
   public:
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index fd08ad8..3be99f6 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -106,14 +106,14 @@
 #define  mkdir  ___xxx_mkdir
 
 // See the comments for the !defined(_WIN32) versions of adb_*().
-extern int  adb_open(const char*  path, int  options);
-extern int  adb_creat(const char*  path, int  mode);
-extern int  adb_read(int  fd, void* buf, int len);
-extern int  adb_write(int  fd, const void*  buf, int  len);
-extern int  adb_lseek(int  fd, int  pos, int  where);
-extern int  adb_shutdown(int  fd);
-extern int  adb_close(int  fd);
-extern int  adb_register_socket(SOCKET s);
+extern int adb_open(const char* path, int options);
+extern int adb_creat(const char* path, int mode);
+extern int adb_read(int fd, void* buf, int len);
+extern int adb_write(int fd, const void* buf, int len);
+extern int adb_lseek(int fd, int pos, int where);
+extern int adb_shutdown(int fd, int direction = SHUT_RDWR);
+extern int adb_close(int fd);
+extern int adb_register_socket(SOCKET s);
 
 // See the comments for the !defined(_WIN32) version of unix_close().
 static __inline__ int  unix_close(int fd)
@@ -414,14 +414,10 @@
 #undef   open
 #define  open    ___xxx_open
 
-static __inline__ int  adb_shutdown(int fd)
-{
-    return shutdown(fd, SHUT_RDWR);
-}
-static __inline__ int  adb_shutdown(int fd, int direction)
-{
+static __inline__ int adb_shutdown(int fd, int direction = SHUT_RDWR) {
     return shutdown(fd, direction);
 }
+
 #undef   shutdown
 #define  shutdown   ____xxx_shutdown
 
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index cd7d187..62f4ac8 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -1011,9 +1011,8 @@
     return ntohs(reinterpret_cast<sockaddr_in*>(&addr_storage)->sin_port);
 }
 
-int  adb_shutdown(int  fd)
-{
-    FH   f = _fh_from_int(fd, __func__);
+int adb_shutdown(int fd, int direction) {
+    FH f = _fh_from_int(fd, __func__);
 
     if (!f || f->clazz != &_fh_socket_class) {
         D("adb_shutdown: invalid fd %d", fd);
@@ -1021,8 +1020,8 @@
         return -1;
     }
 
-    D( "adb_shutdown: %s", f->name);
-    if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
+    D("adb_shutdown: %s", f->name);
+    if (shutdown(f->fh_socket, direction) == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
         D("socket shutdown fd %d failed: %s", fd,
           android::base::SystemErrorCodeToString(err).c_str());
diff --git a/base/include/android-base/scopeguard.h b/base/include/android-base/scopeguard.h
index abcf4bc..c314e02 100644
--- a/base/include/android-base/scopeguard.h
+++ b/base/include/android-base/scopeguard.h
@@ -17,20 +17,27 @@
 #ifndef ANDROID_BASE_SCOPEGUARD_H
 #define ANDROID_BASE_SCOPEGUARD_H
 
-#include <utility>  // for std::move
+#include <utility>  // for std::move, std::forward
 
 namespace android {
 namespace base {
 
+// ScopeGuard ensures that the specified functor is executed no matter how the
+// current scope exits.
 template <typename F>
 class ScopeGuard {
  public:
-  ScopeGuard(F f) : f_(f), active_(true) {}
+  ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {}
 
   ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) {
     that.active_ = false;
   }
 
+  template <typename Functor>
+  ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
+    that.active_ = false;
+  }
+
   ~ScopeGuard() {
     if (active_) f_();
   }
@@ -45,13 +52,16 @@
   bool active() const { return active_; }
 
  private:
+  template <typename Functor>
+  friend class ScopeGuard;
+
   F f_;
   bool active_;
 };
 
-template <typename T>
-ScopeGuard<T> make_scope_guard(T f) {
-  return ScopeGuard<T>(f);
+template <typename F>
+ScopeGuard<F> make_scope_guard(F&& f) {
+  return ScopeGuard<F>(std::forward<F>(f));
 }
 
 }  // namespace base
diff --git a/base/scopeguard_test.cpp b/base/scopeguard_test.cpp
index e11154a..9236d7b 100644
--- a/base/scopeguard_test.cpp
+++ b/base/scopeguard_test.cpp
@@ -17,6 +17,7 @@
 #include "android-base/scopeguard.h"
 
 #include <utility>
+#include <vector>
 
 #include <gtest/gtest.h>
 
@@ -44,3 +45,15 @@
   EXPECT_FALSE(scopeguard.active());
   ASSERT_FALSE(guarded_var);
 }
+
+TEST(scopeguard, vector) {
+  int guarded_var = 0;
+  {
+    std::vector<android::base::ScopeGuard<std::function<void()>>> scopeguards;
+    scopeguards.emplace_back(android::base::make_scope_guard(
+        std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var))));
+    scopeguards.emplace_back(android::base::make_scope_guard(
+        std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var))));
+  }
+  ASSERT_EQ(guarded_var, 2);
+}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4089490..237f081 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -123,6 +123,8 @@
     { nullptr,    "boot_other.img",   "boot.sig",     "boot",     true,  true  },
     { "dtbo",     "dtbo.img",         "dtbo.sig",     "dtbo",     true,  false },
     { "dts",      "dt.img",           "dt.sig",       "dts",      true,  false },
+    { "odm",      "odm.img",          "odm.sig",      "odm",      true,  false },
+    { "product",  "product.img",      "product.sig",  "product",  true,  false },
     { "recovery", "recovery.img",     "recovery.sig", "recovery", true,  false },
     { "system",   "system.img",       "system.sig",   "system",   false, false },
     { nullptr,    "system_other.img", "system.sig",   "system",   true,  true  },
diff --git a/init/stable_properties.h b/init/stable_properties.h
index bd568f0..c8bdaa4 100644
--- a/init/stable_properties.h
+++ b/init/stable_properties.h
@@ -37,6 +37,7 @@
     "persist.sys.zram_enabled",
     "ro.bootmode",
     "ro.build.type",
+    "ro.debuggable",
     "sys.boot_completed",
     "sys.retaildemo.enabled",
     "sys.shutdown.requested",
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 711a12a..e087b2e 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -163,6 +163,9 @@
   }
 
   std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
+  if (!skip_frames_) {
+    skip_names.clear();
+  }
   return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, &skip_names, &error_);
 }
 
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index aab6db9..1e3d379 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -69,6 +69,9 @@
 // Number of simultaneous threads running in our forked process.
 #define NUM_PTRACE_THREADS 5
 
+// The list of shared libaries that make up the backtrace library.
+static std::vector<std::string> kBacktraceLibs{"libunwindstack.so", "libbacktrace.so"};
+
 struct thread_t {
   pid_t tid;
   int32_t state;
@@ -256,16 +259,49 @@
   VERIFY_NO_ERROR(backtrace->GetError().error_code);
 
   ASSERT_TRUE(backtrace->NumFrames() != 0);
+  // None of the frames should be in the backtrace libraries.
   for (const auto& frame : *backtrace ) {
     if (BacktraceMap::IsValid(frame.map)) {
       const std::string name = basename(frame.map.name.c_str());
-      ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so")
-        << DumpFrames(backtrace.get());
+      for (const auto& lib : kBacktraceLibs) {
+        ASSERT_TRUE(name != lib) << DumpFrames(backtrace.get());
+      }
     }
-    break;
   }
 }
 
+TEST(libbacktrace, local_unwind_frames) {
+  // Verify that a local unwind with the skip frames disabled does include
+  // frames within the backtrace libraries.
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid()));
+  ASSERT_TRUE(backtrace.get() != nullptr);
+  backtrace->SetSkipFrames(false);
+  ASSERT_TRUE(backtrace->Unwind(0));
+  VERIFY_NO_ERROR(backtrace->GetError().error_code);
+
+  ASSERT_TRUE(backtrace->NumFrames() != 0);
+  size_t first_frame_non_backtrace_lib = 0;
+  for (const auto& frame : *backtrace) {
+    if (BacktraceMap::IsValid(frame.map)) {
+      const std::string name = basename(frame.map.name.c_str());
+      bool found = false;
+      for (const auto& lib : kBacktraceLibs) {
+        if (name == lib) {
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        first_frame_non_backtrace_lib = frame.num;
+        break;
+      }
+    }
+  }
+
+  ASSERT_NE(0U, first_frame_non_backtrace_lib) << "No frames found in backtrace libraries:\n"
+                                               << DumpFrames(backtrace.get());
+}
+
 TEST(libbacktrace, local_trace) {
   ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0);
 }
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index a088207..735a2f3 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -204,6 +204,9 @@
 
   std::string GetErrorString(BacktraceUnwindError error);
 
+  // Set whether to skip frames in libbacktrace/libunwindstack when doing a local unwind.
+  void SetSkipFrames(bool skip_frames) { skip_frames_ = skip_frames; }
+
  protected:
   Backtrace(pid_t pid, pid_t tid, BacktraceMap* map);
 
@@ -223,6 +226,9 @@
 
   std::vector<backtrace_frame_data_t> frames_;
 
+  // Skip frames in libbacktrace/libunwindstack when doing a local unwind.
+  bool skip_frames_ = true;
+
   BacktraceUnwindError error_;
 };
 
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index b2779b2..bbb150d 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -73,7 +73,8 @@
 #define ATRACE_TAG_NETWORK          (1<<21)
 #define ATRACE_TAG_ADB              (1<<22)
 #define ATRACE_TAG_VIBRATOR         (1<<23)
-#define ATRACE_TAG_LAST             ATRACE_TAG_VIBRATOR
+#define ATRACE_TAG_AIDL             (1<<24)
+#define ATRACE_TAG_LAST             ATRACE_TAG_AIDL
 
 // Reserved for initialization.
 #define ATRACE_TAG_NOT_READY        (1ULL<<63)
diff --git a/property_service/property_info_checker/Android.bp b/property_service/property_info_checker/Android.bp
index 6ee649a..7d66199 100644
--- a/property_service/property_info_checker/Android.bp
+++ b/property_service/property_info_checker/Android.bp
@@ -7,6 +7,7 @@
         "libpropertyinfoserializer",
         "libpropertyinfoparser",
         "libbase",
+        "libsepol",
     ],
     srcs: ["property_info_checker.cpp"],
 }
diff --git a/property_service/property_info_checker/property_info_checker.cpp b/property_service/property_info_checker/property_info_checker.cpp
index e4f8264..52c4383 100644
--- a/property_service/property_info_checker/property_info_checker.cpp
+++ b/property_service/property_info_checker/property_info_checker.cpp
@@ -1,26 +1,150 @@
 #include <iostream>
+#include <memory>
 #include <string>
 #include <vector>
 
 #include <android-base/file.h>
-
+#include <property_info_parser/property_info_parser.h>
 #include <property_info_serializer/property_info_serializer.h>
+#include <sepol/context.h>
+#include <sepol/context_record.h>
+#include <sepol/handle.h>
+#include <sepol/policydb.h>
+#include <sepol/policydb/policydb.h>
 
 using android::base::ReadFileToString;
 using android::properties::BuildTrie;
 using android::properties::ParsePropertyInfoFile;
+using android::properties::PropertyInfoArea;
 using android::properties::PropertyInfoEntry;
 
+class ContextChecker {
+ public:
+  ContextChecker()
+      : policy_file_(nullptr),
+        sepol_handle_(nullptr),
+        sepol_policy_file_(nullptr),
+        sepol_policy_db_(nullptr) {}
+
+  ~ContextChecker() {
+    if (sepol_policy_db_ != nullptr) {
+      sepol_policydb_free(sepol_policy_db_);
+    }
+
+    if (sepol_policy_file_ != nullptr) {
+      sepol_policy_file_free(sepol_policy_file_);
+    }
+
+    if (sepol_handle_ != nullptr) {
+      sepol_handle_destroy(sepol_handle_);
+    }
+
+    if (policy_file_ != nullptr) {
+      fclose(policy_file_);
+    }
+  }
+
+  bool Initialize(const char* policy_file) {
+    policy_file_ = fopen(policy_file, "re");
+    if (policy_file_ == nullptr) {
+      std::cerr << "Could not open policy file, " << policy_file << std::endl;
+      return false;
+    }
+
+    sepol_handle_ = sepol_handle_create();
+    if (sepol_handle_ == nullptr) {
+      std::cerr << "Could not create policy handle." << std::endl;
+      return false;
+    }
+
+    if (sepol_policy_file_create(&sepol_policy_file_) < 0) {
+      std::cerr << "Could not create policy file." << std::endl;
+      return false;
+    }
+
+    if (sepol_policydb_create(&sepol_policy_db_) < 0) {
+      std::cerr << "Could not create policy db." << std::endl;
+      return false;
+    }
+
+    sepol_policy_file_set_fp(sepol_policy_file_, policy_file_);
+    sepol_policy_file_set_handle(sepol_policy_file_, sepol_handle_);
+
+    if (sepol_policydb_read(sepol_policy_db_, sepol_policy_file_) < 0) {
+      std::cerr << "Could not read policy file into policy db." << std::endl;
+      return false;
+    }
+
+    auto* attr =
+        reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, "property_type"));
+    if (attr == nullptr || attr->flavor != TYPE_ATTRIB) {
+      std::cerr << "'property_type' is not defined correctly." << std::endl;
+      return false;
+    }
+
+    property_type_bit_ = attr->s.value - 1;
+
+    return true;
+  }
+
+  bool CheckContext(const char* context) {
+    sepol_context_t* sepol_context_raw;
+    if (sepol_context_from_string(sepol_handle_, context, &sepol_context_raw) < 0) {
+      std::cerr << "Could not allocate context for " << context << std::endl;
+      return false;
+    }
+    auto sepol_context = std::unique_ptr<sepol_context_t, decltype(&sepol_context_free)>{
+        sepol_context_raw, sepol_context_free};
+
+    if (sepol_context_check(sepol_handle_, sepol_policy_db_, sepol_context.get()) < 0) {
+      std::cerr << "Sepol context check failed for " << context << std::endl;
+      return false;
+    }
+
+    const char* context_type = sepol_context_get_type(sepol_context.get());
+
+    auto* type =
+        reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, context_type));
+    if (type == nullptr) {
+      std::cerr << "Could not find context '" << context << "' in policy database" << std::endl;
+      return false;
+    }
+
+    if (type->flavor != TYPE_TYPE) {
+      std::cerr << "Context '" << context << "' is not defined as a type in policy database"
+                << std::endl;
+      return false;
+    }
+
+    if (!ebitmap_get_bit(&policy_db_->type_attr_map[type->s.value - 1], property_type_bit_)) {
+      std::cerr << "Context '" << context << "' does not have property_type attribute" << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+ private:
+  FILE* policy_file_;
+  sepol_handle_t* sepol_handle_;
+  sepol_policy_file_t* sepol_policy_file_;
+  union {
+    sepol_policydb_t* sepol_policy_db_;
+    policydb_t* policy_db_;
+  };
+  unsigned int property_type_bit_;
+};
+
 int main(int argc, char** argv) {
-  if (argc < 2) {
-    std::cerr << "A list of property info files to be checked is expected on the command line"
-              << std::endl;
+  if (argc < 3) {
+    std::cerr << "usage: " << argv[0]
+              << " COMPILED_SEPOLICY PROPERTY_INFO_FILE [PROPERTY_INFO_FILE]..." << std::endl;
     return -1;
   }
 
   auto property_info_entries = std::vector<PropertyInfoEntry>{};
 
-  for (int i = 1; i < argc; ++i) {
+  for (int i = 2; i < argc; ++i) {
     auto filename = argv[i];
     auto file_contents = std::string{};
     if (!ReadFileToString(filename, &file_contents)) {
@@ -47,5 +171,17 @@
     return -1;
   }
 
+  auto checker = ContextChecker{};
+  if (!checker.Initialize(argv[1])) {
+    return -1;
+  }
+
+  auto property_info_area = reinterpret_cast<PropertyInfoArea*>(serialized_contexts.data());
+  for (size_t i = 0; i < property_info_area->num_contexts(); ++i) {
+    if (!checker.CheckContext(property_info_area->context(i))) {
+      return -1;
+    }
+  }
+
   return 0;
 }