Merge "Fix typo cpu6 -> cpu7"
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index dcb4bf7..fb00508 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -138,6 +138,12 @@
     chmod 0666 /sys/kernel/tracing/events/block/block_rq_complete/enable
     chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_complete/enable
 
+    # filemap events for iorapd
+    chmod 0666 /sys/kernel/tracing/events/filemap/mm_filemap_add_to_page_cache/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/filemap/mm_filemap_add_to_page_cache/enable
+    chmod 0666 /sys/kernel/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
+
 # Tracing disabled by default
     write /sys/kernel/debug/tracing/tracing_on 0
     write /sys/kernel/tracing/tracing_on 0
diff --git a/cmds/atrace/atrace_userdebug.rc b/cmds/atrace/atrace_userdebug.rc
index f4e5b98..acc62c0 100644
--- a/cmds/atrace/atrace_userdebug.rc
+++ b/cmds/atrace/atrace_userdebug.rc
@@ -5,6 +5,12 @@
 # Access control to these files is now entirely in selinux policy.
 
 on post-fs
+    # On userdebug allow to enable any event via the generic
+    # set_event interface:
+    # echo sched/foo > set_event == echo 1 > events/sched/foo/enable.
+    chmod 0666 /sys/kernel/tracing/set_event
+    chmod 0666 /sys/kernel/debug/tracing/set_event
+
     chmod 0666 /sys/kernel/tracing/events/workqueue/enable
     chmod 0666 /sys/kernel/debug/tracing/events/workqueue/enable
     chmod 0666 /sys/kernel/tracing/events/regulator/enable
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 712f861..2824c82 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -475,47 +475,6 @@
     return false;
 }
 
