Merge "Move adb tests to system/core/adb."
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 463c1c0..239aaf8 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -76,6 +76,8 @@
             ReadOrderlyShutdown(fd);
         }
         adb_close(fd);
+
+        line_printer_.KeepInfoLine();
     }
 
     bool IsValid() { return fd >= 0; }
@@ -243,8 +245,7 @@
     }
 
     void Print(const std::string& s) {
-        // TODO: we actually don't want ELIDE; we want "ELIDE if smart, FULL if dumb".
-        line_printer_.Print(s, LinePrinter::ELIDE);
+        line_printer_.Print(s, LinePrinter::INFO);
     }
 
     void Printf(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) {
@@ -265,7 +266,7 @@
         android::base::StringAppendV(&s, fmt, ap);
         va_end(ap);
 
-        line_printer_.Print(s, LinePrinter::FULL);
+        line_printer_.Print(s, LinePrinter::ERROR);
     }
 
     void Warning(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) {
@@ -276,7 +277,7 @@
         android::base::StringAppendV(&s, fmt, ap);
         va_end(ap);
 
-        line_printer_.Print(s, LinePrinter::FULL);
+        line_printer_.Print(s, LinePrinter::WARNING);
     }
 
     uint64_t total_bytes;
@@ -664,7 +665,7 @@
         }
     }
 
-    sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s\n", rpath.c_str(),
+    sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s", rpath.c_str(),
               pushed, (pushed == 1) ? "" : "s", skipped,
               (skipped == 1) ? "" : "s", sc.TransferRate().c_str());
     return true;
@@ -739,7 +740,6 @@
         success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode);
     }
 
-    sc.Print("\n");
     return success;
 }
 
@@ -858,7 +858,7 @@
         }
     }
 
-    sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s\n", rpath.c_str(),
+    sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s", rpath.c_str(),
               pulled, (pulled == 1) ? "" : "s", skipped,
               (skipped == 1) ? "" : "s", sc.TransferRate().c_str());
     return true;
@@ -967,7 +967,6 @@
         }
     }
 
-    sc.Print("\n");
     return success;
 }
 
diff --git a/adb/line_printer.cpp b/adb/line_printer.cpp
index 4c57c7e..e8fe6c9 100644
--- a/adb/line_printer.cpp
+++ b/adb/line_printer.cpp
@@ -43,7 +43,7 @@
   return result;
 }
 
-LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) {
+LinePrinter::LinePrinter() : have_blank_line_(true) {
 #ifndef _WIN32
   const char* term = getenv("TERM");
   smart_terminal_ = unix_isatty(1) && term && string(term) != "dumb";
@@ -59,20 +59,24 @@
 #endif
 }
 
+static void Out(const std::string& s) {
+  // Avoid printf and C strings, since the actual output might contain null
+  // bytes like UTF-16 does (yuck).
+  fwrite(s.data(), 1, s.size(), stdout);
+}
+
 void LinePrinter::Print(string to_print, LineType type) {
-  if (console_locked_) {
-    line_buffer_ = to_print;
-    line_type_ = type;
+  if (!smart_terminal_) {
+    Out(to_print);
     return;
   }
 
-  if (smart_terminal_) {
-    printf("\r");  // Print over previous line, if any.
-    // On Windows, calling a C library function writing to stdout also handles
-    // pausing the executable when the "Pause" key or Ctrl-S is pressed.
-  }
+  // Print over previous line, if any.
+  // On Windows, calling a C library function writing to stdout also handles
+  // pausing the executable when the "Pause" key or Ctrl-S is pressed.
+  printf("\r");
 
-  if (smart_terminal_ && type == ELIDE) {
+  if (type == INFO) {
 #ifdef _WIN32
     CONSOLE_SCREEN_BUFFER_INFO csbi;
     GetConsoleScreenBufferInfo(console_, &csbi);
@@ -105,57 +109,19 @@
     if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) {
       to_print = ElideMiddle(to_print, size.ws_col);
     }
-    printf("%s", to_print.c_str());
+    Out(to_print);
     printf("\x1B[K");  // Clear to end of line.
     fflush(stdout);
 #endif
 
     have_blank_line_ = false;
   } else {
-    printf("%s\n", to_print.c_str());
+    Out(to_print);
+    Out("\n");
+    have_blank_line_ = true;
   }
 }
 
-void LinePrinter::PrintOrBuffer(const char* data, size_t size) {
-  if (console_locked_) {
-    output_buffer_.append(data, size);
-  } else {
-    // Avoid printf and C strings, since the actual output might contain null
-    // bytes like UTF-16 does (yuck).
-    fwrite(data, 1, size, stdout);
-  }
-}
-
-void LinePrinter::PrintOnNewLine(const string& to_print) {
-  if (console_locked_ && !line_buffer_.empty()) {
-    output_buffer_.append(line_buffer_);
-    output_buffer_.append(1, '\n');
-    line_buffer_.clear();
-  }
-  if (!have_blank_line_) {
-    PrintOrBuffer("\n", 1);
-  }
-  if (!to_print.empty()) {
-    PrintOrBuffer(&to_print[0], to_print.size());
-  }
-  have_blank_line_ = to_print.empty() || *to_print.rbegin() == '\n';
-}
-
-void LinePrinter::SetConsoleLocked(bool locked) {
-  if (locked == console_locked_)
-    return;
-
-  if (locked)
-    PrintOnNewLine("");
-
-  console_locked_ = locked;
-
-  if (!locked) {
-    PrintOnNewLine(output_buffer_);
-    if (!line_buffer_.empty()) {
-      Print(line_buffer_, line_type_);
-    }
-    output_buffer_.clear();
-    line_buffer_.clear();
-  }
+void LinePrinter::KeepInfoLine() {
+  if (!have_blank_line_) Out("\n");
 }
diff --git a/adb/line_printer.h b/adb/line_printer.h
index 3d0a5bd..42345e2 100644
--- a/adb/line_printer.h
+++ b/adb/line_printer.h
@@ -26,20 +26,14 @@
   bool is_smart_terminal() const { return smart_terminal_; }
   void set_smart_terminal(bool smart) { smart_terminal_ = smart; }
 
-  enum LineType {
-    FULL,
-    ELIDE
-  };
-  /// Overprints the current line. If type is ELIDE, elides to_print to fit on
-  /// one line.
+  enum LineType { INFO, WARNING, ERROR };
+
+  /// Outputs the given line. INFO output will be overwritten.
+  /// WARNING and ERROR appear on a line to themselves.
   void Print(std::string to_print, LineType type);
 
-  /// Prints a string on a new line, not overprinting previous output.
-  void PrintOnNewLine(const std::string& to_print);
-
-  /// Lock or unlock the console.  Any output sent to the LinePrinter while the
-  /// console is locked will not be printed until it is unlocked.
-  void SetConsoleLocked(bool locked);
+  /// If there's an INFO line, keep it. If not, do nothing.
+  void KeepInfoLine();
 
  private:
   /// Whether we can do fancy terminal control codes.
@@ -48,24 +42,9 @@
   /// Whether the caret is at the beginning of a blank line.
   bool have_blank_line_;
 
-  /// Whether console is locked.
-  bool console_locked_;
-
-  /// Buffered current line while console is locked.
-  std::string line_buffer_;
-
-  /// Buffered line type while console is locked.
-  LineType line_type_;
-
-  /// Buffered console output while console is locked.
-  std::string output_buffer_;
-
 #ifdef _WIN32
   void* console_;
 #endif
-
-  /// Print the given data to the console, or buffer it if it is locked.
-  void PrintOrBuffer(const char *data, size_t size);
 };
 
 #endif  // NINJA_LINE_PRINTER_H_
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index cc9f06c..1ab9436 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -279,6 +279,10 @@
             "                                           override the fs type and/or size\n"
             "                                           the bootloader reports.\n"
             "  getvar <variable>                        Display a bootloader variable.\n"
+            "  set_active <suffix>                      Sets the active slot. If slots are\n"
+            "                                           not supported, this does nothing.\n"
+            "                                           note: suffixes starting with a '-'\n"
+            "                                           must use set_active -- <suffix>\n"
             "  boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
             "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
             "                                           Create bootimage and flash it.\n"
@@ -321,7 +325,8 @@
             "  -a, --set-active[=<suffix>]              Sets the active slot. If no suffix is\n"
             "                                           provided, this will default to the value\n"
             "                                           given by --slot. If slots are not\n"
-            "                                           supported, this does nothing.\n"
+            "                                           supported, this does nothing. This will\n"
+            "                                           run after all non-reboot commands.\n"
             "  --unbuffered                             Do not buffer input or output.\n"
             "  --version                                Display version.\n"
             "  -h, --help                               show this message.\n"
@@ -724,9 +729,19 @@
     return android::base::Split(suffix_list, ",");
 }
 
-static std::string verify_slot(Transport* transport, const char *slot) {
+static std::string verify_slot(Transport* transport, const char *slot, bool allow_all) {
     if (strcmp(slot, "all") == 0) {
-        return "all";
+        if (allow_all) {
+            return "all";
+        } else {
+            std::vector<std::string> suffixes = get_suffixes(transport);
+            if (!suffixes.empty()) {
+                return suffixes[0];
+            } else {
+                fprintf(stderr, "No known slots.\n");
+                exit(1);
+            }
+        }
     }
     std::vector<std::string> suffixes = get_suffixes(transport);
     for (const std::string &suffix : suffixes) {
@@ -740,6 +755,10 @@
     exit(1);
 }
 
+static std::string verify_slot(Transport* transport, const char *slot) {
+   return verify_slot(transport, slot, true);
+}
+
 static void do_for_partition(Transport* transport, const char *part, const char *slot,
                              std::function<void(const std::string&)> func, bool force_slot) {
     std::string has_slot;
@@ -1220,14 +1239,14 @@
     if (slot_override != "")
         slot_override = verify_slot(transport, slot_override.c_str());
     if (next_active != "")
-        next_active = verify_slot(transport, next_active.c_str());
+        next_active = verify_slot(transport, next_active.c_str(), false);
 
     if (wants_set_active) {
         if (next_active == "") {
             if (slot_override == "") {
                 wants_set_active = false;
             } else {
-                next_active = slot_override;
+                next_active = verify_slot(transport, slot_override.c_str(), false);
             }
         }
     }
@@ -1385,6 +1404,12 @@
                 do_update(transport, "update.zip", slot_override.c_str(), erase_first);
                 skip(1);
             }
+            wants_reboot = 1;
+        } else if(!strcmp(*argv, "set_active")) {
+            require(2);
+            std::string slot = verify_slot(transport, argv[1], false);
+            fb_set_active(slot.c_str());
+            skip(2);
             wants_reboot = true;
         } else if(!strcmp(*argv, "oem")) {
             argc = do_oem_command(argc, argv);
diff --git a/include/nativeloader/native_loader.h b/include/nativeloader/native_loader.h
index 18b7ba4..e7c69d6 100644
--- a/include/nativeloader/native_loader.h
+++ b/include/nativeloader/native_loader.h
@@ -24,7 +24,7 @@
 
 __attribute__((visibility("default")))
 void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
-                        jobject class_loader, jstring library_path);
+                        jobject class_loader, jstring library_path, jstring permitted_path);
 
 };  // namespace android
 
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/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/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 654bcb8..cef2d75 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -55,10 +55,18 @@
  public:
   LibraryNamespaces() : initialized_(false) { }
 
