Merge "fix: ATRACE does not work for libs loaded in sphal namespace" into oc-dev
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e224aec..803b894 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -949,16 +949,20 @@
             }
             encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
         } else {
+            // fs_options might be null so we cannot use PERROR << directly.
+            // Use StringPrintf to output "(null)" instead.
             if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
-                PERROR << "Ignoring failure to mount an un-encryptable or wiped partition on"
-                       << fstab->recs[attempted_idx].blk_device << " at "
-                       << fstab->recs[attempted_idx].mount_point << " options: "
-                       << fstab->recs[attempted_idx].fs_options;
+                PERROR << android::base::StringPrintf(
+                    "Ignoring failure to mount an un-encryptable or wiped "
+                    "partition on %s at %s options: %s",
+                    fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+                    fstab->recs[attempted_idx].fs_options);
             } else {
-                PERROR << "Failed to mount an un-encryptable or wiped partition on"
-                       << fstab->recs[attempted_idx].blk_device << " at "
-                       << fstab->recs[attempted_idx].mount_point << " options: "
-                       << fstab->recs[attempted_idx].fs_options;
+                PERROR << android::base::StringPrintf(
+                    "Failed to mount an un-encryptable or wiped partition "
+                    "on %s at %s options: %s",
+                    fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+                    fstab->recs[attempted_idx].fs_options);
                 ++error_count;
             }
             continue;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 0a694c1..7d09d01 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -397,6 +397,15 @@
         std::vector<std::string> fstab_entry;
         std::string file_name;
         std::string value;
+        // skip a partition entry if the status property is present and not set to ok
+        file_name = android::base::StringPrintf("%s/%s/status", fstabdir_name.c_str(), dp->d_name);
+        if (read_dt_file(file_name, &value)) {
+            if (value != "okay" && value != "ok") {
+                LINFO << "dt_fstab: Skip disabled entry for partition " << dp->d_name;
+                continue;
+            }
+        }
+
         file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
         if (!read_dt_file(file_name, &value)) {
             LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
diff --git a/include/nativebridge/native_bridge.h b/include/nativebridge/native_bridge.h
index 929b8ae..9bfc935 100644
--- a/include/nativebridge/native_bridge.h
+++ b/include/nativebridge/native_bridge.h
@@ -161,6 +161,9 @@
 // Use NativeBridgeLoadLibrary() instead in non-namespace scenario.
 void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns);
 
+// Returns vendor namespace if it is enabled for the device and null otherwise
+native_bridge_namespace_t* NativeBridgeGetVendorNamespace();
+
 // Native bridge interfaces to runtime.
 struct NativeBridgeCallbacks {
   // Version number of the interface.
@@ -348,6 +351,15 @@
   // Starting with v3, NativeBridge has two scenarios: with/without namespace.
   // Use loadLibrary instead in non-namespace scenario.
   void* (*loadLibraryExt)(const char* libpath, int flag, native_bridge_namespace_t* ns);
+
+  // Get native bridge version of vendor namespace.
+  // The vendor namespace is the namespace used to load vendor public libraries.
+  // With O release this namespace can be different from the default namespace.
+  // For the devices without enable vendor namespaces this function should return null
+  //
+  // Returns:
+  //   vendor namespace or null if it was not set up for the device
+  native_bridge_namespace_t* (*getVendorNamespace)();
 };
 
 // Runtime interfaces to native bridge.
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index ec32da0..71f74ab 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -36,6 +36,7 @@
 #endif
 #include <gtest/gtest.h>
 #include <log/log_event_list.h>
+#include <log/log_properties.h>
 #include <log/log_transport.h>
 #include <log/logprint.h>
 #include <private/android_filesystem_config.h>
@@ -1786,6 +1787,12 @@
         stderr,
         "WARNING: test conditions request being run as root and not AID=%d\n",
         getuid());