-static void dump_systrace() {
-    if (!ds.IsZipping()) {
-        MYLOGD("Not dumping systrace because it's not a zipped bugreport\n");
-        return;
-    }
-    std::string systrace_path = ds.GetPath("-systrace.txt");
-    if (systrace_path.empty()) {
-        MYLOGE("Not dumping systrace because path is empty\n");
-        return;
-    }
-    const char* path = "/sys/kernel/debug/tracing/tracing_on";
-    long int is_tracing;
-    if (read_file_as_long(path, &is_tracing)) {
-        return; // error already logged
-    }
-    if (is_tracing <= 0) {
-        MYLOGD("Skipping systrace because '%s' content is '%ld'\n", path, is_tracing);
-        return;
-    }
-
-    MYLOGD("Running '/system/bin/atrace --async_dump -o %s', which can take several minutes",
-            systrace_path.c_str());
-    if (RunCommand("SYSTRACE", {"/system/bin/atrace", "--async_dump", "-o", systrace_path},
-                   CommandOptions::WithTimeout(120).Build())) {
-        MYLOGE("systrace timed out, its zip entry will be incomplete\n");
-        // TODO: RunCommand tries to kill the process, but atrace doesn't die
-        // peacefully; ideally, we should call strace to stop itself, but there is no such option
-        // yet (just a --async_stop, which stops and dump
-        // if (RunCommand("SYSTRACE", {"/system/bin/atrace", "--kill"})) {
-        //   MYLOGE("could not stop systrace ");
-        // }
-    }
-    if (!ds.AddZipEntry("systrace.txt", systrace_path)) {
-        MYLOGE("Unable to add systrace file %s to zip file\n", systrace_path.c_str());
-    } else {
-        if (remove(systrace_path.c_str())) {
-            MYLOGE("Error removing systrace file %s: %s", systrace_path.c_str(), strerror(errno));
-        }
-    }
-}
-
 static bool skip_not_stat(const char *path) {
     static const char stat[] = "/stat";
     size_t len = strlen(path);
@@ -1440,12 +1399,8 @@
 
 /* Dumps state for the default case. Returns true if everything went fine. */
 static bool DumpstateDefault() {
-    // Dumps systrace right away, otherwise it will be filled with unnecessary events.
-    // First try to dump anrd trace if the daemon is running. Otherwise, dump
-    // the raw trace.
-    if (!dump_anrd_trace()) {
-        dump_systrace();
-    }
+    // Try to dump anrd trace if the daemon is running.
+    dump_anrd_trace();
 
     // Invoking the following dumpsys calls before dump_traces() to try and
     // keep the system stats as close to its initial state as possible.
@@ -2256,6 +2211,28 @@
     options_ = std::move(options);
 }
 
+Dumpstate::RunStatus Dumpstate::Run() {
+    Dumpstate::RunStatus status = RunInternal();
+    if (listener_ != nullptr) {
+        switch (status) {
+            case Dumpstate::RunStatus::OK:
+                // TODO(b/111441001): duration argument does not make sense. Remove.
+                listener_->onFinished(0 /* duration */, options_->notification_title,
+                                      options_->notification_description);
+                break;
+            case Dumpstate::RunStatus::HELP:
+                break;
+            case Dumpstate::RunStatus::INVALID_INPUT:
+                listener_->onError(android::os::IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT);
+                break;
+            case Dumpstate::RunStatus::ERROR:
+                listener_->onError(android::os::IDumpstateListener::BUGREPORT_ERROR_RUNTIME_ERROR);
+                break;
+        }
+    }
+    return status;
+}
+
 /*
  * Dumps relevant information to a bugreport based on the given options.
  *
@@ -2277,7 +2254,7 @@
  * Bugreports are first generated in a local directory and later copied to the caller's fd or
  * directory.
  */
-Dumpstate::RunStatus Dumpstate::Run() {
+Dumpstate::RunStatus Dumpstate::RunInternal() {
     LogDumpOptions(*options_);
     if (!options_->ValidateOptions()) {
         MYLOGE("Invalid options specified\n");
@@ -2482,6 +2459,7 @@
     /* tell activity manager we're done */
     if (options_->do_broadcast) {
         SendBugreportFinishedBroadcast();
+        // Note that listener_ is notified in Run();
     }
 
     MYLOGD("Final progress: %d/%d (estimated %d)\n", progress_->Get(), progress_->GetMax(),
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 529111e..c620c07 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -449,6 +449,8 @@
     std::vector<DumpData> anr_data_;
 
   private:
+    RunStatus RunInternal();
+
     // Used by GetInstance() only.
     explicit Dumpstate(const std::string& version = VERSION_CURRENT);
 
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 98ee1b0..cd9b97f 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -656,8 +656,9 @@
         }
 
         if (update_progress) {
-            message += android::base::StringPrintf("Setting progress (%s): %d/%d\n",
-                                                   listener_name.c_str(), progress, max);
+            message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
+                                                   listener_name.c_str(), progress, max,
+                                                   (100 * progress / max));
         }
 
         return message;
@@ -816,12 +817,14 @@
     SetProgress(0, 30);
 
     EXPECT_CALL(*listener, onProgressUpdated(20));
+    EXPECT_CALL(*listener, onProgress(66));  // 20/30 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
     std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
     EXPECT_THAT(out, StrEq("stdout\n"));
     EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
 
     EXPECT_CALL(*listener, onProgressUpdated(30));
+    EXPECT_CALL(*listener, onProgress(100));  // 35/35 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(10).Build()));
     progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
     EXPECT_THAT(out, StrEq("stdout\n"));
@@ -830,6 +833,7 @@
     // Run a command that will increase maximum timeout.
     EXPECT_CALL(*listener, onProgressUpdated(31));
     EXPECT_CALL(*listener, onMaxProgressUpdated(37));
+    EXPECT_CALL(*listener, onProgress(83));  // 31/37 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
     progress_message = GetProgressMessage(ds.listener_name_, 31, 37, 30);  // 20% increase
     EXPECT_THAT(out, StrEq("stdout\n"));
@@ -838,6 +842,7 @@
     // Make sure command ran while in dry_run is counted.
     SetDryRun(true);
     EXPECT_CALL(*listener, onProgressUpdated(35));
+    EXPECT_CALL(*listener, onProgress(94));  // 35/37 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
     progress_message = GetProgressMessage(ds.listener_name_, 35, 37);
     EXPECT_THAT(out, IsEmpty());
@@ -854,6 +859,7 @@
 
     // First update should always be sent.
     EXPECT_CALL(*listener, onProgressUpdated(1));
+    EXPECT_CALL(*listener, onProgress(12));  // 1/12 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
     std::string progress_message = GetProgressMessage(ds.listener_name_, 1, 8);
     EXPECT_THAT(out, StrEq("stdout\n"));
@@ -866,6 +872,7 @@
 
     // Third update should be sent because it reaches threshold (6 - 1 = 5).
     EXPECT_CALL(*listener, onProgressUpdated(6));
+    EXPECT_CALL(*listener, onProgress(75));  // 6/8 %
     EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
     progress_message = GetProgressMessage(ds.listener_name_, 6, 8);
     EXPECT_THAT(out, StrEq("stdout\n"));
@@ -1105,6 +1112,7 @@
     SetProgress(0, 30);
 
     EXPECT_CALL(*listener, onProgressUpdated(5));
+    EXPECT_CALL(*listener, onProgress(16));  // 5/30 %
     EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
 
     std::string progress_message =
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 990fd43..528e43d 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -949,16 +949,22 @@
         fsync(control_socket_fd_);
     }
 
+    int percent = 100 * progress / max;
     if (listener_ != nullptr) {
-        if (progress % 100 == 0) {
-            // We don't want to spam logcat, so only log multiples of 100.
-            MYLOGD("Setting progress (%s): %d/%d\n", listener_name_.c_str(), progress, max);
+        if (percent % 5 == 0) {
+            // We don't want to spam logcat, so only log multiples of 5.
+            MYLOGD("Setting progress (%s): %d/%d (%d%%)\n", listener_name_.c_str(), progress, max,
+                   percent);
         } else {
             // stderr is ignored on normal invocations, but useful when calling
             // /system/bin/dumpstate directly for debuggging.
-            fprintf(stderr, "Setting progress (%s): %d/%d\n", listener_name_.c_str(), progress, max);
+            fprintf(stderr, "Setting progress (%s): %d/%d (%d%%)\n", listener_name_.c_str(),
+                    progress, max, percent);
         }
+        // TODO(b/111441001): Remove in favor of onProgress
         listener_->onProgressUpdated(progress);
+
+        listener_->onProgress(percent);
     }
 }
 
diff --git a/cmds/surfacereplayer/OWNERS b/cmds/surfacereplayer/OWNERS
new file mode 100644
index 0000000..cc4c842
--- /dev/null
+++ b/cmds/surfacereplayer/OWNERS
@@ -0,0 +1,2 @@
+mathias@google.com
+racarr@google.com
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 05d96ff..d31d1f1 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -112,15 +112,25 @@
 
 #if __ANDROID_API__ >= 29
 
+/**
+ * Possible values of the flags argument to android_res_nsend and android_res_nquery.
+ * Values are ORed together.
+ */
 enum ResNsendFlags : uint32_t {
-    // Send a single request to a single resolver and fail on timeout or network errors
+    /**
+     * Send a single request to a single resolver and fail on timeout or network errors
+     */
     ANDROID_RESOLV_NO_RETRY = 1 << 0,
 
-    // Do not cache the result of the lookup. The lookup may return a result that is already
-    // in the cache, unless the ANDROID_RESOLV_NO_CACHE_LOOKUP flag is also specified.
+    /**
+     * Do not cache the result of the lookup. The lookup may return a result that is already
+     * in the cache, unless the ANDROID_RESOLV_NO_CACHE_LOOKUP flag is also specified.
+     */
     ANDROID_RESOLV_NO_CACHE_STORE = 1 << 1,
 
-    // Don't lookup the request in cache, do not write back the response into the cache
+    /**
+     * Don't lookup the request in cache.
+     */
     ANDROID_RESOLV_NO_CACHE_LOOKUP = 1 << 2,
 };
 
@@ -136,8 +146,7 @@
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nquery(net_handle_t network,
-        const char *dname, int ns_class, int ns_type,
-        enum ResNsendFlags flags) __INTRODUCED_IN(29);
+        const char *dname, int ns_class, int ns_type, uint32_t flags) __INTRODUCED_IN(29);
 
 /**
  * Issue the query |msg| on the given |network|.
@@ -148,10 +157,11 @@
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nsend(net_handle_t network,
-        const uint8_t *msg, size_t msglen, enum ResNsendFlags flags) __INTRODUCED_IN(29);
+        const uint8_t *msg, size_t msglen, uint32_t flags) __INTRODUCED_IN(29);
 
 /**
  * Read a result for the query associated with the |fd| descriptor.
+ * Closes |fd| before returning.
  *
  * Returns:
  *     < 0: negative POSIX error code (see errno.h for possible values). |rcode| is not set.
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 17e8f6b..784e2c8 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -23,7 +23,7 @@
 
 namespace android {
 
-class NativeLoaderNamespace;
+struct NativeLoaderNamespace;
 
 class GraphicsEnv {
 public:
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index a7c7e79..73150dc 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -1,8 +1,7 @@
-brianderson@google.com
 jessehall@google.com
 jwcai@google.com
+lpy@google.com
+marissaw@google.com
 mathias@google.com
-olv@google.com
-pceballos@google.com
 racarr@google.com
 stoza@google.com
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 537c957..b377a41 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -40,13 +40,14 @@
 #define BQ_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
 #define BQ_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
 
-#define ATRACE_BUFFER_INDEX(index)                                   \
-    if (ATRACE_ENABLED()) {                                          \
-        char ___traceBuf[1024];                                      \
-        snprintf(___traceBuf, 1024, "%s: %d",                        \
-                mCore->mConsumerName.string(), (index));             \
-        android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);  \
-    }
+#define ATRACE_BUFFER_INDEX(index)                                                         \
+    do {                                                                                   \
+        if (ATRACE_ENABLED()) {                                                            \
+            char ___traceBuf[1024];                                                        \
+            snprintf(___traceBuf, 1024, "%s: %d", mCore->mConsumerName.string(), (index)); \
+            android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);                    \
+        }                                                                                  \
+    } while (false)
 
 namespace android {
 
diff --git a/libs/math/OWNERS b/libs/math/OWNERS
new file mode 100644
index 0000000..6fb149a
--- /dev/null
+++ b/libs/math/OWNERS
@@ -0,0 +1,6 @@
+jaesoo@google.com
+jiyong@google.com
+mathias@google.com
+pawin@google.com
+randolphs@google.com
+romainguy@google.com
diff --git a/libs/sensor/include/sensor/Sensor.h b/libs/sensor/include/sensor/Sensor.h
index 6926f7f..324d443 100644
--- a/libs/sensor/include/sensor/Sensor.h
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -57,15 +57,15 @@
             uint8_t b[16];
             int64_t i64[2];
         };
-        uuid_t(const uint8_t (&uuid)[16]) { memcpy(b, uuid, sizeof(b));}
+        explicit uuid_t(const uint8_t (&uuid)[16]) { memcpy(b, uuid, sizeof(b));}
         uuid_t() : b{0} {}
     };
 
     Sensor(const Sensor&) = default;
     Sensor& operator=(const Sensor&) = default;
 
-    Sensor(const char * name = "");
-    Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
+    explicit Sensor(const char * name = "");
+    explicit Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
     Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion = 0);
     ~Sensor();
 
diff --git a/libs/sensor/include/sensor/SensorEventQueue.h b/libs/sensor/include/sensor/SensorEventQueue.h
index baed2ee..8176578 100644
--- a/libs/sensor/include/sensor/SensorEventQueue.h
+++ b/libs/sensor/include/sensor/SensorEventQueue.h
@@ -64,7 +64,7 @@
     // Default sensor sample period
     static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
 
-    SensorEventQueue(const sp<ISensorEventConnection>& connection);
+    explicit SensorEventQueue(const sp<ISensorEventConnection>& connection);
     virtual ~SensorEventQueue();
     virtual void onFirstRef();
 
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index 23f7a91..f09c9c6 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -71,7 +71,7 @@
     void sensorManagerDied();
     static status_t waitForSensorService(sp<ISensorServer> *server);
 
-    SensorManager(const String16& opPackageName);
+    explicit SensorManager(const String16& opPackageName);
     status_t assertStateLocked();
 
 private:
diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS
new file mode 100644
index 0000000..3938e4f
--- /dev/null
+++ b/libs/ui/OWNERS
@@ -0,0 +1,5 @@
+jiyong@google.com
+mathias@google.com
+olv@google.com
+romainguy@google.com
+stoza@google.com
diff --git a/services/displayservice/OWNERS b/services/displayservice/OWNERS
new file mode 100644
index 0000000..7a3e4c2
--- /dev/null
+++ b/services/displayservice/OWNERS
@@ -0,0 +1,2 @@
+smoreland@google.com
+lpy@google.com
diff --git a/services/sensorservice/SensorRecord.h b/services/sensorservice/SensorRecord.h
index 5a35410..031744a 100644
--- a/services/sensorservice/SensorRecord.h
+++ b/services/sensorservice/SensorRecord.h
@@ -25,7 +25,7 @@
 
 class SensorService::SensorRecord {
 public:
-    SensorRecord(const sp<const SensorEventConnection>& connection);
+    explicit SensorRecord(const sp<const SensorEventConnection>& connection);
     bool addConnection(const sp<const SensorEventConnection>& connection);
     bool removeConnection(const wp<const SensorEventConnection>& connection);
     size_t getNumConnections() const { return mConnections.size(); }
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
index ddcee28..8d7a05b 100644
--- a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -43,7 +43,7 @@
 
 struct SensorManager final : public ISensorManager {
 
-    SensorManager(JavaVM* vm);
+    explicit SensorManager(JavaVM* vm);
     ~SensorManager();
 
     // Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
diff --git a/services/sensorservice/mat.h b/services/sensorservice/mat.h
index 495c14e..934ae58 100644
--- a/services/sensorservice/mat.h
+++ b/services/sensorservice/mat.h
@@ -139,13 +139,13 @@
 
     mat() { }
     mat(const mat& rhs)  : base(rhs) { }
-    mat(const base& rhs) : base(rhs) { }  // NOLINT(implicit)
+    mat(const base& rhs) : base(rhs) { }  // NOLINT(google-explicit-constructor)
 
     // -----------------------------------------------------------------------
     // conversion constructors
 
     // sets the diagonal to the value, off-diagonal to zero
-    mat(pTYPE rhs) {  // NOLINT(implicit)
+    mat(pTYPE rhs) {  // NOLINT(google-explicit-constructor)
         helpers::doAssign(*this, rhs);
     }
 
diff --git a/services/sensorservice/vec.h b/services/sensorservice/vec.h
index 9e5d280..c195434 100644
--- a/services/sensorservice/vec.h
+++ b/services/sensorservice/vec.h
@@ -322,12 +322,12 @@
 
     vec() { }
     vec(const vec& rhs)  : base(rhs) { }
-    vec(const base& rhs) : base(rhs) { }  // NOLINT(implicit)
+    vec(const base& rhs) : base(rhs) { }  // NOLINT(google-explicit-constructor)
 
     // -----------------------------------------------------------------------
     // conversion constructors
 
-    vec(pTYPE rhs) {  // NOLINT(implicit)
+    vec(pTYPE rhs) {  // NOLINT(google-explicit-constructor)
         for (size_t i=0 ; i<SIZE ; i++)
             base::operator[](i) = rhs;
     }
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index 009b257..ba4cf00 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -139,12 +139,12 @@
         auto app_namespace = android::GraphicsEnv::getInstance().getAppNamespace();
         if (app_namespace &&
             !android::base::StartsWith(path_, kSystemLayerLibraryDir)) {
-            std::string error_msg;
-            dlhandle_ = OpenNativeLibrary(
+            char* error_msg = nullptr;
+            dlhandle_ = OpenNativeLibraryInNamespace(
                 app_namespace, path_.c_str(), &native_bridge_, &error_msg);
             if (!dlhandle_) {
-                ALOGE("failed to load layer library '%s': %s", path_.c_str(),
-                      error_msg.c_str());
+                ALOGE("failed to load layer library '%s': %s", path_.c_str(), error_msg);
+                android::NativeLoaderFreeErrorMessage(error_msg);
                 refcount_ = 0;
                 return false;
             }
@@ -165,9 +165,10 @@
     std::lock_guard<std::mutex> lock(mutex_);
     if (--refcount_ == 0) {
         ALOGV("closing layer library '%s'", path_.c_str());
-        std::string error_msg;
+        char* error_msg = nullptr;
         if (!android::CloseNativeLibrary(dlhandle_, native_bridge_, &error_msg)) {
-            ALOGE("failed to unload library '%s': %s", path_.c_str(), error_msg.c_str());
+            ALOGE("failed to unload library '%s': %s", path_.c_str(), error_msg);
+            android::NativeLoaderFreeErrorMessage(error_msg);
             refcount_++;
         } else {
            dlhandle_ = nullptr;