-  android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader, jstring library_path) {
-    ScopedUtfChars libraryPath(env, library_path);
+  android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader,
+                                   jstring java_library_path,
+                                   jstring java_permitted_path) {
+    ScopedUtfChars library_path(env, java_library_path);
 
-    if (!initialized_ && !InitPublicNamespace(libraryPath.c_str())) {
+    std::string permitted_path;
+    if (java_permitted_path != nullptr) {
+      ScopedUtfChars path(env, java_permitted_path);
+      permitted_path = path.c_str();
+    }
+
+    if (!initialized_ && !InitPublicNamespace(library_path.c_str())) {
       return nullptr;
     }
 
@@ -73,8 +81,11 @@
     android_namespace_t* ns =
             android_create_namespace("classloader-namespace",
                                      nullptr,
-                                     libraryPath.c_str(),
-                                     true);
+                                     library_path.c_str(),
+                                     true,
+                                     java_permitted_path != nullptr ?
+                                        permitted_path.c_str() :
+                                        nullptr);
 
     namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
 
@@ -118,13 +129,16 @@
 
 
 void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
-                        jobject class_loader, jstring library_path) {
+                        jobject class_loader, jstring java_library_path,
+                        jstring java_permitted_path) {
 #if defined(__ANDROID__)
   if (target_sdk_version == 0 || class_loader == nullptr) {
     return dlopen(path, RTLD_NOW);
   }
 
-  android_namespace_t* ns = g_namespaces->GetOrCreate(env, class_loader, library_path);
+  android_namespace_t* ns =
+      g_namespaces->GetOrCreate(env, class_loader, java_library_path,
+                                java_permitted_path);
 
   if (ns == nullptr) {
     return nullptr;
@@ -136,7 +150,8 @@
 
   return android_dlopen_ext(path, RTLD_NOW, &extinfo);
 #else
-  UNUSED(env, target_sdk_version, class_loader, library_path);
+  UNUSED(env, target_sdk_version, class_loader,
+         java_library_path, java_permitted_path);
   return dlopen(path, RTLD_NOW);
 #endif
 }
diff --git a/metricsd/Android.mk b/metricsd/Android.mk
index 839ab65..3553753 100644
--- a/metricsd/Android.mk
+++ b/metricsd/Android.mk
@@ -146,9 +146,7 @@
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS)
 LOCAL_INIT_RC := metrics_collector.rc