+    if (!__android_log_is_debuggable()) {
+      fprintf(
+          stderr,
+          "WARNING: can not run test on a \"user\" build, bypassing test\n");
+      return;
+    }
   }
 
   system((getuid() == AID_ROOT) ? "stop logd" : "su 0 stop logd");
diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp
index a63ab8e..6ed568a 100644
--- a/liblog/tests/log_read_test.cpp
+++ b/liblog/tests/log_read_test.cpp
@@ -23,6 +23,7 @@
 #include <android-base/stringprintf.h>
 #include <android/log.h>  // minimal logging API
 #include <gtest/gtest.h>
+#include <log/log_properties.h>
 // Test the APIs in this standalone include file
 #include <log/log_read.h>
 // Do not use anything in log/log_time.h despite side effects of the above.
@@ -97,9 +98,12 @@
     /* security buffer is allowed to be denied */
     if (strcmp("security", name)) {
       EXPECT_LT(0, get_log_size);
-      /* crash buffer is allowed to be empty, that is actually healthy! */
-      EXPECT_LE((strcmp("crash", name)) != 0,
-                android_logger_get_log_readable_size(logger));
+      // crash buffer is allowed to be empty, that is actually healthy!
+      // kernel buffer is allowed to be empty on "user" builds
+      EXPECT_LE(  // boolean 1 or 0 depending on expected content or empty
+          !!((strcmp("crash", name) != 0) &&
+             ((strcmp("kernel", name) != 0) || __android_log_is_debuggable())),
+          android_logger_get_log_readable_size(logger));
     } else {
       EXPECT_NE(0, get_log_size);
       if (get_log_size < 0) {
diff --git a/libnativebridge/.clang-format b/libnativebridge/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/libnativebridge/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index 7976f67..cc30aaf 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -85,12 +85,14 @@
 // Nativebridge implementation.
 // Used by isCompatibleWith() which is introduced in v2.
 enum NativeBridgeImplementationVersion {
-    // first version, not used.
-    DEFAULT_VERSION = 1,
-    // The version which signal semantic is introduced.
-    SIGNAL_VERSION = 2,
-    // The version which namespace semantic is introduced.
-    NAMESPACE_VERSION = 3,
+  // first version, not used.
+  DEFAULT_VERSION = 1,
+  // The version which signal semantic is introduced.
+  SIGNAL_VERSION = 2,
+  // The version which namespace semantic is introduced.
+  NAMESPACE_VERSION = 3,
+  // The version with vendor namespaces
+  VENDOR_NAMESPACE_VERSION = 4,
 };
 
 // Whether we had an error at some point.
@@ -621,6 +623,14 @@
     return false;
 }
 
+native_bridge_namespace_t* NativeBridgeGetVendorNamespace() {
+  if (!NativeBridgeInitialized() || !isCompatibleWith(VENDOR_NAMESPACE_VERSION)) {
+    return nullptr;
+  }
+
+  return callbacks->getVendorNamespace();
+}
+
 void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) {
   if (NativeBridgeInitialized()) {
     if (isCompatibleWith(NAMESPACE_VERSION)) {
diff --git a/libnativeloader/.clang-format b/libnativeloader/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/libnativeloader/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/libnativeloader/include/nativeloader/dlext_namespaces.h b/libnativeloader/include/nativeloader/dlext_namespaces.h
index 9121277..43c9329 100644
--- a/libnativeloader/include/nativeloader/dlext_namespaces.h
+++ b/libnativeloader/include/nativeloader/dlext_namespaces.h
@@ -124,6 +124,8 @@
  */
 extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);
 
+extern android_namespace_t* android_get_exported_namespace(const char* name);
+
 __END_DECLS
 
 #endif /* __ANDROID_DLEXT_NAMESPACES_H__ */
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 100c31d..36a2e44 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -83,6 +83,12 @@
 static constexpr const char* kPublicNativeLibrariesVendorConfig =
                                   "/vendor/etc/public.libraries.txt";
 
+// The device may be configured to have the vendor libraries loaded to a separate namespace.
+// For historical reasons this namespace was named sphal but effectively it is intended
+// to use to load vendor libraries to separate namespace with controlled interface between
+// vendor and system namespaces.
+static constexpr const char* kVendorNamespaceName = "sphal";
+
 // (http://b/27588281) This is a workaround for apps using custom classloaders and calling
 // System.load() with an absolute path which is outside of the classloader library search path.
 // This list includes all directories app is allowed to access this way.
@@ -170,11 +176,23 @@
         return false;
       }
 
-      if (!android_link_namespaces(ns, nullptr, public_libraries_.c_str())) {
+      // Note that when vendor_ns is not configured this function will return nullptr
+      // and it will result in linking vendor_public_libraries_ to the default namespace
+      // which is expected behavior in this case.
+      android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
+
+      if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
         *error_msg = dlerror();
         return false;
       }
 
+      if (!vendor_public_libraries_.empty()) {
+        if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
+          *error_msg = dlerror();
+          return false;
+        }
+      }
+
       native_loader_ns = NativeLoaderNamespace(ns);
     } else {
       native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
@@ -183,14 +201,24 @@
                                                                   namespace_type,
                                                                   permitted_path.c_str(),
                                                                   parent_ns.get_native_bridge_ns());
