Merge "Add std::string StartsWith*/EndsWith* overloads."
diff --git a/base/Android.bp b/base/Android.bp
index ad0edf4..01800af 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -116,6 +116,7 @@
         "stringprintf_test.cpp",
         "strings_test.cpp",
         "test_main.cpp",
+        "test_utils_test.cpp",
     ],
     target: {
         android: {
diff --git a/base/include/android-base/test_utils.h b/base/include/android-base/test_utils.h
index 4cfa06b..2edafe3 100644
--- a/base/include/android-base/test_utils.h
+++ b/base/include/android-base/test_utils.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_BASE_TEST_UTILS_H
 #define ANDROID_BASE_TEST_UTILS_H
 
+#include <regex>
 #include <string>
 
 #include <android-base/macros.h>
@@ -70,4 +71,32 @@
   DISALLOW_COPY_AND_ASSIGN(CapturedStderr);
 };
 
+#define ASSERT_MATCH(str, pattern)                                             \
+  do {                                                                         \
+    if (!std::regex_search((str), std::regex((pattern)))) {                    \
+      FAIL() << "regex mismatch: expected " << (pattern) << " in:\n" << (str); \
+    }                                                                          \
+  } while (0)
+
+#define ASSERT_NOT_MATCH(str, pattern)                                                     \
+  do {                                                                                     \
+    if (std::regex_search((str), std::regex((pattern)))) {                                 \
+      FAIL() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << (str); \
+    }                                                                                      \
+  } while (0)
+
+#define EXPECT_MATCH(str, pattern)                                                    \
+  do {                                                                                \
+    if (!std::regex_search((str), std::regex((pattern)))) {                           \
+      ADD_FAILURE() << "regex mismatch: expected " << (pattern) << " in:\n" << (str); \
+    }                                                                                 \
+  } while (0)
+
+#define EXPECT_NOT_MATCH(str, pattern)                                                            \
+  do {                                                                                            \
+    if (std::regex_search((str), std::regex((pattern)))) {                                        \
+      ADD_FAILURE() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << (str); \
+    }                                                                                             \
+  } while (0)
+
 #endif  // ANDROID_BASE_TEST_UTILS_H
diff --git a/base/test_utils_test.cpp b/base/test_utils_test.cpp
new file mode 100644
index 0000000..597271a
--- /dev/null
+++ b/base/test_utils_test.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include "android-base/test_utils.h"
+
+#include <gtest/gtest-spi.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace base {
+
+TEST(TestUtilsTest, AssertMatch) {
+  ASSERT_MATCH("foobar", R"(fo+baz?r)");
+  EXPECT_FATAL_FAILURE(ASSERT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
+}
+
+TEST(TestUtilsTest, AssertNotMatch) {
+  ASSERT_NOT_MATCH("foobar", R"(foobaz)");
+  EXPECT_FATAL_FAILURE(ASSERT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
+}
+
+TEST(TestUtilsTest, ExpectMatch) {
+  EXPECT_MATCH("foobar", R"(fo+baz?r)");
+  EXPECT_NONFATAL_FAILURE(EXPECT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
+}
+
+TEST(TestUtilsTest, ExpectNotMatch) {
+  EXPECT_NOT_MATCH("foobar", R"(foobaz)");
+  EXPECT_NONFATAL_FAILURE(EXPECT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
+}
+
+}  // namespace base
+}  // namespace android
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index c473e33..7fec47d 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -218,6 +218,16 @@
     },
 }
 
+cc_benchmark {
+    name: "debuggerd_benchmark",
+    defaults: ["debuggerd_defaults"],
+    srcs: ["debuggerd_benchmark.cpp"],
+    shared_libs: [
+        "libbase",
+        "libdebuggerd_client",
+    ],
+}
+
 cc_binary {
     name: "crash_dump",
     srcs: [
diff --git a/debuggerd/debuggerd_benchmark.cpp b/debuggerd/debuggerd_benchmark.cpp
new file mode 100644
index 0000000..37ee214
--- /dev/null
+++ b/debuggerd/debuggerd_benchmark.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 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.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <thread>
+
+#include <benchmark/benchmark.h>
+#include <debuggerd/client.h>
+
+using namespace std::chrono_literals;
+
+static_assert(std::chrono::high_resolution_clock::is_steady);
+
+enum class ThreadState { Starting, Started, Stopping };
+
+static void SetScheduler() {
+  struct sched_param param {
+    .sched_priority = 1,
+  };
+
+  if (sched_setscheduler(getpid(), SCHED_FIFO, &param) != 0) {
+    fprintf(stderr, "failed to set scheduler to SCHED_FIFO: %s", strerror(errno));
+  }
+}
+
+static std::chrono::duration<double> GetMaximumPause(std::atomic<ThreadState>& state) {
+  std::chrono::duration<double> max_diff(0);
+
+  const auto begin = std::chrono::high_resolution_clock::now();
+  auto last = begin;
+  state.store(ThreadState::Started);
+  while (state.load() != ThreadState::Stopping) {
+    auto now = std::chrono::high_resolution_clock::now();
+
+    auto diff = now - last;
+    if (diff > max_diff) {
+      max_diff = diff;
+    }
+
+    last = now;
+  }
+
+  return max_diff;
+}
+
+static void PerformDump() {
+  pid_t target = getpid();
+  pid_t forkpid = fork();
+  if (forkpid == -1) {
+    err(1, "fork failed");
+  } else if (forkpid != 0) {
+    int status;
+    pid_t pid = waitpid(forkpid, &status, 0);
+    if (pid == -1) {
+      err(1, "waitpid failed");
+    } else if (!WIFEXITED(status)) {
+      err(1, "child didn't exit");
+    } else if (WEXITSTATUS(status) != 0) {
+      errx(1, "child exited with non-zero status %d", WEXITSTATUS(status));
+    }
+  } else {
+    android::base::unique_fd output_fd(open("/dev/null", O_WRONLY | O_CLOEXEC));
+    if (output_fd == -1) {
+      err(1, "failed to open /dev/null");
+    }
+
+    if (!debuggerd_trigger_dump(target, kDebuggerdNativeBacktrace, 1000, std::move(output_fd))) {
+      errx(1, "failed to trigger dump");
+    }
+
+    _exit(0);
+  }
+}
+
+template <typename Fn>
+static void BM_maximum_pause_impl(benchmark::State& state, const Fn& function) {
+  SetScheduler();
+
+  for (auto _ : state) {
+    std::chrono::duration<double> max_pause;
+    std::atomic<ThreadState> thread_state(ThreadState::Starting);
+    auto thread = std::thread([&]() { max_pause = GetMaximumPause(thread_state); });
+
+    while (thread_state != ThreadState::Started) {
+      std::this_thread::sleep_for(1ms);
+    }
+
+    function();
+
+    thread_state = ThreadState::Stopping;
+    thread.join();
+
+    state.SetIterationTime(max_pause.count());
+  }
+}
+
+static void BM_maximum_pause_noop(benchmark::State& state) {
+  BM_maximum_pause_impl(state, []() {});
+}
+
+static void BM_maximum_pause_debuggerd(benchmark::State& state) {
+  BM_maximum_pause_impl(state, []() { PerformDump(); });
+}
+
+BENCHMARK(BM_maximum_pause_noop)->Iterations(128)->UseManualTime();
+BENCHMARK(BM_maximum_pause_debuggerd)->Iterations(128)->UseManualTime();
+
+BENCHMARK_MAIN();
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 0d17a3b..939f4d2 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -36,6 +36,7 @@
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
 #include <android-base/strings.h>
+#include <android-base/test_utils.h>
 #include <android-base/unique_fd.h>
 #include <cutils/sockets.h>
 #include <gtest/gtest.h>
@@ -75,22 +76,6 @@
     return value;                                                  \
   }()
 
-#define ASSERT_MATCH(str, pattern)                                              \
-  do {                                                                          \
-    std::regex r((pattern));                                                    \
-    if (!std::regex_search((str), r)) {                                         \
-      FAIL() << "regex mismatch: expected " << (pattern) << " in: \n" << (str); \
-    }                                                                           \
-  } while (0)
-
-#define ASSERT_NOT_MATCH(str, pattern)                                                      \
-  do {                                                                                      \
-    std::regex r((pattern));                                                                \
-    if (std::regex_search((str), r)) {                                                      \
-      FAIL() << "regex mismatch: expected to not find " << (pattern) << " in: \n" << (str); \
-    }                                                                                       \
-  } while (0)
-
 #define ASSERT_BACKTRACE_FRAME(result, frame_name)                        \
   ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX \
                        R"(/libc.so \()" frame_name R"(\+)")
diff --git a/libutils/include/utils/Atomic.h b/libutils/include/utils/Atomic.h
index 7eb476c..0f592fe 100644
--- a/libutils/include/utils/Atomic.h
+++ b/libutils/include/utils/Atomic.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_UTILS_ATOMIC_H
 #define ANDROID_UTILS_ATOMIC_H
 
+// DO NOT USE: Please instead use std::atomic
+
 #include <cutils/atomic.h>
 
 #endif // ANDROID_UTILS_ATOMIC_H
diff --git a/libutils/include/utils/BitSet.h b/libutils/include/utils/BitSet.h
index 8c61293..8abfb1a 100644
--- a/libutils/include/utils/BitSet.h
+++ b/libutils/include/utils/BitSet.h
@@ -22,6 +22,8 @@
 
 /*
  * Contains some bit manipulation helpers.
+ *
+ * DO NOT USE: std::bitset<32> or std::bitset<64> preferred
  */
 
 namespace android {
diff --git a/libutils/include/utils/Condition.h b/libutils/include/utils/Condition.h
index 3019a21..9bf82eb 100644
--- a/libutils/include/utils/Condition.h
+++ b/libutils/include/utils/Condition.h
@@ -34,6 +34,8 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
+// DO NOT USE: please use std::condition_variable instead.
+
 /*
  * Condition variable class.  The implementation is system-dependent.
  *
diff --git a/libutils/include/utils/Debug.h b/libutils/include/utils/Debug.h
index c699a19..4cbb462 100644
--- a/libutils/include/utils/Debug.h
+++ b/libutils/include/utils/Debug.h
@@ -29,6 +29,8 @@
 #define COMPILE_TIME_ASSERT(_exp) \
     template class CompileTimeAssert< (_exp) >;
 #endif
+
+// DO NOT USE: Please use static_assert instead
 #define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \
     CompileTimeAssert<( _exp )>();
 
diff --git a/libutils/include/utils/Flattenable.h b/libutils/include/utils/Flattenable.h
index 070c710..675e211 100644
--- a/libutils/include/utils/Flattenable.h
+++ b/libutils/include/utils/Flattenable.h
@@ -33,13 +33,13 @@
 public:
     template<size_t N>
     static size_t align(size_t size) {
-        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
+        static_assert(!(N & (N - 1)), "Can only align to a power of 2.");
         return (size + (N-1)) & ~(N-1);
     }
 
     template<size_t N>
     static size_t align(void const*& buffer) {
-        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
+        static_assert(!(N & (N - 1)), "Can only align to a power of 2.");
         uintptr_t b = uintptr_t(buffer);
         buffer = reinterpret_cast<void*>((uintptr_t(buffer) + (N-1)) & ~(N-1));
         return size_t(uintptr_t(buffer) - b);
diff --git a/libutils/include/utils/Functor.h b/libutils/include/utils/Functor.h
index 09ea614..3182a9c 100644
--- a/libutils/include/utils/Functor.h
+++ b/libutils/include/utils/Functor.h
@@ -21,6 +21,10 @@
 
 namespace  android {
 
+// DO NOT USE: please use
+// - C++ lambda
+// - class with well-defined and specific functionality and semantics
+
 class Functor {
 public:
     Functor() {}
diff --git a/libutils/include/utils/KeyedVector.h b/libutils/include/utils/KeyedVector.h
index f93ad6e..03bfe27 100644
--- a/libutils/include/utils/KeyedVector.h
+++ b/libutils/include/utils/KeyedVector.h
@@ -30,6 +30,8 @@
 
 namespace android {
 
+// DO NOT USE: please use std::map
+
 template <typename KEY, typename VALUE>
 class KeyedVector
 {
diff --git a/libutils/include/utils/List.h b/libutils/include/utils/List.h
index 403cd7f..daca016 100644
--- a/libutils/include/utils/List.h
+++ b/libutils/include/utils/List.h
@@ -37,6 +37,8 @@
  *
  * Objects added to the list are copied using the assignment operator,
  * so this must be defined.
+ *
+ * DO NOT USE: please use std::list<T>
  */
 template<typename T> 
 class List 
diff --git a/libutils/include/utils/Singleton.h b/libutils/include/utils/Singleton.h
index 9afedd4..bc47a5c 100644
--- a/libutils/include/utils/Singleton.h
+++ b/libutils/include/utils/Singleton.h
@@ -39,6 +39,11 @@
 #pragma clang diagnostic ignored "-Wundefined-var-template"
 #endif
 
+// DO NOT USE: Please use scoped static initialization. For instance:
+//     MyClass& getInstance() {
+//         static MyClass gInstance(...);
+//         return gInstance;
+//     }
 template <typename TYPE>
 class ANDROID_API Singleton
 {
diff --git a/libutils/include/utils/SortedVector.h b/libutils/include/utils/SortedVector.h
index 5b2a232..47c1376 100644
--- a/libutils/include/utils/SortedVector.h
+++ b/libutils/include/utils/SortedVector.h
@@ -30,6 +30,8 @@
 
 namespace android {
 
+// DO NOT USE: please use std::set
+
 template <class TYPE>
 class SortedVector : private SortedVectorImpl
 {
diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h
index 15ed19f..5f0ce06 100644
--- a/libutils/include/utils/String16.h
+++ b/libutils/include/utils/String16.h
@@ -37,6 +37,8 @@
 
 class String8;
 
+// DO NOT USE: please use std::u16string
+
 //! This is a string holding UTF-16 characters.
 class String16
 {
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index 0225c6b..94ac32f 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -32,6 +32,8 @@
 
 class String16;
 
+// DO NOT USE: please use std::string
+
 //! This is a string holding UTF-8 characters. Does not allow the value more
 // than 0x10FFFF, which is not valid unicode codepoint.
 class String8
diff --git a/libutils/include/utils/Thread.h b/libutils/include/utils/Thread.h
index a261fc8..598298d 100644
--- a/libutils/include/utils/Thread.h
+++ b/libutils/include/utils/Thread.h
@@ -36,6 +36,8 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
+// DO NOT USE: please use std::thread
+
 class Thread : virtual public RefBase
 {
 public:
diff --git a/libutils/include/utils/Vector.h b/libutils/include/utils/Vector.h
index 7e00123..a1a0234 100644
--- a/libutils/include/utils/Vector.h
+++ b/libutils/include/utils/Vector.h
@@ -49,6 +49,8 @@
  * The main templated vector class ensuring type safety
  * while making use of VectorImpl.
  * This is the class users want to use.
+ *
+ * DO NOT USE: please use std::vector
  */
 
 template <class TYPE>
diff --git a/libutils/include/utils/misc.h b/libutils/include/utils/misc.h
index 6cccec3..af5ea02 100644
--- a/libutils/include/utils/misc.h
+++ b/libutils/include/utils/misc.h
@@ -22,7 +22,9 @@
 
 #include <utils/Endian.h>
 
-/* get #of elements in a static array */
+/* get #of elements in a static array
+ * DO NOT USE: please use std::vector/std::array instead
+ */
 #ifndef NELEM
 # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
 #endif
diff --git a/property_service/libpropertyinfoparser/property_info_parser.cpp b/property_service/libpropertyinfoparser/property_info_parser.cpp
index e53c625..a8f6636 100644
--- a/property_service/libpropertyinfoparser/property_info_parser.cpp
+++ b/property_service/libpropertyinfoparser/property_info_parser.cpp
@@ -96,8 +96,12 @@
     if (prefix_len > remaining_name_size) continue;
 
     if (!strncmp(c_string(trie_node.prefix(i)->name_offset), remaining_name, prefix_len)) {
-      *context_index = trie_node.prefix(i)->context_index;
-      *schema_index = trie_node.prefix(i)->schema_index;
+      if (trie_node.prefix(i)->context_index != ~0u) {
+        *context_index = trie_node.prefix(i)->context_index;
+      }
+      if (trie_node.prefix(i)->schema_index != ~0u) {
+        *schema_index = trie_node.prefix(i)->schema_index;
+      }
       return;
     }
   }
@@ -142,8 +146,20 @@
   // Check exact matches
   for (uint32_t i = 0; i < trie_node.num_exact_matches(); ++i) {
     if (!strcmp(c_string(trie_node.exact_match(i)->name_offset), remaining_name)) {
-      if (context_index != nullptr) *context_index = trie_node.exact_match(i)->context_index;
-      if (schema_index != nullptr) *schema_index = trie_node.exact_match(i)->schema_index;
+      if (context_index != nullptr) {
+        if (trie_node.exact_match(i)->context_index != ~0u) {
+          *context_index = trie_node.exact_match(i)->context_index;
+        } else {
+          *context_index = return_context_index;
+        }
+      }
+      if (schema_index != nullptr) {
+        if (trie_node.exact_match(i)->schema_index != ~0u) {
+          *schema_index = trie_node.exact_match(i)->schema_index;
+        } else {
+          *schema_index = return_schema_index;
+        }
+      }
       return;
     }
   }
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index b3fae26..46c2d06 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -844,5 +844,47 @@
   EXPECT_STREQ("3rd", schema);
 }
 
+TEST(propertyinfoserializer, GetPropertyInfo_empty_context_and_schema) {
+  auto property_info = std::vector<PropertyInfoEntry>{
+      {"persist.", "1st", "", false},
+      {"persist.dot_prefix.", "2nd", "", false},
+      {"persist.non_dot_prefix", "3rd", "", false},
+      {"persist.exact_match", "", "", true},
+      {"persist.dot_prefix2.", "", "4th", false},
+      {"persist.non_dot_prefix2", "", "5th", false},
+  };
+
+  auto serialized_trie = std::string();
+  auto build_trie_error = std::string();
+  ASSERT_TRUE(BuildTrie(property_info, "default", "default", &serialized_trie, &build_trie_error))
+      << build_trie_error;
+
+  auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data());
+
+  const char* context;
+  const char* schema;
+  property_info_area->GetPropertyInfo("notpersist.radio.something", &context, &schema);
+  EXPECT_STREQ("default", context);
+  EXPECT_STREQ("default", schema);
+  property_info_area->GetPropertyInfo("persist.nomatch", &context, &schema);
+  EXPECT_STREQ("1st", context);
+  EXPECT_STREQ("default", schema);
+  property_info_area->GetPropertyInfo("persist.dot_prefix.something", &context, &schema);
+  EXPECT_STREQ("2nd", context);
+  EXPECT_STREQ("default", schema);
+  property_info_area->GetPropertyInfo("persist.non_dot_prefix.something", &context, &schema);
+  EXPECT_STREQ("3rd", context);
+  EXPECT_STREQ("default", schema);
+  property_info_area->GetPropertyInfo("persist.exact_match", &context, &schema);
+  EXPECT_STREQ("1st", context);
+  EXPECT_STREQ("default", schema);
+  property_info_area->GetPropertyInfo("persist.dot_prefix2.something", &context, &schema);
+  EXPECT_STREQ("1st", context);
+  EXPECT_STREQ("4th", schema);
+  property_info_area->GetPropertyInfo("persist.non_dot_prefix2.something", &context, &schema);
+  EXPECT_STREQ("1st", context);
+  EXPECT_STREQ("5th", schema);
+}
+
 }  // namespace properties
 }  // namespace android
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 1da93af..b86104d 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -258,12 +258,7 @@
 namespace.default.search.paths += /system/${LIB}/vndk-sp${VNDK_VER}
 namespace.default.search.paths += /system/${LIB}
 
-# TODO(b/70551668) Remove /vendor/${LIB}/hw from search paths.
-# Shared libraries in the directory should be dlopened with full file paths.
-# This is a workaround for some legacy prebuilt binaries.
-namespace.default.search.paths += /vendor/${LIB}/hw
-
-namespace.default.asan.search.paths += /data/asan/odm/${LIB}
+namespace.default.asan.search.paths  = /data/asan/odm/${LIB}
 namespace.default.asan.search.paths +=           /odm/${LIB}
 namespace.default.asan.search.paths += /data/asan/odm/${LIB}/vndk
 namespace.default.asan.search.paths +=           /odm/${LIB}/vndk
@@ -281,9 +276,3 @@
 namespace.default.asan.search.paths +=           /system/${LIB}/vndk-sp${VNDK_VER}
 namespace.default.asan.search.paths += /data/asan/system/${LIB}
 namespace.default.asan.search.paths +=           /system/${LIB}
-
-# TODO(b/70551668) Remove /vendor/${LIB}/hw from search paths.
-# Shared libraries in the directory should be dlopened with full file paths.
-# This is a workaround for some legacy prebuilt binaries.
-namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/hw
-namespace.default.asan.search.paths +=           /vendor/${LIB}/hw
diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in
index 77c2062..df26f90 100644
--- a/rootdir/etc/ld.config.txt.in
+++ b/rootdir/etc/ld.config.txt.in
@@ -240,9 +240,6 @@
 namespace.default.search.paths += /vendor/${LIB}/vndk
 namespace.default.search.paths += /vendor/${LIB}/vndk-sp
 
-# TODO(b/70551668) remove this
-namespace.default.search.paths += /vendor/${LIB}/hw
-
 namespace.default.permitted.paths  = /odm
 namespace.default.permitted.paths += /vendor
 
@@ -259,10 +256,6 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/vndk-sp
 namespace.default.asan.search.paths +=           /vendor/${LIB}/vndk-sp
 
-# TODO(b/70551668) remove this
-namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/hw
-namespace.default.asan.search.paths +=           /vendor/${LIB}/hw
-
 namespace.default.asan.permitted.paths  = /data/asan/odm
 namespace.default.asan.permitted.paths +=           /odm
 namespace.default.asan.permitted.paths += /data/asan/vendor