-LOCAL_REQUIRED_MODULES := \
-  metrics.json \
-  metrics.schema.json
+LOCAL_REQUIRED_MODULES := metrics.json
 LOCAL_RTTI_FLAG := -frtti
 LOCAL_SHARED_LIBRARIES := $(metrics_collector_shared_libraries)
 LOCAL_SRC_FILES := $(metrics_collector_common) \
@@ -207,13 +205,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := metrics.json
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/weaved/commands
-LOCAL_SRC_FILES := etc/weaved/commands/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := metrics.schema.json
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/weaved/states
-LOCAL_SRC_FILES := etc/weaved/states/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/weaved/traits
+LOCAL_SRC_FILES := etc/weaved/traits/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
diff --git a/metricsd/etc/weaved/commands/metrics.json b/metricsd/etc/weaved/commands/metrics.json
deleted file mode 100644
index b7f32d5..0000000
--- a/metricsd/etc/weaved/commands/metrics.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "_metrics": {
-    "_enableAnalyticsReporting": {
-      "minimalRole": "manager"
-    },
-    "_disableAnalyticsReporting": {
-      "minimalRole": "manager"
-    }
-  }
-}
diff --git a/metricsd/etc/weaved/states/metrics.schema.json b/metricsd/etc/weaved/states/metrics.schema.json
deleted file mode 100644
index 130ac46..0000000
--- a/metricsd/etc/weaved/states/metrics.schema.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "_metrics": {
-    "_AnalyticsReportingState": {
-      "enum": ["enabled", "disabled"],
-      "default": "disabled"
-    }
-  }
-}
diff --git a/metricsd/etc/weaved/traits/metrics.json b/metricsd/etc/weaved/traits/metrics.json
new file mode 100644
index 0000000..7d17c77
--- /dev/null
+++ b/metricsd/etc/weaved/traits/metrics.json
@@ -0,0 +1,18 @@
+{
+  "_metrics": {
+    "commands": {
+      "_enableAnalyticsReporting": {
+        "minimalRole": "manager"
+      },
+      "_disableAnalyticsReporting": {
+        "minimalRole": "manager"
+      }
+    },
+    "state": {
+      "_AnalyticsReportingState": {
+        "type": "string",
+        "enum": [ "enabled", "disabled" ]
+      }
+    }
+  }
+}
diff --git a/metricsd/metrics_collector.cc b/metricsd/metrics_collector.cc
index 28f9ad3..5468b9f 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;
@@ -73,6 +71,8 @@
 const char kMeminfoFileName[] = "/proc/meminfo";
 const char kVmStatFileName[] = "/proc/vmstat";
 
+const char kWeaveComponent[] = "metrics";
+
 }  // namespace
 
 // Zram sysfs entries.
@@ -248,10 +248,13 @@
   device_ = weaved::Device::CreateInstance(
       bus_,
       base::Bind(&MetricsCollector::UpdateWeaveState, base::Unretained(this)));
+  device_->AddComponent(kWeaveComponent, {"_metrics"});
   device_->AddCommandHandler(
+      kWeaveComponent,
       "_metrics._enableAnalyticsReporting",
       base::Bind(&MetricsCollector::OnEnableMetrics, base::Unretained(this)));
   device_->AddCommandHandler(
+      kWeaveComponent,
       "_metrics._disableAnalyticsReporting",
       base::Bind(&MetricsCollector::OnDisableMetrics, base::Unretained(this)));
 
@@ -326,12 +329,13 @@
   if (!device_)
     return;
 
-  brillo::VariantDictionary state_change{
-    { "_metrics._AnalyticsReportingState",
-      metrics_lib_->AreMetricsEnabled() ? "enabled" : "disabled" }
-  };
+  std::string enabled =
+      metrics_lib_->AreMetricsEnabled() ? "enabled" : "disabled";
 
-  if (!device_->SetStateProperties(state_change, nullptr)) {
+  if (!device_->SetStateProperty(kWeaveComponent,
+                                 "_metrics._AnalyticsReportingState",
+                                 enabled,
+                                 nullptr)) {
     LOG(ERROR) << "failed to update weave's state";
   }
 }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index b40b9ba..011defb 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -493,6 +493,8 @@
     class_start core
 
 on nonencrypted
+    # A/B update verifier that marks a successful boot.
+    exec - root -- /system/bin/update_verifier nonencrypted
     class_start main
     class_start late_start
 
@@ -521,9 +523,13 @@
     trigger post-fs-data
 
 on property:vold.decrypt=trigger_restart_min_framework
+    # A/B update verifier that marks a successful boot.
+    exec - root -- /system/bin/update_verifier trigger_restart_min_framework
     class_start main
 
 on property:vold.decrypt=trigger_restart_framework
+    # A/B update verifier that marks a successful boot.
+    exec - root -- /system/bin/update_verifier trigger_restart_framework
     class_start main
     class_start late_start