+
       if (ns == nullptr) {
         *error_msg = NativeBridgeGetError();
         return false;
       }
 
-      if (!NativeBridgeLinkNamespaces(ns, nullptr, public_libraries_.c_str())) {
+      native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
+
+      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
+        *error_msg = NativeBridgeGetError();
+        return false;
+      }
+
+      if (!vendor_public_libraries_.empty()) {
+        if (!NativeBridgeLinkNamespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
           *error_msg = NativeBridgeGetError();
           return false;
+        }
       }
 
       native_loader_ns = NativeLoaderNamespace(ns);
@@ -249,9 +277,6 @@
       }
     }
 
-    // This file is optional, quietly ignore if the file does not exist.
-    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
-
     // android_init_namespaces() expects all the public libraries
     // to be loaded so that they can be found by soname alone.
     //
@@ -266,7 +291,13 @@
                           soname.c_str(), dlerror());
     }
 
-    public_libraries_ = base::Join(sonames, ':');
+    system_public_libraries_ = base::Join(sonames, ':');
+
+    sonames.clear();
+    // This file is optional, quietly ignore if the file does not exist.
+    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
+
+    vendor_public_libraries_ = base::Join(sonames, ':');
   }
 
   void Reset() {
@@ -325,7 +356,7 @@
     // code is one example) unknown to linker in which  case linker uses anonymous
     // namespace. The second argument specifies the search path for the anonymous
     // namespace which is the library_path of the classloader.
-    initialized_ = android_init_anonymous_namespace(public_libraries_.c_str(),
+    initialized_ = android_init_anonymous_namespace(system_public_libraries_.c_str(),
                                                     is_native_bridge ? nullptr : library_path);
     if (!initialized_) {
       *error_msg = dlerror();
@@ -334,10 +365,10 @@
 
     // and now initialize native bridge namespaces if necessary.
     if (NativeBridgeInitialized()) {
-        initialized_ = NativeBridgeInitAnonymousNamespace(
-            public_libraries_.c_str(), is_native_bridge ? library_path : nullptr);
-        if (!initialized_) {
-            *error_msg = NativeBridgeGetError();
+      initialized_ = NativeBridgeInitAnonymousNamespace(system_public_libraries_.c_str(),
+                                                        is_native_bridge ? library_path : nullptr);
+      if (!initialized_) {
+        *error_msg = NativeBridgeGetError();
       }
     }
 
@@ -371,8 +402,8 @@
 
   bool initialized_;
   std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
-  std::string public_libraries_;
-
+  std::string system_public_libraries_;
+  std::string vendor_public_libraries_;
 
   DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
 };